View Javadoc
1   /******************************************************************************
2    * SyncManager.java - Synchronize our database against a master
3    * 
4    * PicMan - The BuckoSoft Picture Manager in Java
5    * Copyright(c) 2008 - Dick Balaska
6    * 
7    */
8   package com.buckosoft.PicMan.business;
9   
10  import java.io.File;
11  import java.io.FileNotFoundException;
12  import java.io.FileOutputStream;
13  import java.io.IOException;
14  import java.rmi.RemoteException;
15  import java.util.Calendar;
16  import java.util.Iterator;
17  import java.util.List;
18  
19  import javax.xml.rpc.holders.BooleanHolder;
20  import javax.xml.rpc.holders.CalendarHolder;
21  import javax.xml.rpc.holders.IntHolder;
22  import javax.xml.rpc.holders.StringHolder;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  import com.buckosoft.PicMan.PicManService.PicManServiceProxy;
28  import com.buckosoft.PicMan.domain.Pic;
29  import com.buckosoft.PicMan.domain.Root;
30  import com.buckosoft.PicMan.domain.Set;
31  import com.buckosoft.PicMan.domain.SyncLogEntry;
32  import com.buckosoft.PicMan.domain.System;
33  import com.buckosoft.PicMan.util.SetsCRC;
34  
35  /** Synchronize our database against a master.
36   * @author Dick Balaska
37   * @since 2008/11/09
38   * @version $Revision: 1.1 $ <br> $Date: 2014/08/27 00:49:06 $
39   * @see <a href="http://cvs.buckosoft.com/Projects/java/PicMan/PicMan/src/com/buckosoft/PicMan/business/SyncManager.java">SyncManager.java</a>
40   */
41  public class SyncManager_Old {
42  	public final static int UNKNOWN	= 0;
43  	public final static int INIT	= 1;
44  	public final static int DOWN	= 2;
45  	public final static int ACTIVE	= 3;
46  	public final static int DONE	= 4;
47  	public final static int FAILED  = 5;
48  	
49  
50  	private static final boolean DEBUG = true;
51  	private static final boolean DEBUGSETS = false;
52  	private static final boolean DEBUGSOAP = false;
53  
54  	protected final Log logger = LogFactory.getLog(getClass());
55  
56  	private	int		syncState = UNKNOWN;
57  
58  	private	String	syncUrl;
59  //	private	String endpoint = "http://localhost:8081/PicManService/services/PicManServiceSOAP";	
60  	private	String serviceUri = "PicManService/services/PicManServiceSOAP";	
61  	private	PicManFacade pmf;
62  
63  	private PicManServiceProxy pmsp = null;
64  
65  	/** Initialize the sync manager
66  	 */
67  	public SyncManager_Old() {
68  		syncState = INIT;
69  	}
70  
71  	/** Set the reference to the PicMan API.
72  	 * @param pmf The PicManFacade
73  	 */
74  	public	void setPicMan(PicManFacade pmf) {
75  		this.pmf = pmf;
76  	}
77  
78  	/** Fetch the sync state 
79  	 * @return the syncState
80  	 */
81  	public int getSyncState() {
82  		return syncState;
83  	}
84  
85  	/** Fetch the sync state as a short text string
86  	 * @return the syncState as text
87  	 */
88  	public String getSyncStateAsText() {
89  		if (!pmf.getDB().getSystem().isSyncEnable())
90  			return("Off");
91  		switch (syncState) {
92  		case UNKNOWN:	return("??");
93  		case INIT:		return("Init");
94  		case DOWN:		return("Down");
95  		case ACTIVE:	return("Active");
96  		case DONE:		return("Done");
97  		case FAILED:	return("Failed");
98  		}
99  		return("???");
100 	}
101 
102 	/** Run one iteration of syncing.
103 	 */
104 	public void run() {
105 		SyncLogEntry sle;
106 		this.syncState = ACTIVE;
107 		String auth = "";	// TBD
108 		System sys = pmf.getDB().getSystem();
109 		if (!sys.isSyncEnable())
110 			return;
111 		syncUrl = sys.getSyncUrl();
112 		if (!syncUrl.endsWith("/"))
113 			syncUrl += "/";
114 		syncUrl += serviceUri;
115 		if (DEBUG)
116 			logger.info("Contacting: " + syncUrl);
117 		if (pmsp == null)
118 			pmsp = new PicManServiceProxy();
119 		pmsp.setEndpoint(syncUrl);
120 		String setsCrc = "";
121 		try {
122 			setsCrc = pmsp.getSetsCRC("");
123 		} catch (RemoteException e) {
124 			setDown(e, "getSetsCRC");
125 			if (DEBUGSOAP)
126 				e.printStackTrace();
127 			return;
128 		}
129 //		int localSetCount = pmf.getDB().getSetCRC();
130 		List<Set> sets = pmf.getDB().getSets();
131 		Iterator<Set> iter = sets.iterator();
132 		SetsCRC	crc = new SetsCRC();
133 		while (iter.hasNext()) {
134 			Set set = iter.next();
135 			crc.addSet(set);
136 		}
137 		if (DEBUG)
138 			logger.info("Remote Sets CRC = " + setsCrc + " local = " + crc.getCRC());
139 		if (!setsCrc.equals("" + crc.getCRC())) {
140 			synchronizeSets(auth);
141 		}
142 		Pic pic = pmf.getDB().getNewestPic();
143 		Calendar cal = Calendar.getInstance();
144 		cal.setTime(pic.getDate());
145 		String[] ss = null;
146 		try {
147 			ss = pmsp.getPicListNewerThan(auth, cal);
148 		} catch (RemoteException e) {
149 			setDown(e, "getPicListNewerThan");
150 			if (DEBUGSOAP)
151 				e.printStackTrace();
152 			return;
153 		}
154 		if (ss != null) {
155 			java.lang.String picName = ss[0];
156 			javax.xml.rpc.holders.IntHolder pid = new IntHolder();
157 			javax.xml.rpc.holders.StringHolder name = new StringHolder();
158 			javax.xml.rpc.holders.IntHolder rid = new IntHolder();
159 			javax.xml.rpc.holders.StringHolder location = new StringHolder();
160 			javax.xml.rpc.holders.CalendarHolder picDate = new CalendarHolder();
161 			javax.xml.rpc.holders.CalendarHolder timestamp = new CalendarHolder();
162 						
163 			for (int i=0; i<ss.length; i++) {
164 				if (DEBUG)
165 					logger.info("ss[" + i + "] = " + ss[i]);
166 				sle = new SyncLogEntry(SyncLogEntry.FETCHPIC, ss[i]);
167 				pmf.addSyncToLog(sle);
168 				// Fetch the pic's attributes
169 				picName = ss[i];
170 				try {
171 					pmsp.getPicAttributes(auth, ss[i], pid, name, rid, location, picDate, timestamp);
172 				} catch (RemoteException e) {
173 					setDown(e, "getPicAttributes");
174 					if (DEBUGSOAP)
175 						e.printStackTrace();
176 					return;
177 				}
178 				if (DEBUG) {
179 					logger.info("Fetching pic " + name.value + " rid:" + rid.value + " loc:" + location.value);
180 					logger.info("         picDate: '" + picDate.value.getTime().toString() + "' timeStamp: '" 
181 							+ timestamp.value.getTime().toString() + "'");
182 				}
183 				// Fetch the Pic's data
184 				byte[] b = null;
185 				try {
186 					b = pmsp.getPicPic(auth, name);
187 				} catch (RemoteException e) {
188 					setDown(e, "getPicPic");
189 					if (DEBUGSOAP)
190 						e.printStackTrace();
191 					return;
192 				}
193 				// Create the subdirectories to the file
194 				Root root = pmf.getDB().getRoot(rid.value);
195 				File toDir = new File(root.getPath() + "/" + location.value);
196 				if (!toDir.isDirectory()) {
197 					try {
198 						sle = new SyncLogEntry(SyncLogEntry.CREATEDIR, location.value);
199 						pmf.addSyncToLog(sle);
200 						toDir.mkdirs();
201 					} catch (Exception e) {
202 						e.printStackTrace();
203 						return;
204 					}
205 				}
206 				// Write the jpeg file.
207 				File toFile = new File(root.getPath() + "/" + location.value + "/" + picName + ".jpg");
208 				FileOutputStream fos = null;
209 				try {
210 					fos = new FileOutputStream(toFile);
211 				} catch (FileNotFoundException e) {
212 					setDown(e, "Open");
213 					if (DEBUGSOAP)
214 						e.printStackTrace();
215 					return;
216 				}
217 				try {
218 					fos.write(b);
219 				} catch (IOException e) {
220 					e.printStackTrace();
221 					try {
222 						fos.close();
223 					} catch (IOException e1) {
224 					}
225 					return;
226 				}
227 				try {
228 					fos.close();
229 				} catch (IOException e1) {
230 					e1.printStackTrace();
231 					return;
232 				}
233 				toFile.setLastModified(picDate.value.getTimeInMillis());
234 				toFile.setReadOnly();
235 				pic = new Pic();
236 				pic.setName(picName);
237 				pic.setLocation(location.value);
238 				pic.setRid(rid.value);
239 				pic.getDate().setTime(timestamp.value.getTime().getTime());
240 				pmf.getDB().addPic(pic);
241 				
242 				//break;	// DEBUG just one pic
243 			}	// end for each pic
244 		}
245 		this.syncState = DONE;
246 	}
247 
248 	private void setDown(RemoteException rex, String where) {
249 		syncState = DOWN;
250 		SyncLogEntry sle = new SyncLogEntry(SyncLogEntry.FAILED, where);
251 		sle.setColor(SyncLogEntry.COLOR_BAD);
252 		sle.setMessage(rex.getLocalizedMessage());
253 		pmf.addSyncToLog(sle);
254 		if (DEBUG)
255 			logger.info("rex:" + this.getSyncStateAsText() + " : " + rex.getLocalizedMessage());
256 	}
257 
258 	private void setDown(Exception rex, String where) {
259 		syncState = FAILED;
260 		SyncLogEntry sle = new SyncLogEntry(SyncLogEntry.FAILED, where);
261 		sle.setColor(SyncLogEntry.COLOR_BAD);
262 		sle.setMessage(rex.getLocalizedMessage());
263 		pmf.addSyncToLog(sle);
264 		if (DEBUG)
265 			logger.info("rex:" + this.getSyncStateAsText() + " : " + rex.getLocalizedMessage());
266 	}
267 
268 	private void synchronizeSets(String auth) {
269 		int i;
270 		if (DEBUG)
271 			logger.info("Sync Sets");
272 		SyncLogEntry sle = new SyncLogEntry(SyncLogEntry.INFO, "Sync Sets");
273 		sle.setColor(SyncLogEntry.COLOR_BAD);
274 		pmf.addSyncToLog(sle);
275 		List<Set> mySets = pmf.getDB().getSetsClone();
276 		int hisCount = -1;
277 		try {
278 			hisCount = pmsp.getSetCount(auth);
279 		} catch (RemoteException e) {
280 			setDown(e, "synchronizeSets");
281 			if (DEBUGSOAP)
282 				e.printStackTrace();
283 			return;
284 		}
285 		if (DEBUGSETS)
286 			logger.info("Checking his " + hisCount + " sets");
287 		IntHolder sid = new IntHolder();
288 		StringHolder name = new StringHolder();
289 		StringHolder description = new StringHolder();
290 		BooleanHolder active = new BooleanHolder();
291 		BooleanHolder metaSet = new BooleanHolder();
292 		BooleanHolder microSet = new BooleanHolder();
293 		BooleanHolder nanoSet = new BooleanHolder();
294 		CalendarHolder editDate = new CalendarHolder();
295 		Set set;
296 		Calendar cal = Calendar.getInstance();
297 		int pushCount = 0;
298 		int pullCount = 0;
299 		for (i=1; i<=hisCount; i++) {
300 			try {
301 				sid.value = i;
302 				if (i == 99)
303 					logger.info("99");
304 				pmsp.getSet(auth, sid, name, description, active, metaSet, microSet, nanoSet, editDate);
305 			} catch (RemoteException e) {
306 				setDown(e, "synchronizeSets");
307 				if (DEBUGSOAP)
308 					e.printStackTrace();
309 				return;
310 			}
311 			if (sid.value < 0) {
312 				setDown(new Exception("sid < 0"), "synchronizeSets");
313 				return;
314 			}
315 			set = new Set();
316 			set.setSid(sid.value);
317 			set.setName(name.value);
318 			set.setDescription(description.value);
319 			set.setActive(active.value);
320 			set.setMetaSet(metaSet.value);
321 			set.setMicroSet(microSet.value);
322 			set.setNanoSet(nanoSet.value);
323 			set.setEditDate(editDate.value.getTime());
324 			Iterator<Set> iter = mySets.iterator();
325 			boolean handled = false;
326 			while (iter.hasNext()) {
327 				Set mySet = iter.next();
328 				if (mySet.getSid() == set.getSid()) {
329 					if (mySet.compare(mySet, set) != 0) {
330 						if (DEBUGSETS)
331 							logger.info("mytime=" + mySet.getEditDate() + " histime=" + set.getEditDate());
332 						if (mySet.getEditDate().after(set.getEditDate())) {
333 							if (DEBUGSETS)
334 								logger.info("got set " + set.getSid() + " \"" + set.getName() + "\" = local newer");
335 							cal.setTime(mySet.getEditDate());
336 							try {
337 								pmsp.putSet(auth, mySet.getSid(), mySet.getName(), mySet.getDescription(),
338 										mySet.isActive(), mySet.isMetaSet(), mySet.isMicroSet(), mySet.isNanoSet(),
339 										cal);
340 							} catch (RemoteException e) {
341 								setDown(e, "putSet: " + set.getName());
342 								return;
343 							}
344 							pushCount++;
345 							iter.remove();
346 							handled = true;
347 							break;
348 						} else {	// older
349 							if (DEBUGSETS)
350 								logger.info("got set " + set.getSid() + " \"" + set.getName() + "\" = remote newer");
351 							pmf.getDB().storeSet(set);
352 							pullCount++;
353 							iter.remove();
354 							handled = true;
355 							break;
356 						}
357 					} else {
358 						if (DEBUGSETS)
359 							logger.info("got set " + set.getSid() + " \"" + set.getName() + "\" = same");
360 						iter.remove();
361 						handled = true;
362 						break;
363 					}
364 				}
365 			}
366 			if (!handled) {
367 				if (DEBUGSETS)
368 					logger.info("not found: " + set.getSid() + " \"" + set.getName() + "\"");
369 				pmf.getDB().storeSet(set);
370 				pullCount++;
371 			}
372 		}
373 		for (Set mySet : mySets) {
374 			if (DEBUGSETS)
375 				logger.info("put new set: " + mySet.getName());
376 			cal.setTime(mySet.getEditDate());
377 			pushCount++;
378 			try {
379 				pmsp.putSet(auth, mySet.getSid(), mySet.getName(), mySet.getDescription(),
380 						mySet.isActive(), mySet.isMetaSet(), mySet.isMicroSet(), mySet.isNanoSet(),
381 						cal);
382 			} catch (RemoteException e) {
383 				setDown(e, "putSet: " + mySet.getName());
384 				return;
385 			}
386 		}
387 		if (pushCount != 0 || pullCount != 0)
388 			sle.setMessage("push: " + pushCount + " pull: " + pullCount);
389 	}
390 
391 }