View Javadoc

1   /* ======================================
2    * Copyright (c) 2004-2005 Achim Nierbeck
3    * All rights reserved.
4    *
5    * You may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *       http://www.gnu.org/licenses/lgpl.html
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   * ======================================
16   */
17  
18  /*
19   * $Revision: 1.4 $
20   * Date 14.12.2005
21   * 
22   * $Author: nierbeck $ 
23   * $Date: 2006/02/03 22:33:35 $  
24   */
25  
26  package de.nierbeck.timeTrack;
27  
28  import java.io.File;
29  import java.io.FileNotFoundException;
30  import java.io.FileOutputStream;
31  import java.io.IOException;
32  import java.util.Calendar;
33  import java.util.GregorianCalendar;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Observable;
37  
38  import javax.xml.bind.JAXBContext;
39  import javax.xml.bind.JAXBException;
40  import javax.xml.bind.Marshaller;
41  import javax.xml.bind.Unmarshaller;
42  import javax.xml.bind.ValidationException;
43  import javax.xml.bind.Validator;
44  
45  import org.eclipse.jface.preference.IPreferenceStore;
46  
47  import de.nierbeck.timeTrack.model.Entries;
48  import de.nierbeck.timeTrack.model.EntryType;
49  import de.nierbeck.timeTrack.model.ObjectFactory;
50  import de.nierbeck.timeTrack.preferences.PreferenceConstants;
51  
52  /***
53   * Class TimeTrackEntriesManager is a wrapper class for the entries, since the
54   * entries are generated class.
55   * 
56   * @author Achim
57   * @see java.util.Observable
58   * @see Entries
59   */
60  public class TimeTrackEntriesManager extends Observable implements Entries {
61  
62  	// singleton instance
63  	private static TimeTrackEntriesManager instance;
64  
65  	private transient Entries entries;
66  
67  	private transient JAXBContext jaxbCtxt;
68  
69  	private transient File file;
70  
71  	private transient final ObjectFactory objFactory = new ObjectFactory();
72  
73  	/***
74  	 * 
75  	 * @return the instance
76  	 * @deprecated
77  	 */
78  	public static TimeTrackEntriesManager getTimeTrackEntriesManager() {
79  		if (instance == null) {
80  			instance = new TimeTrackEntriesManager();
81  		}
82  		return instance;
83  	}
84  
85  	/***
86  	 * Constructor of the TimeTrackEntriesManager Class.
87  	 * 
88  	 */
89  	TimeTrackEntriesManager() {
90  		ClassLoader newloader = JAXBContext.class.getClassLoader();
91  		ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
92  		Thread.currentThread().setContextClassLoader(newloader);
93  
94  		try {
95  			jaxbCtxt = JAXBContext.newInstance("de.nierbeck.timeTrack.model"); //$NON-NLS-1$
96  			TimeTrackLog.logInfo("loading JAXBContext done");
97  		} catch (JAXBException e) {
98  			TimeTrackLog.logError("failed to create JAXBContext", e);
99  		} finally {
100 			Thread.currentThread().setContextClassLoader(oldLoader);
101 		}
102 	}
103 
104 	/***
105 	 * delegates the call to the nested class
106 	 * 
107 	 * @see Entries
108 	 * 
109 	 * @return the selected EntryType
110 	 */
111 	public final EntryType getCurrentSelected() {
112 		if (entries == null) {
113 			createEntries();
114 		}
115 		return entries.getCurrentSelected();
116 	}
117 
118 	/***
119 	 * delegates the call to the nested class and notifies the Observers
120 	 * 
121 	 * @see Entries
122 	 * @param value - the current Selected
123 	 */
124 	public final void setCurrentSelected(EntryType value) {
125 		if (entries == null) {
126 			createEntries();
127 		}
128 		entries.setCurrentSelected(value);
129 		setChanged();
130 		notifyObservers();
131 	}
132 
133 	/***
134 	 * delegates the call to the nested class
135 	 * 
136 	 * @see Entries
137 	 * 
138 	 * @return a list containing the entries
139 	 */
140 	public final List getEntry() {
141 		if (entries == null) {
142 			createEntries();
143 		}
144 		return entries.getEntry();
145 	}
146 
147 	/***
148 	 * delegates the call to the nested class
149 	 * 
150 	 * @see Entries
151 	 */
152 	public final void setChanged() {
153 		super.setChanged();
154 	}
155 
156 	private void createEntries() {
157 		try {
158 			setXMLFile();
159 		} catch (JAXBException e) {
160 			TimeTrackLog.logError(this + "createPartControl()", e);
161 			if (entries == null) {
162 				try {
163 					createNewEntries();
164 				} catch (JAXBException e1) {
165 					TimeTrackLog.logError(this + "createPartControl()", e);
166 				}
167 			}
168 		} catch (IOException e) {
169 			TimeTrackLog.logError(this + "createPartControl()", e);
170 		}
171 	}
172 
173 	/***
174 	 * @throws JAXBException
175 	 */
176 	private void createNewEntries() throws JAXBException {
177 		entries = objFactory.createEntries();
178 		createNewCurrentSelected();
179 		// projects = new String[1];
180 		// projects[0] = ""; //$NON-NLS-1$
181 		// tasks = new String[1];
182 		// tasks[0] = ""; //$NON-NLS-1$
183 		// comments = new String[1];
184 		// comments[0] = ""; //$NON-NLS-1$
185 	}
186 
187 	private void setXMLFile() throws JAXBException, IOException {
188 
189 		IPreferenceStore store = TimeTrackPlugin.getDefault().getPreferenceStore();
190 
191 		String xmlFile = store.getString(PreferenceConstants.P_FILE);
192 		if ("".equals(xmlFile)) { //$NON-NLS-1$
193 			xmlFile = PreferenceConstants.P_FILE_DEFAULT;
194 		}
195 		String directory = store.getString(PreferenceConstants.P_PATH);
196 		if ("${workspace_loc}".equals(directory)) { //$NON-NLS-1$
197 			directory = ""; //$NON-NLS-1$
198 		}
199 
200 		StringBuffer xFile = new StringBuffer();
201 
202 		if (directory != null && directory.length() > 0) {
203 			xFile.append(directory); //$NON-NLS-1$
204 			xFile.append("/");
205 		}
206 		if (xmlFile != null && xmlFile.length() > 0) {
207 			xFile.append(xmlFile);
208 
209 			file = new File(xFile.toString());
210 			boolean exists = file.exists();
211 
212 			if (exists) {
213 				unmarshall(file);
214 			} else {
215 				createNewEntries();
216 			}
217 		}
218 	}
219 
220 	/***
221 	 * @param xFile
222 	 * @throws JAXBException
223 	 * @throws JAXBException
224 	 */
225 	private void unmarshall(File file) throws JAXBException {
226 		if (jaxbCtxt == null) {
227 			jaxbCtxt = JAXBContext.newInstance("de.nierbeck.timeTrack.model"); //$NON-NLS-1$
228 		}
229 		Unmarshaller unmarshaller = jaxbCtxt.createUnmarshaller();
230 		Entries entries = null;
231 		entries = (Entries) unmarshaller.unmarshal(file);
232 		if (entries == null) {
233 			entries = objFactory.createEntries();
234 		} else {
235 			this.entries = entries;
236 		}
237 
238 		if (entries.getCurrentSelected() != null) {
239 			entries.getEntry().add(entries.getCurrentSelected());
240 			createNewCurrentSelected();
241 		}
242 
243 		/*
244 		 * Iterator iterator = entries.getEntry().iterator();
245 		 * 
246 		 * ArrayList project = new ArrayList(); String stringProject =
247 		 * entries.getCurrentSelected().getProject(); if (stringProject != null &&
248 		 * stringProject.length() > 0) project.add(stringProject); ArrayList
249 		 * task = new ArrayList(); String stringTask =
250 		 * entries.getCurrentSelected().getTask(); if (stringTask != null &&
251 		 * stringTask.length() > 0) task.add(stringTask); ArrayList comment =
252 		 * new ArrayList(); String stringComment =
253 		 * entries.getCurrentSelected().getComment(); if (stringComment != null &&
254 		 * stringComment.length() > 0) comment.add(stringComment);
255 		 * 
256 		 * while (iterator.hasNext()) { EntryType entry = (EntryType)
257 		 * iterator.next(); stringProject = entry.getProject(); if
258 		 * (stringProject != null && stringProject.length() > 0 &&
259 		 * !project.contains(stringProject)) project.add(stringProject);
260 		 * stringTask = entry.getTask(); if (stringTask != null &&
261 		 * stringTask.length() > 0 && !task.contains(stringTask))
262 		 * task.add(stringTask); stringComment = entry.getComment(); if
263 		 * (stringComment != null && stringComment.length() > 0 &&
264 		 * !comment.contains(stringComment)) comment.add(stringComment); } //
265 		 * try { // projects = new String[project.size()]; //
266 		 * fillArray(projects, project); // tasks = new String[task.size()]; //
267 		 * fillArray(tasks, task); // comments = new String[comment.size()]; //
268 		 * fillArray(comments, comment); // } catch (Exception e) { //
269 		 * TimeTrackLog.logError("failed to create JAXBContext", e); // }
270 		 */
271 	}
272 
273 	private void marshall() throws JAXBException, FileNotFoundException {
274 		final Marshaller marshaller = jaxbCtxt.createMarshaller();
275 		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
276 		final Validator validator = jaxbCtxt.createValidator();
277 
278 		boolean valid = false;
279 		try {
280 			valid = validator.validate(entries);
281 		} catch (ValidationException e) {
282 			TimeTrackLog.logError("XML not Valid", e);
283 			return;
284 		} 
285 		if (!valid) {
286 			TimeTrackLog.logError("XML not Valid", new ValidationException("Entries weren't validatet correctly"));
287 			return; //can't save since the structure isn't valid
288 		}
289 		/*
290 		if (!valid) {
291 			throw new ValidationException("Entries weren't validatet correctly"); //$NON-NLS-1$
292 		}*/
293 
294 		marshaller.marshal(entries, new FileOutputStream(file));
295 	}
296 
297 	/***
298 	 * @throws JAXBException
299 	 */
300 	private void createNewCurrentSelected() throws JAXBException {
301 		EntryType entryType = objFactory.createEntryType();
302 		Calendar calendar = GregorianCalendar.getInstance();
303 		entryType.setStartTime(calendar);
304 		entryType.setComment(""); //$NON-NLS-1$
305 		entryType.setDuration(0);
306 		entryType.setProject(""); //$NON-NLS-1$
307 		entryType.setTask(""); //$NON-NLS-1$
308 		entries.setCurrentSelected(entryType);
309 	}
310 
311 	/***
312 	 * 
313 	 *
314 	 */
315 	public final void restoreState() {
316 		createEntries();
317 	}
318 
319 	/***
320 	 * 
321 	 *
322 	 */
323 	public final void saveState() {
324 		try {
325 			marshall();
326 		} catch (FileNotFoundException e) {
327 			TimeTrackLog.logError("File Not found while Storing", e);
328 		} catch (JAXBException e) {
329 			TimeTrackLog.logError("JAXB Exception while storing", e);
330 		}
331 	}
332 
333 	/***
334 	 * 
335 	 * @return a iterator over the entries
336 	 */
337 	public final Iterator getEntryIterator() {
338 		return entries.getEntry().iterator();
339 	}
340 
341 	/***
342 	 * 
343 	 *
344 	 */
345 	public final void reloadState() {
346 		// first we store the old state!
347 		saveState();
348 		// now we try to build a new state
349 		restoreState();
350 		setChanged();
351 		notifyObservers();
352 	}
353 }