View Javadoc
1   /******************************************************************************
2    * MosaicMan.java - Manage mosaic activities
3    * 
4    * PicMan - The BuckoSoft Picture Manager in Java
5    * Copyright(c) 2007 - Dick Balaska
6    * 
7    */
8   package com.buckosoft.PicMan.business.mosaic;
9   
10  import java.util.Iterator;
11  import java.util.LinkedList;
12  import java.util.List;
13  
14  import org.apache.commons.logging.Log;
15  import org.apache.commons.logging.LogFactory;
16  
17  import com.buckosoft.PicMan.business.PicManFacade;
18  import com.buckosoft.PicMan.domain.Mosaic;
19  
20  /** Manage mosaic building activities
21   * @author Dick Balaska
22   * @since 2007/12/01
23   * @version $Revision: 1.3 $ <br> $Date: 2014/06/21 04:35:32 $
24   * @see <a href="http://cvs.buckosoft.com/Projects/PicMan/PicMan/src/main/java/com/buckosoft/PicMan/business/mosaic/MosaicMan.java">MosaicMan.java</a>
25   */
26  public class MosaicMan {
27  	private static boolean DEBUG = false;
28  	private static boolean DEBUGEngine = false;
29  	protected final Log logger = LogFactory.getLog(getClass());
30  
31  	private	PicManFacade	pmf;
32  
33  	private	boolean	building = false;
34  	
35  	private	Mosaic			mosaicBuilding;
36  	private	MosaicEngine	mosaicEngine;
37  	
38  	private	MosaicManDevelopment	mosaicManDevelopment = new MosaicManDevelopment();
39  
40  	/** A List of Mosaics to be built.  The head entry is built and new ones are added to the tail. */
41  	private	LinkedList<Mosaic>	mosaicList = new LinkedList<Mosaic>();
42  	
43  	/** Set the reference to the PicMan API.
44  	 * @param pmf The PicManFacade
45  	 */
46  	public	void setPicMan(PicManFacade pmf) {
47  		this.pmf = pmf;
48  		mosaicManDevelopment.setPicMan(pmf);
49  	}
50  
51  	/** Enable logger output on this module
52  	 * @param debugFlag true == turn on debugging.
53  	 */
54  	public void setDEBUG(boolean debugFlag) {
55  		DEBUG = debugFlag;
56  	}
57  
58  	/** Enable logger output on any MosaicEngine spawned.
59  	 * @param debugFlag true == turn on debugging.
60  	 */
61  	public void setDEBUGEngine(boolean debugFlag) {
62  		DEBUGEngine = debugFlag;
63  	}
64  
65  	/** Fetch a reference to the MosaicManDevelopment
66  	 * @return the mosaicManDevelopment
67  	 */
68  	public MosaicManDevelopment getMosaicManDevelopment() {
69  		return mosaicManDevelopment;
70  	}
71  
72  	/** If Mosaic is running, return a reference to the running engine.
73  	 * @return the mosaicEngine
74  	 */
75  	public MosaicEngine getMosaicEngine() {
76  		return mosaicEngine;
77  	}
78  
79  	/** Manage synchronized access to the list.
80  	 * There are two operations, remove head (mosaic == null)
81  	 * and add tail (mosaic != null)
82  	 * @param mosaic
83  	 */
84  	private	synchronized void addToMosaicList(Mosaic mosaic) {
85  		if (mosaic == null) {
86  			if (mosaicList.size() > 0)
87  				mosaicList.removeFirst();
88  			return;
89  		}
90  		mosaicList.add(mosaic);
91  	}
92  
93  	/** Are we running the builder?
94  	 * @return the building
95  	 */
96  	public boolean isBuilding() {
97  		return(this.building);
98  	}
99  	
100 	/** Is there work to be done?  i.e. should we run the builder?
101 	 * @return true if there are Mosaics queued to be built
102 	 */
103 	public boolean hasWorkToDo() {
104 		return(this.mosaicList.size() != 0);
105 	}
106 
107 	/** Return a List of the names of Mosaic jobs queued to be run.
108 	 * @return The list of Mosaic Names
109 	 */
110 	public List<String> getMosaicQueueListString() {
111 		LinkedList<String> list = new LinkedList<String>();
112 		Iterator<Mosaic>	iter = mosaicList.iterator();
113 		while (iter.hasNext()) {
114 			Mosaic m = iter.next();
115 			list.add(m.getName());
116 		}
117 		return(list);
118 	}
119 	
120 	/** Queue this Mosaic for building.
121 	 * @param mosaic The Mosaic that the User wants built
122 	 */
123 	public void queueForBuilding(Mosaic mosaic) {
124 		this.addToMosaicList(mosaic);
125 		if (DEBUG)
126 			logger.info("Start building " + mosaic.getName());
127 	}
128 
129 	/** Remove any and all jobs from the Mosaic queue
130 	 * @return The number of jobs removed
131 	 */
132 	public int emptyMosaicQueue() {
133 		int i = this.mosaicList.size();
134 		this.mosaicList.clear();
135 		return(i);
136 	}
137 
138 	/** Build the first mosaic in the list. <br>
139 	 * Returns after the first mosaic is built.  BatchManager will come around again on it's next iteration
140 	 * if there is more work to do.
141 	 * @return true if there is more work to do on this mosaic.
142 	 * @throws Exception Something went wrong.
143 	 */
144 	public boolean runBuilder() throws Exception {
145 		boolean moreWork = false;
146 		this.mosaicBuilding = this.mosaicList.getFirst();
147 		if (this.mosaicBuilding == null)
148 			return(false);
149 		try {
150 			mosaicEngine = (MosaicEngine)Class.forName("com.buckosoft.PicMan.business.mosaic.engine."
151 							+ mosaicBuilding.getEngine()).newInstance();
152 		} catch (Exception e) {
153 			Exception ex = new Exception("Can't instantiate Mosaic Engine: " + mosaicEngine, e);
154 			pmf.addError(ex);
155 			return(false);
156 		}
157 		mosaicEngine.setPicMan(pmf);
158 		mosaicEngine.setDEBUG(DEBUGEngine);
159 		mosaicEngine.setMosaic(this.mosaicBuilding);
160 		pmf.setupMosaicThumbCache(this.mosaicBuilding.getSid(), this.mosaicBuilding.getTileHeight());
161 		this.building = true;
162 		try {
163 			moreWork = mosaicEngine.build();
164 		} catch (Exception e) {
165 			this.building = false;
166 			this.mosaicEngine = null;
167 			this.addToMosaicList(null);
168 			throw e;
169 		}
170 		this.building = moreWork;
171 		if (!moreWork) {
172 			this.mosaicEngine = null;
173 			this.addToMosaicList(null);
174 			this.pmf.releaseMosaicThumbCache();
175 		}
176 		return(moreWork);
177 	}
178 
179 	/** Write the (possibly partially completed) mosaic output jpeg
180 	 */ 
181 	public void outputMosaicFile() {
182 		if (this.mosaicEngine == null) {
183 			Exception e = new Exception("No mosaic to save");
184 			pmf.addError(e);
185 			return;
186 		}
187 		// don't make the backup if we are writing from a user click.
188 		this.mosaicEngine.outputMosaicFile(false);
189 	}
190 }