View Javadoc

1   /**
2    * The contents of this file are subject to the Mozilla Public License Version 1.1
3    * (the "License"); you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at http://www.mozilla.org/MPL/
5    * Software distributed under the License is distributed on an "AS IS" basis,
6    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
7    * specific language governing rights and limitations under the License.
8    *
9    * The Original Code is ""  Description:
10   * ""
11   *
12   * The Initial Developer of the Original Code is University Health Network. Copyright (C)
13   * 2001.  All Rights Reserved.
14   *
15   * Contributor(s): ______________________________________.
16   *
17   * Alternatively, the contents of this file may be used under the terms of the
18   * GNU General Public License (the  "GPL"), in which case the provisions of the GPL are
19   * applicable instead of those above.  If you wish to allow use of your version of this
20   * file only under the terms of the GPL and not to allow others to use your version
21   * of this file under the MPL, indicate your decision by deleting  the provisions above
22   * and replace  them with the notice and other provisions required by the GPL License.
23   * If you do not delete the provisions above, a recipient may use your version of
24   * this file under either the MPL or the GPL.
25   */
26  package ca.uhn.hl7v2.testpanel.controller;
27  
28  import static org.apache.commons.lang.StringUtils.*;
29  
30  import java.awt.Dimension;
31  import java.awt.Font;
32  import java.awt.Point;
33  import java.io.File;
34  import java.io.FileOutputStream;
35  import java.io.FileWriter;
36  import java.io.IOException;
37  import java.io.OutputStreamWriter;
38  import java.io.StringReader;
39  import java.io.StringWriter;
40  import java.io.Writer;
41  import java.nio.charset.Charset;
42  import java.util.ArrayList;
43  import java.util.Arrays;
44  import java.util.Collections;
45  import java.util.List;
46  import java.util.prefs.BackingStoreException;
47  import java.util.prefs.Preferences;
48  
49  import javax.xml.bind.JAXB;
50  import javax.xml.bind.JAXBContext;
51  import javax.xml.bind.JAXBException;
52  import javax.xml.bind.annotation.XmlAccessType;
53  import javax.xml.bind.annotation.XmlAccessorType;
54  import javax.xml.bind.annotation.XmlElement;
55  import javax.xml.bind.annotation.XmlRootElement;
56  
57  import org.apache.commons.lang.StringUtils;
58  import org.apache.commons.lang.Validate;
59  import org.slf4j.Logger;
60  import org.slf4j.LoggerFactory;
61  
62  import ca.uhn.hl7v2.hoh.util.IOUtils;
63  import ca.uhn.hl7v2.testpanel.model.conf.ExportedProfileGroupFile;
64  import ca.uhn.hl7v2.testpanel.model.conf.ProfileFileList;
65  import ca.uhn.hl7v2.testpanel.model.conf.ProfileGroup;
66  import ca.uhn.hl7v2.testpanel.model.conf.TableFileList;
67  import ca.uhn.hl7v2.testpanel.model.msg.Hl7V2MessageCollection;
68  import ca.uhn.hl7v2.testpanel.model.msg.Hl7V2MessageCollection.XmlFormat;
69  import ca.uhn.hl7v2.testpanel.util.CharsetUtils;
70  import ca.uhn.hl7v2.testpanel.util.FileNameComparator;
71  import ca.uhn.hl7v2.testpanel.util.FontUtil;
72  import ca.uhn.hl7v2.testpanel.util.LineEndingsEnum;
73  import ca.uhn.hl7v2.util.StringUtil;
74  
75  @XmlRootElement(name = "TestPanelPrefs", namespace = "urn:ca.uhn.hapi:testpanel:prefs")
76  @XmlAccessorType(XmlAccessType.FIELD)
77  public class Prefs {
78  
79  	private static final String GET_EXPORT_PROFILE_GROUP_DIRECTORY = "getExportProfileGroupDirectory";
80  	private static final String GET_HL7_EDITOR_SPLIT = "getHl7EditorSplit";
81  	private static final String GET_HL7V2_DIFF_FILE1 = "getHl7V2DiffFile1";
82  	private static final String GET_HL7V2_DIFF_FILE2 = "getHl7V2DiffFile2";
83  	private static final String GET_HL7V2_DIFF_SHOW_WHOLE_MESSAGE_ON_ERROR = "getHl7V2DiffShowWholeMessageOnError";
84  	private static final String GET_HL7V2_DIFF_STOP_ON_FIRST_ERROR = "getHl7V2DiffStopOnFirstError";
85  	private static final String GET_HL7V2_SORT_BY = "getHl7V2SortBy";
86  	private static final String GET_HL7V2_SORT_INPUT = "getHl7V2SortInputFile";
87  	private static final String GET_HL7V2_SORT_OUTPUT = "getHl7V2SortOutputFile";
88  	private static final String GET_HL7V2_SORT_OVERWRITE_MODE = "getHl7V2SortOverwriteMode";
89  	private static final String GET_INBOUND_CONNECTION_LIST = "getInboundConnectionList";
90  	private static final String GET_INTERFACE_HOH_SECURITY_KEYSTORE_DIRECTORY = "getInterfaceHohSecurityKeystoreDirectory";
91  	private static final String GET_MOST_RECENT_CONNECTION_CHARSET = "getMostRecentConnectionCharset";
92  	private static final String GET_MOST_RECENTLY_SELECTED_ITEM_ID = "getMostRecentlySelectedItemId";
93  	private static final String GET_OPEN_PATH_CONFORMANCE_PROFILE = "getOpenPathConformanceProfile";
94  	private static final String GET_OPEN_PATH_MESSAGES = "getOpenPathMessages";
95  	private static final String GET_OPEN_TABLE_FILES = "getOpenTableFiles";
96  	private static final String GET_OPENSAVE_CHARSET = "getOpenOrSaveCharset";
97  	private static final String GET_OUTBOUND_CONNECTION_LIST = "getOutboundConnectionList";
98  	private static final String GET_RECENT_MESSAGE_FILES = "getRecentMessageFiles";
99  	private static final String GET_SAVE_LINE_ENDINGS = "getSaveLineEndings";
100 	private static final String GET_SAVE_PATH_MESSAGES = "getSavePathMessages";
101 	private static final String GET_SAVE_STRIP_COMMENTS = "getSaveStripComments";
102 	private static final String GET_SHOW_LOG_CONSOLE = "getShowLogConsole";
103 	private static final String GET_WINDOW_MAXIMIZED = "getWindowMaximized";
104 	private static final String GET_WINDOW_POSITIONH = "getWindowPositionH";
105 	private static final String GET_WINDOW_POSITIONW = "getWindowPositionW";
106 	private static final String GET_WINDOW_POSITIONX = "getWindowPositionX";
107 	private static final String GET_WINDOW_POSITIONY = "getWindowPositionY";
108 
109 	private static Prefs ourInstance;
110 	private static JAXBContext ourJaxbContext;
111 	private static final Logger ourLog = LoggerFactory.getLogger(Prefs.class);
112 	private static final Preferences ourPrefs = Preferences.userNodeForPackage(ca.uhn.hl7v2.testpanel.controller.Prefs.class);
113 	private transient Controller myController;
114 
115 	@XmlElement(name = "export_profile_group_directory")
116 	private String myExportProfileGroupDirectory;
117 
118 	@XmlElement(name = "hl7v2_editor_split")
119 	private Integer myHl7EditorSplit;
120 
121 	@XmlElement(name = "hl7v2_diff_file1")
122 	private String myHl7V2DiffFile1;
123 
124 	@XmlElement(name = "hl7v2_diff_file2")
125 	private String myHl7V2DiffFile2;
126 
127 	@XmlElement(name = "hl7v2_show_whole_message_on_error")
128 	private boolean myHl7V2DiffShowWholeMessageOnError;
129 
130 	@XmlElement(name = "hl7v2_diff_stop_on_first_error")
131 	private boolean myHl7V2DiffStopOnFirstError;
132 
133 	@XmlElement(name = "hl7v2_sort_by")
134 	private String myHl7V2SortBy;
135 
136 	@XmlElement(name = "hl7v2_sort_input_file")
137 	private String myHl7V2SortInputFile;
138 
139 	@XmlElement(name = "hl7v2_output_file")
140 	private String myHl7V2SortOutputFile;
141 
142 	@XmlElement(name = "hl7v2_sort_override_mode")
143 	private String myHl7V2SortOverwriteMode;
144 
145 	@XmlElement(name = "import_profile_group_directory")
146 	private String myImportProfileGroupDirectory;
147 
148 	@XmlElement(name = "inbound_connection_list")
149 	private String myInboundConnectionList;
150 
151 	@XmlElement(name = "interface_hoh_security_keystore_directory")
152 	private String myInterfaceHohSecurityKeystoreDirectory;
153 
154 	private transient String myLastPrefsFileSaveValue;
155 
156 	@XmlElement(name = "most_recent_communication_charset")
157 	private String myMostRecentConnectionCharset;
158 
159 	@XmlElement(name = "most_recently_selected_item_id")
160 	private String myMostRecentlySelectedItemId;
161 
162 	// private List<OpenImportedProfileGroupFile>
163 	// myOpenImportedProfileGroupFile;
164 
165 	@XmlElement(name = "open_or_save_charset")
166 	private String myOpenOrSaveCharset;
167 
168 	@XmlElement(name = "open_path_conformance_profile")
169 	private String myOpenPathConformanceProfile;
170 
171 	@XmlElement(name = "open_path_messages")
172 	private String myOpenPathMessages;
173 
174 	@XmlElement(name = "open_table_files")
175 	private ArrayList<String> myOpenTableFiles;
176 
177 	@XmlElement(name = "outbound_connection_list")
178 	private String myOutboundConnectionList;
179 
180 	@XmlElement(name = "recent_message_xml_files")
181 	private List<XmlFormat> myRecentMessageXmlFiles;
182 
183 	@XmlElement(name = "save_line_endings")
184 	private String mySaveLineEndings;
185 
186 	@XmlElement(name = "save_path_messages")
187 	private String mySavePathMessages;
188 
189 	@XmlElement(name = "save_strip_comments")
190 	private boolean mySaveStripComments;
191 
192 	@XmlElement(name = "show_log_console")
193 	private boolean myShowLogConsole;
194 
195 	@XmlElement(name = "window_maximized")
196 	private boolean myWindowMaximized;
197 
198 	@XmlElement(name = "window_position_h")
199 	private int myWindowPositionH;
200 
201 	@XmlElement(name = "window_position_w")
202 	private int myWindowPositionW;
203 
204 	@XmlElement(name = "window_position_x")
205 	private Integer myWindowPositionX;
206 
207 	@XmlElement(name = "window_position_y")
208 	private Integer myWindowPositionY;
209 
210 	/**
211 	 * Non instantiable
212 	 */
213 	private Prefs() {
214 	}
215 
216 	public void addMessagesFileXmlToRecents(ProfileFileList theProfileFileList, List<Hl7V2MessageCollection> theMessageFiles) {
217 		List<Hl7V2MessageCollection> current = getRecentMessageXmlFiles(theProfileFileList);
218 		for (Hl7V2MessageCollection next : theMessageFiles) {
219 			if (StringUtils.isBlank(next.getSaveFileName())) {
220 				continue;
221 			}
222 			if (current.contains(next) == false) {
223 				current.add(0, next);
224 			}
225 		}
226 
227 		if (current.size() > 10) {
228 			current = current.subList(0, 10);
229 		}
230 
231 		myRecentMessageXmlFiles = new ArrayList<Hl7V2MessageCollection.XmlFormat>();
232 		for (Hl7V2MessageCollection string : current) {
233 			myRecentMessageXmlFiles.add(string.exportConfigToXmlWithoutContents());
234 		}
235 		sync();
236 	}
237 
238 	// public void addOpenImportedProfileGroupFile(OpenImportedProfileGroupFile
239 	// theFile) {
240 	// getOpenImportedProfileGroupFile().add(theFile);
241 	// sync();
242 	// }
243 
244 	public void clearRecentMessageXmlFiles() {
245 		myRecentMessageXmlFiles = new ArrayList<Hl7V2MessageCollection.XmlFormat>();
246 		sync();
247 	}
248 
249 	public String getExportProfileGroupDirectory() {
250 		return defaultString(myExportProfileGroupDirectory);
251 	}
252 
253 	public Font getHl7EditorFont() {
254 		Font retVal;
255 
256 		List<String> fonts = FontUtil.getMonospacedFontNames();
257 		if (fonts.contains("Monaco")) {
258 			retVal = new Font("Monaco", Font.PLAIN, 12);
259 		} else if (fonts.contains("Andale Mono")) {
260 			retVal = new Font("Andale Mono", Font.PLAIN, 12);
261 		} else if (fonts.contains("Lucida Console")) {
262 			retVal = new Font("Lucida Console", Font.PLAIN, 12);
263 		} else if (fonts.contains("Consolas")) {
264 			retVal = new Font("Consolas", Font.PLAIN, 12);
265 		} else if (fonts.contains("Lucida Sans Typewriter")) {
266 			retVal = new Font("Lucida Sans Typewriter", Font.PLAIN, 12);
267 		} else {
268 			retVal = new Font("Monospace", Font.PLAIN, 12);
269 		}
270 
271 		ourLog.info("Got font for HL7 editor: {}", retVal);
272 		return retVal;
273 	}
274 
275 	public double getHl7EditorSplit() {
276 		Double hl7EditorSplit = myHl7EditorSplit != null ? myHl7EditorSplit / 100.0 : 0.4;
277 		return enforceHl7EditorSplitLimits(hl7EditorSplit);
278 	}
279 
280 	public String getHl7V2DiffFile1() {
281 		return myHl7V2DiffFile1 == null ? "" : myHl7V2DiffFile1;
282 	}
283 
284 	public String getHl7V2DiffFile2() {
285 		return myHl7V2DiffFile2 == null ? "" : myHl7V2DiffFile2;
286 	}
287 
288 	public boolean getHl7V2DiffShowWholeMessageOnError() {
289 		return myHl7V2DiffShowWholeMessageOnError;
290 	}
291 
292 	public boolean getHl7V2DiffStopOnFirstError() {
293 		return myHl7V2DiffStopOnFirstError;
294 	}
295 
296 	public String getHl7V2SortBy() {
297 		return myHl7V2SortBy;
298 	}
299 
300 	public String getHl7V2SortInputFile() {
301 		return myHl7V2SortInputFile;
302 	}
303 
304 	public String getHl7V2SortOutputFile() {
305 		return myHl7V2SortOutputFile;
306 	}
307 
308 	public String getHl7V2SortOverwriteMode() {
309 		return myHl7V2SortOverwriteMode;
310 	}
311 
312 	public File getImportProfileGroupDirectory() {
313 		return new File(defaultString(myImportProfileGroupDirectory, "."));
314 	}
315 
316 	public String getInboundConnectionList() {
317 		return myInboundConnectionList;
318 	}
319 
320 	public String getInterfaceHohSecurityKeystoreDirectory() {
321 		return myInterfaceHohSecurityKeystoreDirectory;
322 	}
323 
324 	public Charset getMostRecentConnectionCharset() {
325 		String charset = isNotBlank(myMostRecentConnectionCharset) ? myMostRecentConnectionCharset : CharsetUtils.DEFAULT_CONNECTION_CHARSET.displayName();
326 		try {
327 			return Charset.forName(charset);
328 		} catch (Exception e) {
329 			return CharsetUtils.DEFAULT_CONNECTION_CHARSET;
330 		}
331 	}
332 
333 	public String getMostRecentlySelectedItemId() {
334 		return myMostRecentlySelectedItemId;
335 	}
336 
337 	// /**
338 	// * @return the openImportedProfileGroupFile
339 	// */
340 	// public List<OpenImportedProfileGroupFile>
341 	// getOpenImportedProfileGroupFile() {
342 	// if (myOpenImportedProfileGroupFile == null) {
343 	// myOpenImportedProfileGroupFile = new
344 	// ArrayList<Prefs.OpenImportedProfileGroupFile>();
345 	// }
346 	// return myOpenImportedProfileGroupFile;
347 	// }
348 
349 	public Charset getOpenOrSaveCharset() {
350 		String savedVal = defaultString(myOpenOrSaveCharset, Charset.defaultCharset().name());
351 
352 		Charset retVal;
353 		try {
354 			retVal = Charset.forName(savedVal);
355 		} catch (Exception e) {
356 			retVal = Charset.defaultCharset();
357 		}
358 		return retVal;
359 	}
360 
361 	public String getOpenPathConformanceProfile() {
362 		return defaultString(myOpenPathConformanceProfile, ".");
363 	}
364 
365 	public String getOpenPathMessages() {
366 		return defaultString(myOpenPathMessages, ".");
367 	}
368 
369 	public List<File> getOpenTableFiles() {
370 		ArrayList<File> retVal = new ArrayList<File>();
371 		if (myOpenTableFiles == null) {
372 			myOpenTableFiles = new ArrayList<String>();
373 		}
374 		for (String next : myOpenTableFiles) {
375 			retVal.add(new File(next));
376 		}
377 		return retVal;
378 
379 	}
380 
381 	public String getOutboundConnectionList() {
382 		return myOutboundConnectionList;
383 	}
384 
385 	public List<Hl7V2MessageCollection> getRecentMessageXmlFiles(ProfileFileList theProfileFileList) {
386 		List<Hl7V2MessageCollection> retVal = new ArrayList<Hl7V2MessageCollection>();
387 		List<XmlFormat> savedVals = myRecentMessageXmlFiles;
388 		for (XmlFormat string : savedVals) {
389 			try {
390 				Hl7V2MessageCollection nextMsg = Hl7V2MessageCollection.fromXml(theProfileFileList, string);
391 				assert nextMsg.getSourceMessage() == null;
392 				if (StringUtils.isNotBlank(nextMsg.getSaveFileName())) {
393 					retVal.add(nextMsg);
394 				}
395 			} catch (Exception e) {
396 				ourLog.error("Failed to restore profile", e);
397 			}
398 		}
399 		return retVal;
400 
401 	}
402 
403 	public LineEndingsEnum getSaveLineEndings() {
404 		String savedVal = defaultString(mySaveLineEndings, LineEndingsEnum.HL7.name());
405 		LineEndingsEnum retVal;
406 		try {
407 			retVal = LineEndingsEnum.valueOf(savedVal);
408 		} catch (Exception e) {
409 			retVal = LineEndingsEnum.HL7;
410 		}
411 		return retVal;
412 
413 	}
414 
415 	public String getSavePathMessages() {
416 		return defaultString(mySavePathMessages, ".");
417 	}
418 
419 	public boolean getSaveStripComments() {
420 		return mySaveStripComments;
421 	}
422 
423 	public boolean getShowLogConsole() {
424 		return myShowLogConsole;
425 	}
426 
427 	/**
428 	 * Returns (0,0) if nothing was stored
429 	 */
430 	public Dimension getWindowDimension() {
431 		int width = myWindowPositionW;
432 		int height = myWindowPositionH;
433 		return new Dimension(width, height);
434 	}
435 
436 	public boolean getWindowMaximized() {
437 		return myWindowMaximized;
438 	}
439 
440 	/**
441 	 * Returns (-1,-1) if nothing was stored
442 	 */
443 	public Point getWindowPosition() {
444 		int x = myWindowPositionX != null ? myWindowPositionX : -1;
445 		int y = myWindowPositionY != null ? myWindowPositionY : -1;
446 		return new Point(x, y);
447 	}
448 
449 	private void initFromJavaPrefs() {
450 		myOpenTableFiles = new ArrayList<String>();
451 		String savedValsSplit = ourPrefs.get(GET_OPEN_TABLE_FILES, "");
452 		String[] savedVals = defaultString(savedValsSplit).split("\\n");
453 		for (String string : savedVals) {
454 			if (StringUtils.isNotBlank(string)) {
455 				myOpenTableFiles.add(string);
456 			}
457 		}
458 
459 		myOutboundConnectionList = ourPrefs.get(GET_OUTBOUND_CONNECTION_LIST, null);
460 		myOpenPathConformanceProfile = ourPrefs.get(GET_OPEN_PATH_CONFORMANCE_PROFILE, ".");
461 		myOpenPathMessages = ourPrefs.get(GET_OPEN_PATH_MESSAGES, ".");
462 		myInterfaceHohSecurityKeystoreDirectory = ourPrefs.get(GET_INTERFACE_HOH_SECURITY_KEYSTORE_DIRECTORY, null);
463 		myMostRecentlySelectedItemId = ourPrefs.get(GET_MOST_RECENTLY_SELECTED_ITEM_ID, "");
464 		myOpenOrSaveCharset = ourPrefs.get(GET_OPENSAVE_CHARSET, Charset.defaultCharset().name());
465 		myHl7V2SortInputFile = ourPrefs.get(GET_HL7V2_SORT_INPUT, "");
466 		myHl7V2SortOverwriteMode = ourPrefs.get(GET_HL7V2_SORT_OVERWRITE_MODE, "");
467 		myInboundConnectionList = ourPrefs.get(GET_INBOUND_CONNECTION_LIST, null);
468 		myHl7V2SortOutputFile = ourPrefs.get(GET_HL7V2_SORT_OUTPUT, "");
469 		myHl7V2DiffStopOnFirstError = ourPrefs.getBoolean(GET_HL7V2_DIFF_STOP_ON_FIRST_ERROR, false);
470 		myExportProfileGroupDirectory = ourPrefs.get(GET_EXPORT_PROFILE_GROUP_DIRECTORY, "");
471 		myHl7V2DiffShowWholeMessageOnError = ourPrefs.getBoolean(GET_HL7V2_DIFF_SHOW_WHOLE_MESSAGE_ON_ERROR, false);
472 		myHl7V2SortBy = ourPrefs.get(GET_HL7V2_SORT_BY, "");
473 		myMostRecentConnectionCharset = ourPrefs.get(GET_MOST_RECENT_CONNECTION_CHARSET, CharsetUtils.DEFAULT_CONNECTION_CHARSET.displayName());
474 		myHl7EditorSplit = (int) (ourPrefs.getDouble(GET_HL7_EDITOR_SPLIT, 0.4) * 100.0);
475 		myHl7V2DiffFile1 = ourPrefs.get(GET_HL7V2_DIFF_FILE1, "");
476 		myHl7V2DiffFile2 = ourPrefs.get(GET_HL7V2_DIFF_FILE2, "");
477 		mySavePathMessages = ourPrefs.get(GET_SAVE_PATH_MESSAGES, ".");
478 
479 		String recentMessageXmlFiles = ourPrefs.get(GET_RECENT_MESSAGE_FILES, "");
480 		ArrayList<String> recentMessageXmlFilesSplit = new ArrayList<String>(Arrays.asList(defaultString(recentMessageXmlFiles).split("\\n")));
481 		myRecentMessageXmlFiles = new ArrayList<Hl7V2MessageCollection.XmlFormat>();
482 		for (String string : recentMessageXmlFilesSplit) {
483 			try {
484 				myRecentMessageXmlFiles.add(JAXB.unmarshal(new StringReader(string), Hl7V2MessageCollection.XmlFormat.class));
485 			} catch (Exception e) {
486 				ourLog.error("Failed to restore file \"" + string + "\": " + e.getMessage(), e);
487 			}
488 		}
489 
490 		mySaveLineEndings = ourPrefs.get(GET_SAVE_LINE_ENDINGS, LineEndingsEnum.HL7.name());
491 		mySaveStripComments = ourPrefs.getBoolean(GET_SAVE_STRIP_COMMENTS, false);
492 		myWindowMaximized = ourPrefs.getBoolean(GET_WINDOW_MAXIMIZED, false);
493 		myWindowPositionX = ourPrefs.getInt(GET_WINDOW_POSITIONX, -1);
494 		myWindowPositionY = ourPrefs.getInt(GET_WINDOW_POSITIONY, -1);
495 		myWindowPositionW = ourPrefs.getInt(GET_WINDOW_POSITIONW, 0);
496 		myWindowPositionH = ourPrefs.getInt(GET_WINDOW_POSITIONH, 0);
497 		myShowLogConsole = ourPrefs.getBoolean(GET_SHOW_LOG_CONSOLE, false);
498 
499 	}
500 
501 	// public void
502 	// removeOpenImportedProfileGroupFile(OpenImportedProfileGroupFile theFile)
503 	// {
504 	// getOpenImportedProfileGroupFile().remove(theFile);
505 	// sync();
506 	// }
507 
508 	/**
509 	 * @param theController
510 	 *            the controller to set
511 	 */
512 	public void setController(Controller theController) {
513 		myController = theController;
514 	}
515 
516 	public void setExportProfileGroupDirectory(String theDirectory) {
517 		myExportProfileGroupDirectory = theDirectory;
518 		sync();
519 	}
520 
521 	public void setHl7EditorSplit(double theRatio) {
522 		theRatio = enforceHl7EditorSplitLimits(theRatio);
523 		myHl7EditorSplit = (int) (theRatio * 100.0);
524 		sync();
525 	}
526 
527 	public void setHl7V2DiffFile1(String theFile) {
528 		myHl7V2DiffFile1 = theFile;
529 		sync();
530 
531 	}
532 
533 	public void setHl7V2DiffFile2(String theFile) {
534 		myHl7V2DiffFile2 = theFile;
535 		sync();
536 	}
537 
538 	public void setHl7V2DiffShowWholeMessageOnError(boolean theSelected) {
539 		myHl7V2DiffShowWholeMessageOnError = theSelected;
540 		sync();
541 	}
542 
543 	public void setHl7V2DiffStopOnFirstError(boolean theValue) {
544 		myHl7V2DiffStopOnFirstError = theValue;
545 		sync();
546 	}
547 
548 	public void setHl7V2SortBy(String theSelectedItem) {
549 		myHl7V2SortBy = theSelectedItem;
550 		sync();
551 	}
552 
553 	public void setHl7V2SortInputFile(String theText) {
554 		myHl7V2SortInputFile = theText;
555 		sync();
556 	}
557 
558 	public void setHl7V2SortOutputFile(String theText) {
559 		myHl7V2SortOutputFile = theText;
560 		sync();
561 	}
562 
563 	public void setHl7V2SortOverwriteMode(String theMode) {
564 		myHl7V2SortOverwriteMode = theMode;
565 		sync();
566 	}
567 
568 	/**
569 	 * @param theImportProfileGroupDirectory
570 	 *            the importProfileGroupDirectory to set
571 	 */
572 	public void setImportProfileGroupDirectory(File theImportProfileGroupDirectory) {
573 		if (theImportProfileGroupDirectory.isDirectory()) {
574 			myImportProfileGroupDirectory = theImportProfileGroupDirectory.getAbsolutePath();
575 			sync();
576 		}
577 
578 	}
579 
580 	public void setInboundConnectionList(String theValue) {
581 		Validate.notNull(theValue);
582 		myInboundConnectionList = theValue;
583 		sync();
584 	}
585 
586 	public void setInterfaceHohSecurityKeystoreDirectory(String theValue) {
587 		myInterfaceHohSecurityKeystoreDirectory = theValue;
588 		sync();
589 	}
590 
591 	public void setMostRecentConnectionCharset(String theCharSet) {
592 		assert theCharSet != null;
593 		myMostRecentConnectionCharset = theCharSet;
594 		sync();
595 	}
596 
597 	public void setMostRecentlySelectedItemId(String theId) {
598 		assert theId != null;
599 		myMostRecentlySelectedItemId = theId;
600 		sync();
601 	}
602 
603 	public void setOpenOrSaveCharset(Charset theValue) {
604 		Validate.notNull(theValue);
605 		myOpenOrSaveCharset = theValue.name();
606 		sync();
607 	}
608 
609 	public void setOpenPathConformanceProfile(String theValue) {
610 		StringUtil.validateNotEmpty(theValue);
611 
612 		if (theValue.lastIndexOf(File.separatorChar) > 0) {
613 			theValue = theValue.substring(0, theValue.lastIndexOf(File.separatorChar));
614 		}
615 
616 		myOpenPathConformanceProfile = theValue;
617 		sync();
618 	}
619 
620 	public void setOpenPathMessages(String theValue) {
621 		StringUtil.validateNotEmpty(theValue);
622 
623 		if (theValue.lastIndexOf(File.separatorChar) > 0) {
624 			theValue = theValue.substring(0, theValue.lastIndexOf(File.separatorChar));
625 		}
626 
627 		myOpenPathMessages = theValue;
628 		sync();
629 	}
630 
631 	public void setOpenProfiles(List<ProfileGroup> theProfiles, TableFileList theTableFileList) {
632 		int index = 0;
633 		List<File> files = new ArrayList<File>();
634 		try {
635 
636 			for (ProfileGroup profileGroup : theProfiles) {
637 				index++;
638 				String seq = StringUtils.leftPad(Integer.toString(index), 10, '0');
639 				File fileName = createProfileGroupFileName(seq, profileGroup);
640 				files.add(fileName);
641 
642 				FileOutputStream fos = new FileOutputStream(fileName);
643 				Writer nextWriter = new OutputStreamWriter(fos, Charset.forName("UTF-8"));
644 				if (isNotBlank(profileGroup.getSourceUrl())) {
645 					ExportedProfileGroupFile exported = new ExportedProfileGroupFile(profileGroup, theTableFileList);
646 					nextWriter.append(exported.exportConfigToXm());
647 				} else {
648 					nextWriter.append(profileGroup.exportConfigToXml());
649 				}
650 
651 				nextWriter.close();
652 			}
653 
654 			IOUtils.deleteAllFromDirectoryExcept(getProfileGroupFileDirectory(), files);
655 			
656 		} catch (IOException e) {
657 			ourLog.error("Failed to flush profile group file", e);
658 		}
659 	}
660 
661 	public void setOpenTableFiles(List<File> theFiles) {
662 		myOpenTableFiles = new ArrayList<String>();
663 		for (File file : theFiles) {
664 			myOpenTableFiles.add(file.getAbsolutePath());
665 		}
666 		sync();
667 	}
668 
669 	public void setOutboundConnectionList(String theValue) {
670 		Validate.notNull(theValue);
671 		myOutboundConnectionList = theValue;
672 		sync();
673 	}
674 
675 	public void setSaveLineEndings(LineEndingsEnum theValue) {
676 		Validate.notNull(theValue);
677 		mySaveLineEndings = theValue.name();
678 		sync();
679 	}
680 
681 	public void setSavePathMessages(String theValue) {
682 		StringUtil.validateNotEmpty(theValue);
683 
684 		if (theValue.lastIndexOf(File.separatorChar) > 0) {
685 			theValue = theValue.substring(0, theValue.lastIndexOf(File.separatorChar));
686 		}
687 
688 		mySavePathMessages = theValue;
689 		sync();
690 	}
691 
692 	public void setSaveStripComments(boolean theValue) {
693 		Validate.notNull(theValue);
694 		mySaveStripComments = theValue;
695 		sync();
696 	}
697 
698 	public void setShowLogConsole(boolean theValue) {
699 		Validate.notNull(theValue);
700 
701 		myShowLogConsole = theValue;
702 		sync();
703 	}
704 
705 	public void setWindowDimension(Dimension theDimension) {
706 		assert theDimension != null;
707 
708 		myWindowPositionH = theDimension.height;
709 		myWindowPositionY = theDimension.width;
710 		sync();
711 	}
712 
713 	public void setWindowMaximized(boolean theWindowMaximized) {
714 		myWindowMaximized = theWindowMaximized;
715 		sync();
716 	}
717 
718 	public void setWindowPosition(Point thePosition) {
719 		assert thePosition != null;
720 
721 		myWindowPositionX = thePosition.x;
722 		myWindowPositionY = thePosition.y;
723 		sync();
724 	}
725 
726 	private void sync() {
727 
728 		Runnable r = new Runnable() {
729 			@Override
730 			public void run() {
731 				StringWriter writer = new StringWriter();
732 				try {
733 					ourJaxbContext.createMarshaller().marshal(Prefs.this, writer);
734 				} catch (JAXBException e) {
735 					ourLog.error("Failed to marshall prefs! This shouldn't happen", e);
736 				}
737 
738 				final String prefs = writer.toString();
739 				if (StringUtils.equals(myLastPrefsFileSaveValue, prefs)) {
740 					return;
741 				}
742 
743 				ourLog.info("Syncing user preferences to disk");
744 
745 				try {
746 					FileWriter w = new FileWriter(getPrefsFile(), false);
747 					w.append(prefs);
748 					w.close();
749 
750 					ourLog.info("Done synchronizing user prefs ({} chars)", prefs.length());
751 					myLastPrefsFileSaveValue = prefs;
752 
753 					try {
754 						ourPrefs.clear();
755 					} catch (BackingStoreException e) {
756 						// we can ignore this
757 					}
758 
759 				} catch (IOException e) {
760 					ourLog.error("Failed to write prefs file to disk", e);
761 				}
762 
763 			}
764 		};
765 
766 		if (myController != null) {
767 			myController.invokeInBackground(r);
768 		}
769 
770 	}
771 
772 	private static File createProfileGroupFileName(String theSeq, ProfileGroup profileGroup) {
773 		File dir = getProfileGroupFileDirectory();
774 		dir.mkdirs();
775 		return new File(dir, theSeq + "-" + profileGroup.getId() + ".xml");
776 	}
777 
778 	private static double enforceHl7EditorSplitLimits(double theRatio) {
779 		theRatio = Math.min(0.8, theRatio);
780 		theRatio = Math.max(0.2, theRatio);
781 		return theRatio;
782 	}
783 
784 	public static File getDefaultTableFileDirectory() {
785 		File testPanelHome = getTestpanelHomeDirectory();
786 		File retVal = new File(testPanelHome, "tables");
787 		retVal.mkdirs();
788 		return retVal;
789 	}
790 
791 	public static Prefs getInstance() {
792 		try {
793 			ourJaxbContext = JAXBContext.newInstance(Prefs.class, XmlFormat.class);
794 		} catch (JAXBException e) {
795 			throw new Error(e);
796 		}
797 
798 		if (ourInstance == null) {
799 			File prefsFile = getPrefsFile();
800 			if (prefsFile.exists() && prefsFile.isFile() && prefsFile.canRead()) {
801 				try {
802 					ourInstance = (Prefs) ourJaxbContext.createUnmarshaller().unmarshal(prefsFile);
803 				} catch (Exception e) {
804 					ourLog.error("Failed to load prefs- Using default!", e);
805 					ourInstance = new Prefs();
806 				}
807 			} else {
808 				ourInstance = new Prefs();
809 				try {
810 					if (ourPrefs.keys().length > 0) {
811 						ourInstance.initFromJavaPrefs(); // hopefully we will do
812 															// away
813 															// with this
814 															// eventually
815 					}
816 				} catch (BackingStoreException e) {
817 					// we can ignore this
818 				}
819 			}
820 		}
821 		return ourInstance;
822 	}
823 
824 	public static List<ProfileGroup> getOpenProfiles() {
825 		ArrayList<ProfileGroup> retVal = new ArrayList<ProfileGroup>();
826 
827 		File dir = getProfileGroupFileDirectory();
828 		dir.mkdirs();
829 
830 		ArrayList<File> files = new ArrayList<File>(Arrays.asList(dir.listFiles()));
831 		Collections.sort(files, new FileNameComparator());
832 		
833 		for (File next : files) {
834 			if (next.getName().toLowerCase().contains(".xml")) {
835 				try {
836 					retVal.add(ProfileGroup.readFromFile(next));
837 				} catch (Exception e) {
838 					ourLog.error("Failed to unmarshall profile file", e);
839 				}
840 			}
841 		}
842 
843 		return retVal;
844 	}
845 
846 	private static File getPrefsFile() {
847 		return new File(getTestpanelHomeDirectory(), "prefs.xml");
848 	}
849 
850 	public static File getProfileGroupFileDirectory() {
851 		File testPanelHome = getTestpanelHomeDirectory();
852 		File retVal = new File(testPanelHome, "profilegroups");
853 		retVal.mkdirs();
854 		return retVal;
855 	}
856 
857 	public static File getTempWorkfilesDirectory() throws IOException {
858 		File testPanelHome = getTestpanelHomeDirectory();
859 		File retVal = new File(testPanelHome, "workfiles");
860 		retVal.mkdirs();
861 		return retVal;
862 	}
863 
864 	public static File getTestpanelHomeDirectory() {
865 		File userHome = new File(System.getProperty("user.home"));
866 		File testPanelHome = new File(userHome, "HapiTestPanel");
867 		return testPanelHome;
868 	}
869 
870 	// @XmlType()
871 	// @XmlAccessorType(XmlAccessType.FIELD)
872 	// public static class OpenImportedProfileGroupFile {
873 	//
874 	// private String myId;
875 	// private String myUrl;
876 	//
877 	// public OpenImportedProfileGroupFile() {
878 	// super();
879 	// }
880 	//
881 	// public OpenImportedProfileGroupFile(String theUrl, String theId) {
882 	// super();
883 	// myUrl = theUrl;
884 	// myId = theId;
885 	// }
886 	//
887 	// /*
888 	// * (non-Javadoc)
889 	// *
890 	// * @see java.lang.Object#equals(java.lang.Object)
891 	// */
892 	// @Override
893 	// public boolean equals(Object obj) {
894 	// if (this == obj) {
895 	// return true;
896 	// }
897 	// if (obj == null) {
898 	// return false;
899 	// }
900 	// if (!(obj instanceof OpenImportedProfileGroupFile)) {
901 	// return false;
902 	// }
903 	// OpenImportedProfileGroupFile other = (OpenImportedProfileGroupFile) obj;
904 	// if (myId == null) {
905 	// if (other.myId != null) {
906 	// return false;
907 	// }
908 	// } else if (!myId.equals(other.myId)) {
909 	// return false;
910 	// }
911 	// return true;
912 	// }
913 	//
914 	// /**
915 	// * @return the id
916 	// */
917 	// public String getId() {
918 	// return myId;
919 	// }
920 	//
921 	// /**
922 	// * @return the url
923 	// */
924 	// public String getUrl() {
925 	// return myUrl;
926 	// }
927 	//
928 	// /*
929 	// * (non-Javadoc)
930 	// *
931 	// * @see java.lang.Object#hashCode()
932 	// */
933 	// @Override
934 	// public int hashCode() {
935 	// final int prime = 31;
936 	// int result = 1;
937 	// result = prime * result + ((myId == null) ? 0 : myId.hashCode());
938 	// return result;
939 	// }
940 	//
941 	// /**
942 	// * @param theId
943 	// * the id to set
944 	// */
945 	// public void setId(String theId) {
946 	// myId = theId;
947 	// }
948 	//
949 	// /**
950 	// * @param theUrl
951 	// * the url to set
952 	// */
953 	// public void setUrl(String theUrl) {
954 	// myUrl = theUrl;
955 	// }
956 	//
957 	// }
958 
959 }