View Javadoc
1   /******************************************************************************
2    * DatabaseImpl.java - Implement the API into the PicMan database
3    * 
4    * PicMan - The BuckoSoft Picture Manager in Java
5    * Copyright(c) 2005 - Dick Balaska
6    * 
7    */
8   package com.buckosoft.PicMan.db;
9   
10  import java.text.DecimalFormat;
11  import java.util.Calendar;
12  import java.util.Date;
13  import java.util.HashMap;
14  import java.util.Iterator;
15  import java.util.LinkedHashMap;
16  import java.util.LinkedList;
17  import java.util.List;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.hibernate.HibernateException;
22  import org.hibernate.Session;
23  import org.springframework.dao.DataAccessException;
24  
25  import com.buckosoft.PicMan.business.SetChangedListener;
26  import com.buckosoft.PicMan.business.common.PicManCommonFacade;
27  import com.buckosoft.PicMan.db.logic.MetaSetFilter;
28  import com.buckosoft.PicMan.domain.Chain;
29  import com.buckosoft.PicMan.domain.Contact;
30  import com.buckosoft.PicMan.domain.Filter;
31  import com.buckosoft.PicMan.domain.FilterMicroSet;
32  import com.buckosoft.PicMan.domain.MetaSet;
33  import com.buckosoft.PicMan.domain.MetaSetRule;
34  import com.buckosoft.PicMan.domain.Mosaic;
35  import com.buckosoft.PicMan.domain.MosaicBatch;
36  import com.buckosoft.PicMan.domain.MosaicTile;
37  import com.buckosoft.PicMan.domain.Pic;
38  import com.buckosoft.PicMan.domain.Poster;
39  import com.buckosoft.PicMan.domain.Root;
40  import com.buckosoft.PicMan.domain.Set;
41  import com.buckosoft.PicMan.domain.SetSize;
42  import com.buckosoft.PicMan.domain.SyncClient;
43  import com.buckosoft.PicMan.domain.SyncServer;
44  import com.buckosoft.PicMan.domain.System;
45  import com.buckosoft.PicMan.domain.User;
46  import com.buckosoft.PicMan.domain.Virgin;
47  import com.buckosoft.PicMan.domain.mosaic.MosaicVector;
48  
49  /** Implement the API into the PicMan database
50   * @author Dick Balaska
51   * @since 2006/07/17
52   * @see <a href="http://cvs.buckosoft.com/Projects/PicMan/PicMan/src/com/buckosoft/PicMan/db/DatabaseImpl.java">DatabaseImpl.java</a>
53   */
54  public class DatabaseImpl implements DatabaseFacade, SetChangedListener {
55  	private static boolean DEBUG = false;
56  //	private static boolean DEBUGMETASETS = false;
57  	protected final Log logger = LogFactory.getLog(getClass());
58  
59  	private	String			dbUser;
60  	private	String			dbUrl;
61  	
62  	private	List<Integer>	sizes;			// totally unflexible size list (should be a database)
63  	private	int[]			sizeArray;		// easier to deal with totally unflexible size array
64  	private	ChainsDao		chainsDao;
65  	private	ContactsDao		contactsDao;
66  	private	FiltersDao		filtersDao;
67  	private	FiltersMicroSetsDao filtersMicroSetsDao;
68  	private	MetaSetsDao		metaSetsDao;
69  	private	MosaicsDao		mosaicsDao;
70  	private	MosaicBatchesDao mosaicBatchesDao;
71  	private	MosaicTilesDao	mosaicTilesDao;
72  	private	MosaicVectorsDao mosaicVectorsDao;
73  	private	PicsDao			picsDao;
74  	private	PostersDao		postersDao;
75  	private	RootsDao		rootsDao;
76  	private	Server_SyncDao	server_SyncDao;
77  	private	SystemDao		systemDao;
78  	private	SetsDao			setsDao;
79  	private	SetTimestampsDao setTimestampsDao;
80  	private	UsersDao		usersDao;
81  	private VirginsDao		virginsDao;
82  
83  	private	MetaSetFilter	metaSetFilter = new MetaSetFilter();
84  
85  	// XXX: This should be extended to support multiple users
86  	private class HomeThumbAttr {
87  		String			homeThumbsForUserSetCached = "";
88  		List<String>	homeThumbsForUser = null;
89  		User			homeThumbsUser = null;
90  		int				homeThumbsUserIndex = 0;
91  	}
92  	HomeThumbAttr homeThumbAttr = new HomeThumbAttr();
93  	
94  	PicManCommonFacade pmcf;
95  
96  	DatabaseImpl() {
97  		this.metaSetFilter.setDatabase(this);
98  
99  		sizes = new LinkedList<Integer>();
100 		sizes.add(new Integer(75));
101 		sizes.add(new Integer(100));
102 		sizes.add(new Integer(150));
103 		sizes.add(new Integer(200));
104 		sizes.add(new Integer(300));
105 
106 		sizeArray = new int[5];
107 		sizeArray[0] = 75;
108 		sizeArray[1] = 100;
109 		sizeArray[2] = 150;
110 		sizeArray[3] = 200;
111 		sizeArray[4] = 300;
112 	}
113 
114 
115 	public void setPicManCommonFacade(PicManCommonFacade picManCommonFacade) {
116 		this.pmcf = picManCommonFacade;
117 		this.pmcf.addSetChangedListener(this);
118 	}
119 
120 	/* (non-Javadoc)
121 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#setDEBUG(boolean)
122 	 */
123 	public void setDEBUG(boolean debugFlag) {
124 		DEBUG = debugFlag;
125 	}
126 
127 
128 	//-------------------------------------------------------------------------
129 	// Setter methods for dependency injection
130 	//-------------------------------------------------------------------------
131 
132 	/** AOP setter for the ChainsDao
133 	 * @param chainsDao The ChainsDao from the Spring Database Setup
134 	 */
135 	public void setChainsDao(ChainsDao chainsDao) {
136 		this.chainsDao = chainsDao;
137 	}
138 	/** AOP setter for the ContactsDao
139 	 * @param contactsDao The ContactsDao from the Spring Database Setup
140 	 */
141 	public void setContactsDao(ContactsDao contactsDao) {
142 		this.contactsDao = contactsDao;
143 	}
144 	/** AOP setter for the FiltersDao
145 	 * @param filtersDao The FiltersDao from the Spring Database Setup
146 	 */
147 	public void setFiltersDao(FiltersDao filtersDao) {
148 		this.filtersDao = filtersDao;
149 	}
150 	/** AOP setter for the FiltersMicroSetsDao
151 	 * @param filtersMicroSetsDao The FiltersMicroSetsDao from the Spring Database Setup
152 	 */
153 	public void setFiltersMicroSetsDao(FiltersMicroSetsDao filtersMicroSetsDao) {
154 		this.filtersMicroSetsDao = filtersMicroSetsDao;
155 	}
156 	/** AOP setter for the MetaSetsDao
157 	 * @param metaSetsDao The MetaSetsDao from the Spring Database Setup
158 	 */
159 	public void setMetaSetsDao(MetaSetsDao metaSetsDao) {
160 		this.metaSetsDao = metaSetsDao;
161 	}
162 	/** AOP setter for the MosaicTilesDao
163 	 * @param mosaicTilesDao The MosaicTilesDao from the Spring Database Setup
164 	 */
165 	public void setMosaicTilesDao(MosaicTilesDao mosaicTilesDao) {
166 		this.mosaicTilesDao = mosaicTilesDao;
167 	}
168 	/** AOP setter for the MosaicsDao
169 	 * @param mosaicsDao The MosaicsDao from the Spring Database Setup
170 	 */
171 	public void setMosaicsDao(MosaicsDao mosaicsDao) {
172 		this.mosaicsDao = mosaicsDao;
173 	}
174 	/** AOP setter for the MosaicsDao
175 	 * @param mosaicBatchesDao The MosaicsBatchDao from the Spring Database Setup
176 	 */
177 	public void setMosaicBatchesDao(MosaicBatchesDao mosaicBatchesDao) {
178 		this.mosaicBatchesDao = mosaicBatchesDao;
179 	}
180 	/** AOP setter for the MosaicVectorsDao
181 	 * @param mosaicVectorsDao The MosaicVectorsDao from the Spring Database Setup
182 	 */
183 	public void setMosaicVectorsDao(MosaicVectorsDao mosaicVectorsDao) {
184 		this.mosaicVectorsDao = mosaicVectorsDao;
185 	}
186 	/** AOP setter for the PicsDao
187 	 * @param picsDao The PicsDao from the Spring Database Setup
188 	 */
189 	public void setPicsDao(PicsDao picsDao) {
190 		this.picsDao = picsDao;
191 	}
192 	/** AOP setter for the PostersDao
193 	 * @param postersDao The PostersDao from the Spring Database Setup
194 	 */
195 	public void setPostersDao(PostersDao postersDao) {
196 		this.postersDao = postersDao;
197 	}
198 	/** AOP setter for the RootsDao
199 	 * @param rootsDao The RootsDao from the Spring Database Setup
200 	 */
201 	public void setRootsDao(RootsDao rootsDao) {
202 		this.rootsDao = rootsDao;
203 	}
204 	/** AOP setter for the Server's SyncDao
205 	 * @param server_SyncDao The Server_SyncDao from the Spring Database Setup
206 	 */
207 	public void setServer_SyncDao(Server_SyncDao server_SyncDao) {
208 		this.server_SyncDao = server_SyncDao;
209 	}
210 	/** AOP setter for the SystemDao
211 	 * @param systemDao The SystemDao from the Spring Database Setup
212 	 */
213 	public void setSystemDao(SystemDao systemDao) {
214 		this.systemDao = systemDao;
215 	}
216 	/** AOP setter for the SetsDao
217 	 * @param setsDao The SetsDao from the Spring Database Setup
218 	 */
219 	public void setSetsDao(SetsDao setsDao) {
220 		this.setsDao = setsDao;
221 	}
222 	/** AOP setter for the SetTimestampsDao
223 	 * @param setTimestampsDao The SetTimestampsDao from the Spring Database Setup
224 	 */
225 	public void setSetTimestampsDao(SetTimestampsDao setTimestampsDao) {
226 		this.setTimestampsDao = setTimestampsDao;
227 	}
228 	/** AOP setter for the UsersDao
229 	 * @param usersDao The UsersDao from the Spring Database Setup
230 	 */
231 	public void setUsersDao(UsersDao usersDao) {
232 		this.usersDao = usersDao;
233 	}
234 	/** AOP setter for the VirginsDao
235 	 * @param virginsDao The VirginsDao from the Spring Database Setup
236 	 */
237 	public void setVirginsDao(VirginsDao virginsDao) {
238 		this.virginsDao = virginsDao;
239 	}
240 
241 	/** Why is this public?  Because Spring was freaking out trying to reflect the type.
242 	 * @return Our kinda private ChainsDao
243 	 */
244 	public ChainsDao getChainsDao() { return(chainsDao); }
245 	
246 
247 	//-------------------------------------------------------------------------
248 	// Operation methods, implementing the PicManFacade interface
249 	//-------------------------------------------------------------------------
250 
251 	/* (non-Javadoc)
252 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#setDbUser(java.lang.String)
253 	 */
254 	@Override
255 	public void setDbUser(String dbUser) {
256 		this.dbUser = dbUser;
257 	}
258 
259 
260 	/* (non-Javadoc)
261 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getDbUser()
262 	 */
263 	@Override
264 	public String getDbUser() {
265 		return(this.dbUser);
266 	}
267 
268 
269 	/* (non-Javadoc)
270 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#setDbUrl(java.lang.String)
271 	 */
272 	@Override
273 	public void setDbUrl(String dbUrl) {
274 		this.dbUrl = dbUrl;
275 	}
276 
277 
278 	/* (non-Javadoc)
279 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getDbUrl()
280 	 */
281 	@Override
282 	public String getDbUrl() {
283 		return(this.dbUrl);
284 	}
285 
286 
287 	
288 	/*******************************************************
289 	 * System Management
290 	 */
291 	
292 	/* (non-Javadoc)
293 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSystem()
294 	 */
295 	public System getSystem() {
296 		return(this.systemDao.getSystem());
297 	}
298 	
299 	/* (non-Javadoc)
300 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#saveSystem(com.buckosoft.PicMan.domain.System)
301 	 */
302 	public void saveSystem(System sys) {
303 		this.systemDao.setSystem(sys);
304 	}
305 	
306 	/* (non-Javadoc)
307 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicExtensions()
308 	 */
309 	public List<String> getPicExtensions() {
310 		return(systemDao.getSystem().getPicExtensions());
311 	}
312 	
313 	/* (non-Javadoc)
314 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getThumbHeight()
315 	 */
316 	public int	getThumbHeight() {
317 		return(systemDao.getSystem().getThumbHeight());
318 	}
319 
320 	///////////////////////////////////////////////////////////////////////////
321 	/* Roots Management */
322 	
323 	/* (non-Javadoc)
324 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRoots()
325 	 */
326 	public List<Root> getRoots() {
327 		return(rootsDao.getRoots());
328 	}
329 
330 	/* (non-Javadoc)
331 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRootCount()
332 	 */
333 	public	int		getRootCount() {
334 		return(rootsDao.getRootCount());
335 	}
336 	/* (non-Javadoc)
337 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRoot(int)
338 	 */
339 	public Root getRoot(int rid) {
340 		return(rootsDao.getRoot(rid));
341 	}
342 
343 	/* (non-Javadoc)
344 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRoot(java.lang.String)
345 	 */
346 	public Root getRoot(String name) {
347 		return(rootsDao.getRoot(name));
348 	}
349 
350 	/* (non-Javadoc)
351 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#setRoots(java.util.List)
352 	 */
353 	public void setRoots(List<Root> roots) {
354 		this.rootsDao.setRoots(roots);
355 	}
356 
357 	/* (non-Javadoc)
358 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#addRoot(com.buckosoft.PicMan.domain.Root)
359 	 */
360 	public void addRoot(Root r) {
361 		int count = rootsDao.getRootCount();
362 		r.setRid(count+1);
363 		rootsDao.addRoot(r);
364 	}
365 
366 	/* (non-Javadoc)
367 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeRoot(com.buckosoft.PicMan.domain.Root)
368 	 */
369 	public	void	storeRoot(Root root) {
370 		rootsDao.storeRoot(root);
371 	}
372 
373 	/* (non-Javadoc)
374 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deleteRoot(com.buckosoft.PicMan.domain.Root)
375 	 */
376 	public void deleteRoot(Root root) {
377 		rootsDao.deleteRoot(root);
378 	}
379 
380 	/* (non-Javadoc)
381 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getInactiveRoots()
382 	 */
383 	public List<Root> getInactiveRoots() {
384 		return(rootsDao.getInactiveRoots());
385 	}
386 
387 	/* (non-Javadoc)
388 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getActiveRoots()
389 	 */
390 	public List<Root> getActiveRoots() {
391 		return(rootsDao.getActiveRoots());
392 	}
393 
394 	///////////////////////////////////////////////////////////////////////////
395 	/* Sets Management */
396 	
397 	/* (non-Javadoc)
398 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSets()
399 	 */
400 	public List<Set> getSets() {
401 		return(setsDao.getSets());
402 	}
403 
404 	/* (non-Javadoc)
405 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSetsClone()
406 	 */
407 	public List<Set> getSetsClone() {
408 		return(setsDao.getSetsClone());
409 	}
410 
411 	/* (non-Javadoc)
412 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSetCount()
413 	 */
414 	public	int		getSetCount() {
415 		return(setsDao.getSetCount());
416 	}
417 
418 	/* (non-Javadoc)
419 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSet(int)
420 	 */
421 	public	Set		getSet(int sid) {
422 		return(setsDao.getSet(sid));
423 	}
424 
425 	/* (non-Javadoc)
426 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSet(java.lang.String)
427 	 */
428 	public	Set		getSet(String setName) {
429 		return(setsDao.getSet(setName));
430 	}
431 
432 	/* (non-Javadoc)
433 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#setSets(java.util.List)
434 	 */
435 	public void setSets(List<Set> sets) {
436 		this.setsDao.setSets(sets);
437 	}
438 
439 	/** Add a new set to the database.
440 	 * @param s The Set to add.  The sid should be 0.
441 	 */
442 	public void addSet(Set s) {
443 //		int count = setsDao.getSetCount();
444 //		s.setSid(count+1);
445 		s.setSid(0);
446 		setsDao.addSet(s);
447 		s = setsDao.getSet(s.getName());
448 		if (!s.isMetaSet() && !s.isMicroSet() && !s.isNanoSet()) {
449 			List<Integer> l = getSizes();
450 			Iterator<Integer> it = l.iterator();
451 			while (it.hasNext()) {
452 				Integer i = (Integer)it.next();
453 				filtersDao.addSet(s.getName(), i.intValue());
454 			}
455 		}
456 	}
457 
458 	/** Store an existing set to the database.
459 	 * @param set The set to store.  The sid should NOT be 0.
460 	 */
461 	public	void	storeSet(Set set) {
462 		if (!set.isMetaSet() && !set.isMicroSet() && !set.isNanoSet()) {
463 			Set s1 = getSet(set.getSid());
464 			if (!set.getName().equals(s1.getName())) {		// renaming a set...
465 				List<Integer> l = getSizes();
466 				Iterator<Integer> it = l.iterator();
467 				while (it.hasNext()) {
468 					Integer i = (Integer)it.next();
469 					filtersDao.renameSet(s1.getName(), set.getName(), i.intValue());
470 				}
471 				
472 			}
473 		}
474 		setsDao.storeSet(set);
475 	}
476 	
477 	/** Delete this set from the database.
478 	 * @param s The set to delete.
479 	 */
480 	public void deleteSet(Set s) {
481 		List<Integer> l = getSizes();
482 		Iterator<Integer> it = l.iterator();
483 		while (it.hasNext()) {
484 			Integer i = (Integer)it.next();
485 			filtersDao.deleteSet(s.getName(), i.intValue());
486 		}
487 		setsDao.deleteSet(s);
488 	}
489 
490 
491 	/* (non-Javadoc)
492 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#renameSet(java.lang.String, java.lang.String)
493 	 */
494 	public void renameSet(String oldName, String newName) {
495 		Set set = this.getSet(oldName);
496 		List<Chain> clist = this.getChains();
497 		for (Chain c : clist) {
498 			boolean modified = false;
499 			List<SetSize> slist = c.getSetSizes();
500 			Iterator<SetSize> siter = slist.iterator();
501 			while (siter.hasNext()) {
502 				SetSize ss = siter.next();
503 				if (ss.getSetName().equals(oldName)) {
504 					modified = true;
505 					ss.setSetName(newName);
506 				}
507 			}
508 			if (modified) {
509 				this.storeChain(c);
510 			}
511 		}
512 		List<Set> slist = this.getSets();
513 		for (Set s : slist) {
514 			boolean modified = false;
515 			if (!s.isMetaSet())
516 				continue;
517 			MetaSet ms = this.getMetaSet(s.getSid());
518 			for (MetaSetRule msr : ms.getRules()) {
519 				if (msr.getType() == MetaSet.NAME) {
520 					if (msr.getValue().equals(oldName)) {
521 						msr.setValue(newName);
522 						modified = true;
523 					}
524 				}
525 			}
526 			if (modified)
527 				this.storeMetaSet(ms);
528 		}
529 		set.setName(newName);
530 		this.storeSet(set);
531 	}
532 
533 	/** Build a list of inactive sets
534 	 * @return A List of Sets
535 	 */
536 	public List<Set> getInactiveSets() {
537 		return(setsDao.getInactiveSets());
538 	}
539 
540 	/** Build a list of active sets
541 	 * @return A List of Sets
542 	 */
543 	public List<Set> getActiveSets() {
544 		return(setsDao.getActiveSets());
545 	}
546 
547 	///////////////////////////////////////////////////////////////////////////
548 	/** 
549 	 * MetaSet Management
550 	 */
551 	/* (non-Javadoc)
552 	 * @see com.buckosoft.PicMan.domain.logic.PicManFacade#getMetaSet(int)
553 	 */
554 	public MetaSet getMetaSet(int sid) {
555 		return(this.metaSetsDao.getMetaSet(sid));
556 	}
557 
558 	/* (non-Javadoc)
559 	 * @see com.buckosoft.PicMan.domain.logic.PicManFacade#storeMetaSet(com.buckosoft.PicMan.domain.MetaSet)
560 	 */
561 	public void storeMetaSet(MetaSet mset) {
562 		this.metaSetsDao.storeMetaSet(mset);
563 	}
564 
565 	/** Get a List of Column names for the MetaSets.
566 	 * @return a List of "columns" for the known metasets
567 	 */
568 	public	List<String>	getMetaSetColumns() {
569 		List<String> columns = new LinkedList<String>();
570 		List<Integer> sizes = getSizes();
571 		List<Set> sets = getSets();
572 		SetSize	ss = new SetSize();
573 		Iterator<Set> setIter = sets.iterator();
574 		while (setIter.hasNext()) {
575 			Set set = (Set)setIter.next();
576 			if (set.isMetaSet()) {
577 				ss.setSetName(set.getName());
578 				Iterator<Integer> sizeIter = sizes.iterator();
579 				while (sizeIter.hasNext()) {
580 					ss.setSize(((Integer)sizeIter.next()).intValue());
581 					columns.add(ss.getGuiSetSize());
582 				}
583 			}
584 		}
585 		return(columns);
586 	}
587 
588 	/* (non-Javadoc)
589 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMetaSetFilter()
590 	 */
591 	public MetaSetFilter getMetaSetFilter() {
592 		return(this.metaSetFilter);
593 	}
594 
595 	///////////////////////////////////////////////////////////////////////////
596 	/* 
597 	 * Mosaic Management
598 	 */
599 	/* (non-Javadoc)
600 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaic(int)
601 	 */
602 	public Mosaic getMosaic(int mid) {
603 		return(this.mosaicsDao.getMosaic(mid));
604 	}
605 
606 	/* (non-Javadoc)
607 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaic(java.lang.String, java.lang.String, int, int)
608 	 */
609 	public Mosaic getMosaic(String masterPic, String engine, int sid, int tileHeight) {
610 		return(this.mosaicsDao.getMosaic(masterPic, engine, sid, tileHeight));
611 	}
612 
613 	/* (non-Javadoc)
614 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaicTileCount(int)
615 	 */
616 	public int getMosaicTileCount(int mid) {
617 		return(this.mosaicTilesDao.getTileCount(mid));
618 	}
619 
620 	/* (non-Javadoc)
621 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaics()
622 	 */
623 	public List<Mosaic> getMosaics() {
624 		return(this.mosaicsDao.getMosaics());
625 	}
626 
627 	/* (non-Javadoc)
628 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeMosaic(com.buckosoft.PicMan.domain.Mosaic)
629 	 */
630 	public void storeMosaic(Mosaic mosaic) {
631 		this.mosaicsDao.storeMosaic(mosaic);
632 	}
633 
634 	/* (non-Javadoc)
635 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deleteMosaic(int)
636 	 */
637 	public void deleteMosaic(int mid) {
638 		this.mosaicsDao.deleteMosaic(mid);
639 	}
640 
641 	///////////////////////////////////////////////////////////////////////////
642 	/*
643 	 * MosaicBatch Management
644 	 */
645 	/* (non-Javadoc)
646 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaicBatch(int)
647 	 */
648 	public MosaicBatch getMosaicBatch(int mbid) {
649 		return(this.mosaicBatchesDao.getMosaicBatch(mbid));
650 	}
651 
652 	/* (non-Javadoc)
653 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaicBatches()
654 	 */
655 	public List<MosaicBatch> getMosaicBatches() {
656 		return(this.mosaicBatchesDao.getMosaicBatches());
657 	}
658 
659 	/* (non-Javadoc)
660 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeMosaicBatch(com.buckosoft.PicMan.domain.MosaicBatch)
661 	 */
662 	public void storeMosaicBatch(MosaicBatch mbatch) {
663 		this.mosaicBatchesDao.storeMosaicBatch(mbatch);
664 	}
665 
666 	///////////////////////////////////////////////////////////////////////////
667 	/*
668 	 * MosaicTile Management
669 	 */
670 	/* (non-Javadoc)
671 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deleteMosaicTiles(int)
672 	 */
673 	public void deleteMosaicTiles(int mid) {
674 		this.mosaicTilesDao.deleteMosaicTiles(mid);
675 	}
676 
677 	/* (non-Javadoc)
678 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaicTiles(int)
679 	 */
680 	public List<MosaicTile> getMosaicTiles(int mid) {
681 		return(this.mosaicTilesDao.getMosaicTiles(mid));
682 	}
683 
684 	/* (non-Javadoc)
685 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeMosaicTile(com.buckosoft.PicMan.domain.MosaicTile)
686 	 */
687 	public void storeMosaicTile(MosaicTile tile) {
688 		this.mosaicTilesDao.storeMosaicTile(tile);
689 	}
690 
691 	///////////////////////////////////////////////////////////////////////////
692 	/* 
693 	 * MosaicVector Management
694 	 */
695 	/* (non-Javadoc)
696 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#updateMosaicVectors(com.buckosoft.PicMan.domain.MosaicVector)
697 	 */
698 	public void updateMosaicVectors(MosaicVector mv) {
699 		this.mosaicVectorsDao.updateMosaicVector(mv);
700 		
701 	}
702 
703 	/* (non-Javadoc)
704 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getMosaicVectors(java.util.List)
705 	 */
706 	public List<MosaicVector> getMosaicVectors(List<Pic> picList) {
707 		return(this.mosaicVectorsDao.getMosaicVectors(picList));
708 	}
709 
710 	///////////////////////////////////////////////////////////////////////////
711 	/* 
712 	 * Poster Management
713 	 */
714 	/* (non-Javadoc)
715 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPoster(int)
716 	 */
717 	public Poster getPoster(int pid) {
718 		return(this.postersDao.getPoster(pid));
719 	}
720 
721 	/* (non-Javadoc)
722 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPosters()
723 	 */
724 	public List<Poster> getPosters() {
725 		return(this.postersDao.getPosters());
726 	}
727 
728 	/* (non-Javadoc)
729 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storePoster(com.buckosoft.PicMan.domain.Poster)
730 	 */
731 	public void storePoster(Poster poster) {
732 		this.postersDao.storePoster(poster);
733 	}
734 
735 	/* (non-Javadoc)
736 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deletePoster(int)
737 	 */
738 	public void deletePoster(int pid) {
739 		this.postersDao.deletePoster(pid);
740 	}
741 
742 	
743 	///////////////////////////////////////////////////////////////////////////
744 	/*
745 	 * Size Management
746 	 */
747 
748 	/* (non-Javadoc)
749 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSizes()
750 	 */
751 	public	List<Integer>	getSizes() {
752 		return(sizes);
753 	}
754 
755 	/* (non-Javadoc)
756 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSizeArray()
757 	 */
758 	public	int[]	getSizeArray() {
759 		return(sizeArray);
760 	}
761 
762 	/* (non-Javadoc)
763 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSizeCount()
764 	 */
765 	public	int		getSizeCount() {
766 		return(5);
767 	}
768 
769 	
770 	///////////////////////////////////////////////////////////////////////////
771 	/* Chains Management */
772 	
773 	/* (non-Javadoc)
774 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getChains()
775 	 */
776 	public	List<Chain>	getChains() {
777 		return(chainsDao.getChains());
778 	}
779 
780 	/* (non-Javadoc)
781 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getChainCount()
782 	 */
783 	public	int		getChainCount() {
784 		return(chainsDao.getChainCount());
785 	}
786 
787 	/* (non-Javadoc)
788 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getChain(java.lang.String)
789 	 */
790 	public	Chain	getChain(String chainName) {
791 		return(chainsDao.getChain(chainName));
792 	}
793 
794 	/* (non-Javadoc)
795 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getChain(int)
796 	 */
797 	public	Chain	getChain(int cid) {
798 		return(chainsDao.getChain(cid));
799 	}
800 
801 	/* (non-Javadoc)
802 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeChain(com.buckosoft.PicMan.domain.Chain)
803 	 */
804 	public	void	storeChain(Chain chain) {
805 		chainsDao.storeChain(chain);
806 	}
807 
808 	/* (non-Javadoc)
809 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deleteChain(com.buckosoft.PicMan.domain.Chain)
810 	 */
811 	public	void	deleteChain(Chain chain) {
812 		chainsDao.deleteChain(chain);
813 	}
814 
815 	/* (non-Javadoc)
816 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSetsInChain(int)
817 	 */
818 	public List<Set>	getSetsInChain(int cid) {
819 		Chain c = getChain(cid);
820 		LinkedList<Set> theList = new LinkedList<Set>();
821 		Iterator<SetSize> iter = c.getSetSizes().iterator();
822 		while (iter.hasNext()) {
823 			SetSize ss = (SetSize)iter.next();
824 			boolean match = false;
825 			Iterator<Set> iterThe = theList.iterator();
826 			while (iterThe.hasNext()) {
827 				Set s = iterThe.next();
828 				if (DEBUG) {
829 					if (s == null || ss == null) {
830 						logger.info("s or ss == null");
831 					}
832 				}
833 				if (s.getName().equals(ss.getSetName())) {
834 					match = true;
835 					break;
836 				}
837 			}
838 			if (match == false) {
839 				if (DEBUG)
840 					logger.info("Add set \"" + ss.getSetName() + "\"");
841 				Set set = setsDao.getSet(ss.getSetName());
842 				if (set == null) {
843 					RuntimeException e = new RuntimeException("getSetsInChain can't find set \"" + ss.getSetName() + "\" in chain \"" + c.getName() + "\"");
844 					pmcf.addError(e);
845 				} else
846 					theList.add(set);
847 			}
848 		}
849 		return(theList);
850 		
851 	}
852 
853 	/* (non-Javadoc)
854 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSetSizesInChain(int, int)
855 	 */
856 	@SuppressWarnings("unchecked")
857 	public List<SetSize> getSetSizesInChain(int cid, int sid) {
858 		Chain c = getChain(cid);
859 		Set set = getSet(sid);
860 		LinkedList<SetSize> theList = (LinkedList<SetSize>) c.getSetSizes().clone();
861 		Iterator<SetSize> iter = theList.iterator();
862 		while (iter.hasNext()) {
863 			SetSize ss = (SetSize)iter.next();
864 			if (!set.getName().equals(ss.getSetName())) {
865 				iter.remove();
866 			}
867 		}
868 		return(theList);
869 	}
870 
871 	///////////////////////////////////////////////////////////////////////////
872 	/* Contacts */
873 	
874 
875 	/* (non-Javadoc)
876 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getContact(int, java.lang.String)
877 	 */
878 	public	Contact	getContact(int cid, String name) {
879 		return(contactsDao.getContact(cid, name));
880 	}
881 
882 	/* (non-Javadoc)
883 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getContact(int, java.lang.String, int, int)
884 	 */
885 	public	Contact	getContact(int cid, String setName, int size, int item) {
886 		return(contactsDao.getContact(cid, setName, size, item));
887 	}
888 
889 	/* (non-Javadoc)
890 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#addContact(com.buckosoft.PicMan.domain.Contact)
891 	 */
892 	public	void	addContact(Contact c) {
893 		contactsDao.addContact(c);
894 	}
895 
896 	/* (non-Javadoc)
897 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getNewestContact()
898 	 */
899 	public	Contact		getNewestContact() {
900 		return(contactsDao.getNewestContact());
901 	}
902 
903 	/* (non-Javadoc)
904 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getContactOldestMap(com.buckosoft.PicMan.domain.Chain)
905 	 */
906 	public HashMap<String, Date>		getContactOldestMap(Chain chain) {
907 		return(contactsDao.getContactOldestMap(chain));
908 	}
909 	///////////////////////////////////////////////////////////////////////////
910 	/*
911 	 * Filter management 
912 	 */
913 
914 	
915 	/* (non-Javadoc)
916 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFilterCount()
917 	 */
918 	public	int		getFilterCount() {
919 		return(this.filtersDao.getFilterCount());
920 	}
921 
922 	/* (non-Javadoc)
923 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFilterColumns()
924 	 */
925 	public	List<String>	getFilterColumns() {
926 		if (DEBUG)
927 			logger.info("getFilterColumns()");
928 		return(this.filtersDao.getFilterColumns());
929 	}
930 
931 	/* (non-Javadoc)
932 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFilters()
933 	 */
934 	public	List<Filter>	getFilters() {
935 		return(this.filtersDao.getFilters());
936 	}
937 
938 	/* (non-Javadoc)
939 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFiltersBySet(java.lang.String, int)
940 	 */
941 	public 	List<Filter>	getFiltersBySet(String set, int size) {
942 		return(this.filtersDao.getFiltersBySet(set, size));
943 	}
944 
945 	/* (non-Javadoc)
946 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicNamesBySet(java.lang.String, int)
947 	 */
948 	public	List<String>	getPicNamesBySet(String setName, int size) {
949 		Set set = getSet(setName);
950 		return(getPicNamesBySet(set, size));
951 	}
952 
953 	/* (non-Javadoc)
954 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicNamesBySet(com.buckosoft.PicMan.domain.Set, int)
955 	 */
956 	public List<String> getPicNamesBySet(Set set, int size) {
957 		if (set.isMetaSet())
958 			return(this.metaSetFilter.getListOfPicNamesInMetaSet(set, size, MetaSet.NONE, 0));
959 		if (set.isMicroSet() || set.isNanoSet())
960 			return(this.getMicroSetPicNamesInSet(set.getSid()));
961 		return(this.filtersDao.getPicNamesBySet(set, size));
962 	}
963 
964 
965 	@Override
966 	public List<String> getPicNamesBySet(MetaSet set, int size, int rateOp, int rateVal) {
967 		return(this.metaSetFilter.getListOfPicNames(set, size, rateOp, rateVal));
968 	}
969 
970 	/* (non-Javadoc)
971 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicNamesBySet(java.lang.String, int, int, int)
972 	 */
973 	public List<String> getPicNamesBySet(String setName, int size, int rateOp, int rateVal) {
974 		Set set = getSet(setName);
975 		return(getPicNamesBySet(set, size, rateOp, rateVal));
976 	}
977 
978 	/* (non-Javadoc)
979 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicNamesBySet(java.lang.String, int, int, int)
980 	 */
981 	public	List<String>	getPicNamesBySet(Set set, int size, int rateOp, int rateVal) {
982 		if (set.isMetaSet())
983 			return(this.metaSetFilter.getListOfPicNamesInMetaSet(set, size, rateOp, rateVal));
984 		if (set.isMicroSet() || set.isNanoSet())
985 			return(this.getMicroSetPicNamesInSet(set.getSid()));
986 //		if (set.isFuncSet())
987 // aborted:	return(this.getPicNamesByFunc(set.getSid(), size, rateOp, rateVal));
988 		return(this.filtersDao.getPicNamesBySet(set, size, rateOp, rateVal));
989 	}
990 
991 	public List<String>	getPicNamesByFunc(int func, int size, int rateOp, String operand) {
992 		switch (func) {
993 		case Set.FUNC_SID_DATE:
994 			if (rateOp == 0)
995 				return(this.picsDao.getPicNames());
996 			if (operand == null)
997 				operand = "1900-01-01";
998 			return(this.picsDao.getPicNamesByDateFunc(MetaSet.rateOps[rateOp], operand));
999 //			return(new LinkedList<String>());
1000 		case Set.FUNC_SID_ROOT:
1001 			return(this.picsDao.getPicNamesByRootFunc(MetaSet.rateOps[rateOp], Integer.parseInt(operand)));
1002 		default:
1003 			RuntimeException e = new RuntimeException("unknown func: " + func);
1004 		
1005 			throw e;
1006 		}
1007 		
1008 	}
1009 	
1010 	/* (non-Javadoc)
1011 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFilterDates()
1012 	 */
1013 	public	HashMap<String, Date>	getSetTimestamps() {
1014 		HashMap<String, Date> hm = this.setTimestampsDao.getSetTimestamps();
1015 		return(hm);
1016 	}
1017 
1018 	/* (non-Javadoc)
1019 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#addFilter(com.buckosoft.PicMan.domain.Filter)
1020 	 */
1021 	public	void	addFilter(Filter filter) {
1022 //		Filter oldFilter = this.filtersDao.getFilter(filter.getPicName());
1023 
1024 		this.filtersDao.addFilter(filter);
1025 		this.updateMicroFilters(filter);
1026 //		this.processFilterDates(filter);
1027 /*
1028 		// build a list of changed metaSets
1029 		LinkedHashMap<String, String> changed = new LinkedHashMap<String, String>();
1030 		List<Set> sets = this.getSets();
1031 		Iterator<Set> iter = sets.iterator();
1032 		int		i;
1033 		while (iter.hasNext()) {
1034 			Set set = iter.next();
1035 			if (!set.isMetaSet())
1036 				continue;
1037 			if (DEBUGMETASETS) {
1038 				if (set.getName().equals("DickB"))
1039 					logger.info("DickB");
1040 			}
1041 
1042 			boolean[] reto = this.metaSetFilter.isFilterInSet(this.getMetaSet(set.getSid()), oldFilter);
1043 			boolean[] retn = this.metaSetFilter.isFilterInSet(this.getMetaSet(set.getSid()), filter);
1044 			
1045 			if (DEBUGMETASETS) {
1046 				String	s = "";
1047 				for (i=0; i<sizeArray.length; i++)
1048 					s += reto[i] ? "T" : "F";
1049 				logger.info("reto=" + s + "  - " + set.getName());
1050 				s = "";
1051 				for (i=0; i<sizeArray.length; i++)
1052 					s += retn[i] ? "T" : "F";
1053 				logger.info("retn=" + s + "  - " + set.getName());
1054 			}
1055 
1056 			for (i=0; i<sizeArray.length; i++) {
1057 				if (reto[i] ^ retn[i]) {
1058 					if (DEBUG)
1059 						logger.info("set updated: " + set.getName() + " ro=" + reto[i] + " rn=" + retn[i]);
1060 					changed.put(set.getName() + "_" + sizeArray[i], "");
1061 				}
1062 			}
1063 		}
1064 //		if (!changed.isEmpty()) {
1065 //			this.setTimestampsDao.updateFilterDates(changed);
1066 //		}
1067 */	}
1068 /*
1069 	@SuppressWarnings("unchecked")
1070 	public	void processFilterDates(Filter f) {
1071 		if (f != null) {
1072 			LinkedHashMap<String, Integer> oldf = this.getFilter(f.getPicName()).getFilters();
1073 			LinkedHashMap<String, Integer> newf = (LinkedHashMap<String, Integer>)f.getFilters().clone();
1074 			LinkedHashMap<String, String> changed = new LinkedHashMap<String, String>();
1075 			
1076 			Iterator<String> it = oldf.keySet().iterator();
1077 			while (it.hasNext()) {
1078 				String	oldKey = it.next();
1079 				if (!newf.containsKey(oldKey)) {
1080 					if (DEBUG)
1081 						logger.info("newf !key" + oldKey);
1082 					if (((Integer)oldf.get(oldKey)).intValue() != 0) {
1083 						if (DEBUG)
1084 							logger.info("Add newf" + oldKey);
1085 						changed.put(oldKey, "");
1086 					}
1087 				} else {
1088 					if (DEBUG)
1089 						logger.info("comparing: " + oldKey + " old:" + ((Integer)oldf.get(oldKey)).intValue() + " new: " + ((Integer)newf.get(oldKey)).intValue());
1090 					if (((Integer)oldf.get(oldKey)).intValue() != ((Integer)newf.get(oldKey)).intValue()) {
1091 						changed.put(oldKey, "");
1092 						if (DEBUG)
1093 							logger.info("keys different");
1094 					}
1095 					newf.remove(oldKey);
1096 				}
1097 			}
1098 			it = newf.keySet().iterator();
1099 			while (it.hasNext()) {			// These are in new, but not old, so update
1100 				String newKey = (String)it.next();
1101 				if (DEBUG)
1102 					logger.info("newf has key: " + newKey);
1103 				changed.put(newKey, "");
1104 			}
1105 //			this.setTimestampsDao.updateFilterDates(changed);
1106 		}
1107 	}
1108 */	
1109 	
1110 	
1111 	/* (non-Javadoc)
1112 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getFilter(java.lang.String)
1113 	 */
1114 	public	Filter	getFilter(String picName) {
1115 		Filter f = this.filtersDao.getFilter(picName);
1116 		Pic pic = this.getPic(picName);
1117 		if (pic == null) {
1118 			throw new RuntimeException("No pic for " + picName);
1119 		}
1120 		List<FilterMicroSet>	li = this.filtersMicroSetsDao.getFiltersInPid(pic.getPid());
1121 		Iterator<FilterMicroSet> iter = li.iterator();
1122 		while (iter.hasNext()) {
1123 			FilterMicroSet fms = iter.next();
1124 			f.addFilter(this.setsDao.getSet(fms.getSid()).getName(), fms.getValue());
1125 		}
1126 
1127 		return(f);
1128 	}
1129 
1130 
1131 	/* (non-Javadoc)
1132 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicFromFilterMicroSet(int)
1133 	 */
1134 	public FilterMicroSet getPicFromFilterMicroSet(int pid, int sid) {
1135 		return(this.filtersMicroSetsDao.getFilterMicroSet(pid, sid));
1136 	}
1137 
1138 	private	List<String>	getMicroSetPicNamesInSet(int sid) {
1139 		List<FilterMicroSet>	ll = this.filtersMicroSetsDao.getPicsInSet(sid);
1140 		List<String>	list = new LinkedList<String>();
1141 		
1142 		Iterator<FilterMicroSet>	iter = ll.iterator();
1143 		while (iter.hasNext()) {
1144 			FilterMicroSet fms = iter.next();
1145 			if (fms.getValue() != 0)
1146 				list.add(this.getPic(fms.getPid()).getName());
1147 		}
1148 		return(list);
1149 	}
1150 
1151 	private	void	updateMicroFilters(Filter filter) {
1152 		Pic pic = this.getPic(filter.getPicName());
1153 		this.filtersMicroSetsDao.deleteFilters(pic.getPid());
1154 
1155 		LinkedHashMap<String, Integer> map = filter.getFilters();
1156 		Iterator<String> it = map.keySet().iterator();
1157 		String	key;
1158 		Set set;
1159 		while (it.hasNext()) {
1160 			key = (String)it.next();
1161 //			if (DEBUG)
1162 //				logger.info("key=" + key);
1163 			if (key.indexOf('_') != -1)
1164 				continue;
1165 			set = this.getSet(key);
1166 			this.filtersMicroSetsDao.storeFilter(set.getSid(), pic.getPid(), map.get(key));
1167 		}
1168 
1169 	}
1170 
1171 	/* (non-Javadoc)
1172 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getUser(int)
1173 	 */
1174 	public User getUser(int userid) throws DataAccessException {
1175 		return(this.usersDao.getUser(userid));
1176 	}
1177 
1178 	/* (non-Javadoc)
1179 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeUser(com.buckosoft.PicMan.domain.User)
1180 	 */
1181 	public void storeUser(User user) {
1182 		this.usersDao.storeUser(user);
1183 	}
1184 
1185 	///////////////////////////////////////////////////////////////////////////
1186 	/* Virgin management */
1187 
1188 	/* (non-Javadoc)
1189 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getVirgins()
1190 	 */
1191 	public	List<Virgin>	getVirgins() {
1192 		return(this.virginsDao.getVirgins());
1193 	}
1194 
1195 	/* (non-Javadoc)
1196 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getVirgins(int)
1197 	 */
1198 	public	List<Virgin>	getVirgins(int max) {
1199 		return(this.virginsDao.getVirgins(max));
1200 	}
1201 
1202 	/* (non-Javadoc)
1203 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#isVirgin(java.lang.String)
1204 	 */
1205 	public	boolean	isVirgin(String pic) {
1206 		return(this.virginsDao.isVirgin(pic));
1207 	}
1208 
1209 	/* (non-Javadoc)
1210 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#addVirgin(java.lang.String)
1211 	 */
1212 	public	void	addVirgin(String pic) {
1213 		this.virginsDao.addVirgin(pic);
1214 	}
1215 
1216 	/* (non-Javadoc)
1217 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#deleteVirgin(java.lang.String)
1218 	 */
1219 	public	void	deleteVirgin(String pic) {
1220 		this.virginsDao.deleteVirgin(pic);
1221 	}
1222 
1223 	/* (non-Javadoc)
1224 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getVirginCount()
1225 	 */
1226 	public	int		getVirginCount() {
1227 		return(this.virginsDao.getVirginCount());
1228 	}
1229 
1230 
1231 	///////////////////////////////////////////////////////////////////////////
1232 	/* Pic management */
1233 
1234 	/* (non-Javadoc)
1235 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#addPic(com.buckosoft.PicMan.domain.Pic)
1236 	 */
1237 	public	void	addPic(Pic pic) {
1238 		this.picsDao.addPic(pic);
1239 	}
1240 
1241 	/* (non-Javadoc)
1242 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#updatePic(com.buckosoft.PicMan.domain.Pic)
1243 	 */
1244 	public	void	updatePic(Pic pic) {
1245 		this.picsDao.updatePic(pic);
1246 	}
1247 
1248 	/* (non-Javadoc)
1249 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPic(java.lang.String)
1250 	 */
1251 	public	Pic		getPic(String picName) {
1252 		return(this.picsDao.getPic(picName));
1253 	}
1254 
1255 	/* (non-Javadoc)
1256 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPic(int)
1257 	 */
1258 	public	Pic		getPic(int pid) {
1259 		return(this.picsDao.getPic(pid));
1260 	}
1261 
1262 	/*
1263 	 * (non-Javadoc)
1264 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getNewestPic()
1265 	 */
1266 	public Pic getNewestPic() {
1267 		return(this.picsDao.getNewestPic());
1268 	}
1269 
1270 	/* (non-Javadoc)
1271 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRandomPic()
1272 	 */
1273 	public Pic getRandomPic() {
1274 		return(this.picsDao.getRandomPic());
1275 	}
1276 
1277 	/* (non-Javadoc)
1278 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicsByMD5Sum(long)
1279 	 */
1280 	@Override
1281 	public List<Pic> getPicsByMD5Sum(long md5sum) {
1282 		return(this.picsDao.getPicsByMD5Sum(md5sum));
1283 	}
1284 
1285 
1286 	/* (non-Javadoc)
1287 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getRandomHomePagePic(com.buckosoft.PicMan.domain.User)
1288 	 */
1289 	public String getRandomHomePagePicName(User user) {
1290 		if (user.getHomeThumbSetName().isEmpty())
1291 			return("");
1292 		if (homeThumbAttr.homeThumbsUser == null || homeThumbAttr.homeThumbsUser != user 
1293 				|| !user.getHomeThumbSetName().equals(homeThumbAttr.homeThumbsForUserSetCached)) {
1294 			homeThumbAttr.homeThumbsUser = user;
1295 			homeThumbAttr.homeThumbsForUser = null;
1296 		}
1297 		if (homeThumbAttr.homeThumbsForUser == null) {
1298 			homeThumbAttr.homeThumbsForUserSetCached = user.getHomeThumbSetName();
1299 			homeThumbAttr.homeThumbsForUser = new LinkedList<String>();
1300 			List<String> ll = this.getPicNamesBySet(user.getHomeThumbSetName(), 75);
1301 			homeThumbAttr.homeThumbsUserIndex = 0;
1302 			while (!ll.isEmpty()) {
1303 				double d = Math.random() * ll.size();
1304 				homeThumbAttr.homeThumbsForUser.add(ll.remove((int)d));
1305 			}
1306 		}
1307 		if (homeThumbAttr.homeThumbsForUser.isEmpty())
1308 			return("");
1309 		String s = homeThumbAttr.homeThumbsForUser.get(homeThumbAttr.homeThumbsUserIndex++);
1310 		if (homeThumbAttr.homeThumbsUserIndex >= homeThumbAttr.homeThumbsForUser.size())
1311 			homeThumbAttr.homeThumbsUserIndex = 0;
1312 		return(s);
1313 	}
1314 
1315 	@Override
1316 	public void onSetChanged(SetSize setSize) {
1317 		if (homeThumbAttr.homeThumbsForUserSetCached == setSize.getSetName()) {
1318 			homeThumbAttr.homeThumbsForUser = null;
1319 		}
1320 	}
1321 
1322 	/* (non-Javadoc)
1323 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getHomePageRandomPic()
1324 	 */
1325 /*	public Pic getRandomHomePagePic(User user) {
1326 		return(this.picsDao.getRandomPic(1));
1327 	}
1328 */
1329 
1330 	/* (non-Javadoc)
1331 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicsMap()
1332 	 */
1333 	public	HashMap<String, Date>		getPicsMap() {
1334 		return(this.picsDao.getPicsMap());
1335 	}
1336 
1337 	/* (non-Javadoc)
1338 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPics()
1339 	 */
1340 	public	List<Pic>	getPics() {
1341 		return(this.picsDao.getPics());
1342 	}
1343 
1344 	/* (non-Javadoc)
1345 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPics(java.lang.String)
1346 	 */
1347 	public	List<Pic>	getPics(String picName) {
1348 		return(this.picsDao.getPics(picName));
1349 	}
1350 
1351 	/* (non-Javadoc)
1352 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPics(com.buckosoft.PicMan.domain.Set)
1353 	 */
1354 	public List<Pic> getPics(Set set, int size) {
1355 		size = normalizeSize(size);
1356 		List<String>	list = this.getPicNamesBySet(set.getName(), size);
1357 		return(this.picsDao.getPics(list));
1358 	}
1359 
1360 	/* (non-Javadoc)
1361 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicsInDir(int, java.lang.String)
1362 	 */
1363 	public List<Pic> getPicsInDir(int rid, String dirName) {
1364 		return(this.picsDao.getPicsInDir(rid, dirName));
1365 	}
1366 	
1367 	public List<Pic> getPicsNewerThan(Calendar calendar) {
1368 		return(this.picsDao.getPicsNewerThan(calendar));
1369 	}
1370 
1371 	/* (non-Javadoc)
1372 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicRate(com.buckosoft.PicMan.domain.Pic, com.buckosoft.PicMan.domain.Set, int)
1373 	 */
1374 	@Override
1375 	public double	getPicRate(String picName, Set set, int size) {
1376 		size = normalizeSize(size);
1377 		Filter f = this.getFilter(picName);
1378 		if (!set.isMetaSet()) {
1379 			return(f.getFilter(set.getName(), size));
1380 		} else {
1381 			return(this.getMetaSetFilter().getPicRate(this.getMetaSet(set.getSid()), f, size));
1382 		}
1383 	}
1384 
1385 	@Override
1386 	public double	getPicRate(String picName, MetaSet metaSet, int size) {
1387 		size = normalizeSize(size);
1388 		Filter f = this.getFilter(picName);
1389 		return(this.getMetaSetFilter().getPicRate(metaSet, f, size));
1390 	}
1391 
1392 	/* (non-Javadoc)
1393 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicMaxThumbCacheDirUsed()
1394 	 */
1395 	public int getPicMaxThumbCacheDirUsed() {
1396 		return(this.picsDao.getMaxThumbCacheDirUsed());
1397 	}
1398 
1399 	/* (non-Javadoc)
1400 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getPicThumbCacheFillCount(int)
1401 	 */
1402 	public int getPicThumbCacheFillCount(int cacheDir) {
1403 		return(this.picsDao.getThumbCacheFillCount(cacheDir));
1404 	}
1405 
1406 	/* (non-Javadoc)
1407 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getUuid(java.lang.String, int)
1408 	 */
1409 	public String		getUuid(String setName, int size) {
1410 		DecimalFormat df3 = new DecimalFormat("000");
1411 		return(new String(setName + "_" + df3.format(size)));
1412 	}
1413 
1414 	/** Given an arbitrary tile height, return a height that we actually know about.
1415 	 * @param size The size to normalize
1416 	 * @return One of the sizes from our size array of filters
1417 	 */
1418 	public int normalizeSize(int size) {
1419 		for (int i=0; i<this.sizeArray.length; i++) {
1420 			if (size <= this.sizeArray[i])
1421 				return(this.sizeArray[i]);
1422 		}
1423 		return(this.sizeArray[this.sizeArray.length-1]);
1424 	}
1425 
1426 
1427 	public Date getClientSyncTimestamp(String host) {
1428 		return(this.server_SyncDao.getClientTimestamp(host));
1429 	}
1430 
1431 	public void setClientSyncTimestamp(String host) {
1432 		this.server_SyncDao.setClientTimestamp(host);
1433 	}
1434 
1435 
1436 	/* (non-Javadoc)
1437 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#updateSetTimestamp(java.lang.String)
1438 	 */
1439 	@Override
1440 	public void updateSetTimestamp(String setSize) {
1441 		this.setTimestampsDao.updateSetTimestamp(setSize);
1442 	}
1443 
1444 	/* (non-Javadoc)
1445 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeSyncClient(com.buckosoft.PicMan.domain.SyncClient)
1446 	 */
1447 	@Override
1448 	public void storeSyncClient(SyncClient syncClient) {
1449 		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
1450 		session.getTransaction().begin();
1451 		try {
1452 			session.saveOrUpdate(syncClient);
1453 		} finally {
1454 			session.getTransaction().commit();
1455 		}		
1456 	}
1457 
1458 
1459 	/* (non-Javadoc)
1460 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSyncClients()
1461 	 */
1462 	@SuppressWarnings("unchecked")
1463 	@Override
1464 	public List<SyncClient> getSyncClients() {
1465 		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
1466 		session.getTransaction().begin();
1467 		List<SyncClient> result = null;
1468 		try {
1469 			result = session.createQuery("from SyncClient").list();
1470 		} catch (HibernateException e) {
1471 			e.printStackTrace();
1472 		} finally {
1473 			session.getTransaction().commit();
1474 		}
1475 		return(result);
1476 	}
1477 
1478 
1479 	/* (non-Javadoc)
1480 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#storeSyncServer(com.buckosoft.PicMan.domain.SyncServer)
1481 	 */
1482 	@Override
1483 	public void storeSyncServer(SyncServer syncServer) {
1484 		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
1485 		session.getTransaction().begin();
1486 		try {
1487 			session.saveOrUpdate(syncServer);
1488 		} finally {
1489 			session.getTransaction().commit();
1490 		}
1491 	}
1492 
1493 
1494 	/* (non-Javadoc)
1495 	 * @see com.buckosoft.PicMan.db.DatabaseFacade#getSyncServers()
1496 	 */
1497 	@Override
1498 	public List<SyncServer> getSyncServers() {
1499 		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
1500 		session.getTransaction().begin();
1501 		@SuppressWarnings("unchecked")
1502 		List<SyncServer> result = session.createQuery("from SyncServer").list();
1503 		session.getTransaction().commit();
1504 		return(result);
1505 	}
1506 }