1
2
3
4
5
6
7
8
9 package com.buckosoft.PicMan.business;
10
11 import java.io.File;
12 import java.util.ArrayList;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.concurrent.locks.ReentrantLock;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import com.buckosoft.PicMan.business.contact.ContactEngine;
24 import com.buckosoft.PicMan.domain.Chain;
25 import com.buckosoft.PicMan.domain.ContactParams;
26 import com.buckosoft.PicMan.domain.Filter;
27 import com.buckosoft.PicMan.domain.FilterMicroSet;
28 import com.buckosoft.PicMan.domain.JobLogEntry;
29 import com.buckosoft.PicMan.domain.MetaSet;
30 import com.buckosoft.PicMan.domain.MetaSetRule;
31 import com.buckosoft.PicMan.domain.Pic;
32 import com.buckosoft.PicMan.domain.PosterParams;
33 import com.buckosoft.PicMan.domain.Set;
34 import com.buckosoft.PicMan.domain.SetSize;
35 import com.buckosoft.PicMan.domain.System;
36
37
38
39
40
41
42
43
44 public class ContactManager implements SetChangedListener {
45
46 private static boolean DEBUG = false;
47 private static final boolean DEBUGENTRY = false;
48 private static final boolean DEBUGSPIN = false;
49
50 protected final Log logger = LogFactory.getLog(getClass());
51
52
53
54
55 private static final boolean onePicOnly = false;
56
57 private PicManFacade pmf;
58
59 private LinkedList<ContactParams> contactList = new LinkedList<ContactParams>();
60 private LinkedList<ContactParams> spinList = new LinkedList<ContactParams>();
61 private String contactRunning;
62 private boolean abortRequest = false;
63
64 private List<String> cachedPicNames;
65 private ContactParams cachedContactParams;
66
67 private ReentrantLock cpLock = new ReentrantLock();
68 private ContactParams currentContactParams;
69
70 public void setPicMan(PicManFacade pmf) {
71 this.pmf = pmf;
72 pmf.addSetChangedListener(this);
73 }
74
75
76
77
78 public String getContactRunning() {
79 return contactRunning;
80 }
81
82 public boolean makeContacts() throws Exception {
83 try {
84 contactList = determineContactsToMake();
85 } catch (Exception e) {
86
87 throw e;
88 }
89 boolean workDone = false;
90 if (DEBUGENTRY)
91 logger.info("process contacts: " + contactList.size());
92 Iterator<ContactParams> it = contactList.iterator();
93 if (it.hasNext()) {
94
95
96
97 workDone = true;
98 }
99 try {
100 JobLogEntry jle = null;
101 while (it.hasNext()) {
102 ContactParams cp = (ContactParams)it.next();
103 setContactParamsRunning(cp);
104 contactRunning = cp.getUuid();
105
106 if (!pmf.getDB().getSystem().isJobLogSummaryOnly() || cp.getContactNumber() == 0) {
107 if (DEBUG)
108 logger.debug("Start log entry for " + cp.getContactNumber());
109 jle = new JobLogEntry();
110
111 jle.setNote(pmf.getDB().getChain(cp.getCid()).getName());
112 if (!pmf.getDB().getSystem().isJobLogSummaryOnly())
113 jle.setName(cp.getUuid());
114 else
115 jle.setName(cp.getUid());
116 jle.setType(JobLogEntry.CONTACT);
117 pmf.addJobToLog(jle);
118 }
119 ContactEngine contactEngine = null;
120 String engineName = cp.getEngineName();
121 if (cp instanceof PosterParams) {
122 try {
123 contactEngine = (ContactEngine)Class.forName("com.buckosoft.PicMan.business.contact.PosterEngine").newInstance();
124 } catch (Exception e) {
125 Exception ex = new Exception("Can't instantiate Poster Engine: ", e);
126 pmf.addError(ex);
127 }
128
129 }
130 try {
131 if (contactEngine == null)
132 contactEngine = (ContactEngine)Class.forName("com.buckosoft.PicMan.business.contact.engine." + engineName).newInstance();
133 } catch (Exception e) {
134 Exception ex = new Exception("Can't instantiate Contact Engine: " + engineName, e);
135 pmf.addError(ex);
136 }
137 boolean ret = false;
138 if (contactEngine != null) {
139 contactEngine.setPicMan(pmf);
140 contactEngine.setContactManager(this);
141 ret = contactEngine.makeContact(cp);
142 }
143 if (isAbort())
144 jle.setNote("*" + jle.getNote());
145 if (ret == false) {
146 jle.setError();
147 jle.setEndTime();
148 pmf.addJobToLog(jle);
149 }
150 if (!pmf.getDB().getSystem().isJobLogSummaryOnly()
151 || cp.getContactNumber() >= pmf.getDB().getChain(cp.getCid()).getContactCount()-1
152 || cp instanceof PosterParams
153 || isAbort()) {
154 if (DEBUG)
155 logger.debug("Finish log entry for " + cp.getContactNumber());
156 jle.setEndTime();
157 pmf.addJobToLog(jle);
158 }
159 if (isAbort()) {
160 clearAbort();
161 setContactParamsRunning(null);
162 break;
163 }
164 removeFromSpin(cp);
165 }
166 } catch (Exception e) {
167
168 throw e;
169 }
170 return(workDone);
171 }
172
173
174 private void setContactParamsRunning(ContactParams cp) {
175 cpLock.lock();
176 try {
177 currentContactParams = cp;
178 } finally {
179 cpLock.unlock();
180 }
181 }
182
183 public ContactParams getContactParamsRunning() {
184 ContactParams cp;
185 cpLock.lock();
186 try {
187 cp = currentContactParams;
188 } finally {
189 cpLock.unlock();
190 }
191 return(cp);
192 }
193
194
195
196
197
198 public boolean isAbort() {
199 if (!pmf.getDB().getSystem().isEngineOn())
200 return(true);
201 if (!this.abortRequest)
202 return(false);
203 return(true);
204 }
205
206 private void clearAbort() {
207 this.abortRequest = false;
208 }
209
210
211
212
213
214 @Override
215 public void onSetChanged(SetSize ss) {
216 cpLock.lock();
217 try {
218 if (currentContactParams != null
219 && ss.getSize() == currentContactParams.getSize()
220 && ss.getSetName().equals(currentContactParams.getSetName())) {
221 this.abortRequest = true;
222 logger.info("onSetChanged: aborting build of " + ss.getSetSize());
223 }
224 } finally {
225 cpLock.unlock();
226 }
227 }
228
229
230
231
232
233
234 public LinkedList<ContactParams> determineContactsToMake() {
235 LinkedList<ContactParams> theList = new LinkedList<ContactParams>();
236 theList.clear();
237 List<Chain> chains = pmf.getDB().getChains();
238
239
240
241 HashMap<String, Date> filterAgeMap = pmf.getDB().getSetTimestamps();
242 Iterator<Chain> iter = chains.iterator();
243 while (iter.hasNext()) {
244 Chain chain = (Chain)iter.next();
245 if (!chain.isActive())
246 continue;
247 int contactsPerSet = chain.getContactCount();
248 HashMap<String, Date> contactAgeMap = pmf.getDB().getContactOldestMap(chain);
249
250
251
252 Iterator<SetSize> iss = chain.getSetSizes().iterator();
253 while (iss.hasNext()) {
254 SetSize ss = (SetSize)iss.next();
255
256
257 if (!isSpin(chain.getCid(), ss.getSetName(), ss.getSize(), -1)) {
258 Date fdate = (Date)filterAgeMap.get(ss.getSetSize());
259 Date cdate = (Date)contactAgeMap.get(ss.getGuiSetSize());
260 if (DEBUG)
261 logger.debug("Comparing: " + System.getUuid(ss.getSetName(), ss.getSize()) + " f:" + fdate + " c: " + cdate);
262 Date fdateWild = (Date)filterAgeMap.get(ss.getSetName());
263 if (fdateWild != null) {
264 if (cdate != null) {
265 if (fdateWild.after(cdate)) {
266 fdate = null;
267 cdate = null;
268 }
269 }
270 }
271 if (fdate != null) {
272 if (cdate != null) {
273 if (DEBUG)
274 logger.debug("class: f=" + fdate.getClass() + " c=" + cdate.getClass());
275 if (fdate.before(cdate))
276 continue;
277 }
278 } else {
279 if (cdate != null)
280 continue;
281 }
282 if (DEBUG)
283 logger.debug("Building set: " + ss.getSetSize());
284 }
285 for (int i=0; i<contactsPerSet; i++) {
286 ContactParams cp = new ContactParams();
287 cp.setContactNumber(i);
288 cp.setCid(chain.getCid());
289 cp.setSetSize(ss);
290 cp.setRankMinMax(chain.getRatingMin(), chain.getRatingMax());
291 cp.setEngineName(chain.getEngine());
292 if (onePicOnly) {
293 cp.setSize(300);
294 cp.setSetName("X");
295 }
296 File dir = new File(chain.getContactDirectory() + File.separator + ss.getSetName());
297
298 try {
299 if (!dir.isDirectory())
300 dir = dir.getParentFile();
301 } catch (Exception e) {
302 dir = dir.getParentFile();
303 }
304
305 cp.setOutputDirectory(dir.getPath());
306 theList.add(cp);
307 if (onePicOnly)
308 return(theList);
309 }
310 }
311 }
312 for (ContactParams cp : spinList) {
313 if (cp instanceof PosterParams)
314 theList.add(cp);
315 }
316 return(theList);
317 }
318
319 public List<String> getPicNames(ContactParams cp) {
320 if (cachedContactParams != null) {
321 if (cp.equalsPics(cachedContactParams)) {
322 ArrayList<String> al = new ArrayList<String>(cachedPicNames);
323 return(al);
324 }
325 }
326 cachedPicNames = pmf.getDB().getPicNamesBySet(cp.getSetName(), cp.getSize());
327
328 cachedContactParams = cp;
329 ArrayList<String> al = new ArrayList<String>(cachedPicNames);
330 return(al);
331 }
332
333 protected List<String> setupPicsList(ContactParams cp, List<String> picNames) {
334
335
336 ArrayList<String> al = new ArrayList<String>(picNames);
337 Iterator<String> iter = al.iterator();
338 while (iter.hasNext()) {
339 String picName = iter.next();
340 if (isFilteredOut(cp, picName))
341 iter.remove();
342 }
343 return(al);
344 }
345 protected boolean isFilteredOut(ContactParams cp, String picName) {
346 Filter f = pmf.getDB().getFilter(picName);
347 double rating = 9;
348 Set set = pmf.getDB().getSet(cp.getSetName());
349 if (set.isMetaSet()) {
350
351
352
353
354
355
356 rating = pmf.getDB().getPicRate(picName, set, cp.getSize());
357 boolean nono = false;
358 if (nono) {
359 MetaSet ms = pmf.getDB().getMetaSet(set.getSid());
360 List<MetaSetRule> msrList = ms.getRules();
361 Iterator<MetaSetRule> msrIter = msrList.iterator();
362 int count = 0;
363 while (msrIter.hasNext()) {
364
365
366 rating *= count;
367 int prate = f.getFilter(cp.getSetName(), cp.getSize());
368 rating += prate;
369 count++;
370 rating /= count;
371 }
372 }
373 } else if (set.isMicroSet() || set.isNanoSet()) {
374 Pic pic = pmf.getDB().getPic(picName);
375 FilterMicroSet fms = pmf.getDB().getPicFromFilterMicroSet(pic.getPid(), set.getSid());
376 if (fms != null)
377 rating = fms.getValue();
378 else
379 rating = 0;
380 } else {
381 rating = f.getFilter(cp.getSetName(), cp.getSize());
382 }
383 logger.debug("isFilteredOut: " + picName + " " + rating);
384 if (rating < cp.getRankMin())
385 return(true);
386 if (cp.getRankMax() == 9)
387 return(false);
388 if (rating > cp.getRankMax())
389 return(true);
390 return(false);
391 }
392
393
394
395
396
397
398 public void addSpin(List<ContactParams> list) {
399 Iterator<ContactParams> iter = list.iterator();
400 while (iter.hasNext()) {
401 ContactParams cp = iter.next();
402 if (DEBUGSPIN)
403 logger.info("addSpin: cp cid=" + cp.getCid() + " ss= " + cp.getSetName() + "_" + cp.getSize() + " cn=" + cp.getContactNumber());
404 if (!isOnList(spinList, cp)) {
405 spinList.add(cp);
406 }
407 }
408 }
409
410 private boolean isOnList(List<ContactParams> list, ContactParams cp) {
411 Iterator<ContactParams> iter = list.iterator();
412 while (iter.hasNext()) {
413 ContactParams cpl = iter.next();
414 if (cpl.equals(cp))
415 return(true);
416 }
417 return(false);
418 }
419
420
421
422
423
424
425
426 private boolean isSpin(int cid, String setName, int size, int contactNumber) {
427 Iterator<ContactParams> iter = spinList.iterator();
428 ContactParams cp = new ContactParams(cid, setName, size, contactNumber);
429 while (iter.hasNext()) {
430 ContactParams cpl = iter.next();
431 if (cpl.equals(cp))
432 return(true);
433 }
434 return(false);
435 }
436 private void removeFromSpin(ContactParams cp) {
437 if (DEBUGSPIN)
438 logger.info("removeFromSpin: cp cid=" + cp.getCid() + " ss= " + cp.getSetName() + "_" + cp.getSize() + " cn=" + cp.getContactNumber());
439 Iterator<ContactParams> iter = spinList.iterator();
440 while (iter.hasNext()) {
441 ContactParams cpl = iter.next();
442 if (cpl.equals(cp)) {
443 spinList.remove(cpl);
444 return;
445 }
446 }
447 }
448 }