1
2
3
4
5
6
7
8 package com.buckosoft.PicMan.business.mosaic;
9
10 import java.awt.image.BufferedImage;
11 import java.io.File;
12 import java.util.Date;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.LinkedList;
16
17 import javax.imageio.ImageIO;
18 import javax.imageio.ImageWriter;
19 import javax.imageio.stream.ImageOutputStream;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import com.buckosoft.PicMan.business.PicManFacade;
25 import com.buckosoft.PicMan.business.util.CopyFile;
26 import com.buckosoft.PicMan.db.DatabaseFacade;
27 import com.buckosoft.PicMan.domain.JobLogEntry;
28 import com.buckosoft.PicMan.domain.Mosaic;
29 import com.buckosoft.PicMan.domain.Pic;
30 import com.buckosoft.PicMan.domain.Set;
31
32
33
34
35
36
37
38 public class MosaicEngine {
39 protected static boolean DEBUG = false;
40 private final Log logger = LogFactory.getLog(getClass());
41
42 protected PicManFacade pmf;
43 protected DatabaseFacade dbf;
44
45 protected Mosaic mosaic;
46 protected Pic masterPic;
47 protected int mid;
48 protected BufferedImage bi;
49 protected int tileHeight = 50;
50 protected Date lastMosaicUpdate = new Date(0);
51 protected Set mosaicSet;
52
53 protected JobLogEntry jobLogEntry = null;
54
55
56 protected HashMap<String, ConfigItem> configMap = new HashMap<String, ConfigItem>();
57
58 protected LinkedList<String> configList = new LinkedList<String>();
59
60 protected HashMap<String, Object> buildParameters = new HashMap<String, Object>();
61
62
63
64
65 public MosaicEngine() {
66 addConfig("rateWeight", "rate multiplier when selecting pics", ConfigItem.TYPE_DOUBLE, 1.0);
67
68 }
69
70
71
72 public void setPicMan(PicManFacade pmf) {
73 this.pmf = pmf;
74 this.dbf = pmf.getDB();
75 }
76
77
78
79
80 public void setDEBUG(boolean debugFlag) {
81 DEBUG = debugFlag;
82 }
83
84
85
86
87 public Date getLastMosaicUpdate() {
88 return lastMosaicUpdate;
89 }
90
91 protected void setLastMosaicUpdate() {
92 this.lastMosaicUpdate = new Date();
93 }
94
95
96
97
98
99 public int getTileHeight() {
100 return tileHeight;
101 }
102
103
104
105
106 public void setTileHeight(int tileHeight) {
107 this.tileHeight = tileHeight;
108 }
109
110
111
112
113 public BufferedImage getImage() {
114 return bi;
115 }
116
117
118
119
120 public String getName() {
121 if (this.mosaic != null)
122 return(this.mosaic.getName());
123 return("No Name");
124 }
125
126
127
128
129 public String getMasterPicName() {
130 if (this.mosaic != null)
131 return(this.mosaic.getMasterPic());
132 return("");
133 }
134
135
136
137 public String getOutputFileName() {
138 if (this.mosaic != null)
139 return(this.mosaic.getOutPic());
140 return("No Filename");
141 }
142
143
144
145
146 public String getDurationAsString() {
147 if (jobLogEntry == null)
148 return("xx:xx");
149 return(jobLogEntry.getDurationAsString());
150 }
151
152
153
154
155 public void setMosaic(Mosaic mosaic) {
156 this.mosaic = mosaic;
157 this.mosaicSet = pmf.getDB().getSet(mosaic.getSid());
158 this.masterPic = pmf.getDB().getPic(mosaic.getMasterPic());
159 this.mid = mosaic.getMid();
160 this.tileHeight = mosaic.getTileHeight();
161 this.setupBuildParameters();
162 this.bi = pmf.getPicReader().readPic(this.masterPic);
163 setLastMosaicUpdate();
164 }
165
166
167
168
169
170 public void outputMosaicFile(boolean makeBackup) {
171 Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
172 ImageWriter writer = (ImageWriter)writers.next();
173 File file = new File(this.mosaic.getOutPic());
174 if (DEBUG)
175 logger.info("Writing jpg to '" + file.getPath() + "'");
176 try {
177 ImageOutputStream oos = ImageIO.createImageOutputStream(file);
178 writer.setOutput(oos);
179 writer.write(bi);
180 oos.close();
181 } catch (Exception e) {
182
183 pmf.addError(new Exception ("Can't write jpeg to '"+ file.getPath() + "'",e));
184 return;
185 }
186 if (makeBackup)
187 CopyFile.makeBackup(pmf, file);
188 }
189
190
191
192
193
194 public boolean build() throws Exception {
195 jobLogEntry = new JobLogEntry();
196 jobLogEntry.setType(JobLogEntry.MOSAIC);
197 jobLogEntry.setName(this.mosaic.getName());
198 pmf.addJobToLog(jobLogEntry);
199 this.mosaic.setStartTime(new Date());
200 boolean ret = false;
201 try {
202 ret = _build();
203 } catch (Exception e) {
204 jobLogEntry.setEndTime();
205 throw e;
206 }
207 jobLogEntry.setEndTime();
208 if (!mosaic.isBatch())
209 pmf.getDB().storeMosaic(mosaic);
210 outputMosaicFile(mosaic.isMakeBackup());
211 return(ret);
212 }
213
214 protected boolean _build() throws Exception {
215 throw new Exception("Should be overridden");
216
217 }
218
219
220
221
222 public String getStatus() {
223 return("Should be overridden");
224 }
225
226
227
228
229 public String getInfo() {
230 return("Should be overridden");
231 }
232
233
234
235
236
237
238
239
240 public class ConfigItem {
241 public final static int TYPE_STRING = 1;
242 public final static int TYPE_INT = 2;
243 public final static int TYPE_DOUBLE = 3;
244 public final static int TYPE_BOOLEAN = 4;
245
246 private String name;
247 private String description;
248 @SuppressWarnings("unused")
249 private int order;
250 private int type;
251 private int valueInt;
252 private double valueDouble;
253 private String valueString;
254
255
256
257
258
259
260
261 public ConfigItem(String name, String description, int type, int order) {
262 this.name = name;
263 this.description = description;
264 this.type = type;
265 this.order = order;
266 }
267
268
269
270
271 public int getValueInt() {
272 return valueInt;
273 }
274
275
276
277
278 public void setValueInt(int valueInt) {
279 this.valueInt = valueInt;
280 }
281
282
283
284
285 public double getValueDouble() {
286 return valueDouble;
287 }
288
289
290
291
292 public void setValueDouble(double valueDouble) {
293 this.valueDouble = valueDouble;
294 }
295
296
297
298
299 public String getValueString() {
300 return valueString;
301 }
302
303
304
305
306 public void setValueString(String valueString) {
307 this.valueString = valueString;
308 }
309
310
311
312
313 public String getName() {
314 return name;
315 }
316
317
318
319
320 public String getDescription() {
321 return description;
322 }
323
324
325
326
327 public int getType() {
328 return type;
329 }
330
331 }
332
333 protected void addConfig(String name, String description, int type, int value) {
334 ConfigItem ci = new ConfigItem(name, description, type, configMap.size());
335 ci.valueInt = value;
336 configMap.put(name, ci);
337 configList.add(name);
338 }
339 protected void addConfig(String name, String description, int type, double value) {
340 ConfigItem ci = new ConfigItem(name, description, type, configMap.size());
341 ci.valueDouble = value;
342 configMap.put(name, ci);
343 configList.add(name);
344 }
345
346
347
348
349 public HashMap<String, ConfigItem> getConfigMap() {
350 return(configMap);
351 }
352
353 private void setupBuildParameters() {
354 HashMap<String, String> engineConfig = mosaic.getEngineConfig();
355 for (String key : configMap.keySet()) {
356 ConfigItem ci = configMap.get(key);
357 String v = engineConfig.get(key);
358 if (v != null) {
359 switch (ci.type) {
360 case ConfigItem.TYPE_INT:
361 int i = -1;
362 try {
363 i = Integer.parseInt(v);
364 } catch (NumberFormatException e) {
365 pmf.addError(e);
366 logger.info(e);
367 i = -1;
368 }
369 buildParameters.put(key, new Integer(i));
370 break;
371 case ConfigItem.TYPE_DOUBLE:
372 double d = 0.0;
373 try {
374 if (!v.isEmpty())
375 d = Double.parseDouble(v);
376 } catch (NumberFormatException e) {
377 pmf.addError(e);
378 logger.info(e);
379 d = 0.0;
380 }
381 buildParameters.put(key, new Double(d));
382 break;
383 default:
384 Exception e = new Exception("Unhandled type " + ci.type);
385 pmf.addError(e);
386 logger.info(e);
387 break;
388 }
389 } else {
390 switch (ci.type) {
391 case ConfigItem.TYPE_INT:
392 buildParameters.put(key, new Integer(ci.getValueInt()));
393 break;
394 case ConfigItem.TYPE_DOUBLE:
395 buildParameters.put(key, new Double(ci.getValueDouble()));
396 break;
397 default:
398 Exception e = new Exception("Unhandled default type " + ci.type);
399 pmf.addError(e);
400 logger.info(e);
401 break;
402 }
403 }
404 }
405 }
406 }