1 package org.xmlhammer;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.net.URI;
7 import java.text.DecimalFormat;
8 import java.text.NumberFormat;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 import javax.swing.JFrame;
13 import javax.swing.JSplitPane;
14 import javax.xml.XMLConstants;
15 import javax.xml.bind.JAXBContext;
16 import javax.xml.bind.JAXBException;
17 import javax.xml.bind.Marshaller;
18 import javax.xml.bind.util.JAXBResult;
19 import javax.xml.transform.Transformer;
20 import javax.xml.transform.TransformerFactory;
21 import javax.xml.transform.stream.StreamSource;
22
23 import org.apache.log4j.Logger;
24 import org.apache.xml.resolver.CatalogManager;
25 import org.xmlhammer.gui.XMLHammer;
26 import org.xmlhammer.model.jaxp.Attributes;
27 import org.xmlhammer.model.jaxp.Feature;
28 import org.xmlhammer.model.jaxp.Features;
29 import org.xmlhammer.model.jaxp.JAXPDocumentBuilderFactory;
30 import org.xmlhammer.model.jaxp.JAXPSAXParserFactory;
31 import org.xmlhammer.model.jaxp.JAXPSchemaFactory;
32 import org.xmlhammer.model.jaxp.JAXPTransformerFactory;
33 import org.xmlhammer.model.jaxp.JAXPXPathFactory;
34 import org.xmlhammer.model.jaxp.Mapping;
35 import org.xmlhammer.model.jaxp.Mappings;
36 import org.xmlhammer.model.jaxp.Properties;
37 import org.xmlhammer.model.jaxp.SchemaFactoryProperties;
38 import org.xmlhammer.model.jaxp.SchemaFactoryProperty;
39 import org.xmlhammer.model.jaxp.Settings;
40 import org.xmlhammer.model.preferences.CdataSectionElements;
41 import org.xmlhammer.model.preferences.Charsets;
42 import org.xmlhammer.model.preferences.Directories;
43 import org.xmlhammer.model.preferences.DoctypePublics;
44 import org.xmlhammer.model.preferences.DoctypeSystems;
45 import org.xmlhammer.model.preferences.Expressions;
46 import org.xmlhammer.model.preferences.Extensions;
47 import org.xmlhammer.model.preferences.ExternalApplication;
48 import org.xmlhammer.model.preferences.Frame;
49 import org.xmlhammer.model.preferences.Medias;
50 import org.xmlhammer.model.preferences.Menu;
51 import org.xmlhammer.model.preferences.Patterns;
52 import org.xmlhammer.model.preferences.Preferences;
53 import org.xmlhammer.model.preferences.Projects;
54 import org.xmlhammer.model.preferences.Proxy;
55 import org.xmlhammer.model.preferences.Results;
56 import org.xmlhammer.model.preferences.Schemas;
57 import org.xmlhammer.model.preferences.Searches;
58 import org.xmlhammer.model.preferences.Sources;
59 import org.xmlhammer.model.preferences.Split;
60 import org.xmlhammer.model.preferences.Stylesheets;
61 import org.xmlhammer.model.preferences.Titles;
62 import org.xmlhammer.model.preferences.Menu.Menuitem;
63 import org.xmlhammer.model.preferences.Preferences.Catalogs;
64 import org.xmlhammer.model.preferences.Preferences.Helpmenu;
65 import org.xmlhammer.model.preferences.Preferences.History;
66 import org.xmlhammer.model.preferences.Preferences.Catalogs.Catalog;
67
68 public class PreferencesHandler {
69 private static final String PREFERENCES_FILE = ".xmlhammer.xml";
70 private static final String PREFERENCES_DIR = System.getProperty("user.home")+File.separator+".xmlhammer"+File.separator;
71
72 private static PreferencesHandler handler = null;
73 private Preferences preferences = null;
74 private boolean useDefault = false;
75
76 private PreferencesHandler() {
77 super();
78 }
79
80 public static PreferencesHandler getInstance() {
81 if (handler == null) {
82 handler = new PreferencesHandler();
83 }
84
85 return handler;
86 }
87
88 public void useDefaultPreferences() {
89 useDefault = true;
90 preferences = null;
91 }
92
93 /***
94 * @return the preferences.
95 */
96 public Preferences getPreferences() {
97 if (preferences == null) {
98 File file = new File(PREFERENCES_DIR+PREFERENCES_FILE);
99
100 if (file.exists() && !useDefault) {
101 URI uri = file.toURI();
102
103 try {
104 JAXBContext context = JAXBContext.newInstance("org.xmlhammer.model.preferences");
105 JAXBResult result = new JAXBResult(context);
106
107
108 TransformerFactory factory = TransformerFactory.newInstance();
109 Transformer transformer = factory.newTransformer(new StreamSource(getClass().getResourceAsStream("/org/xmlhammer/convert/convert-from-2006-01-to-2007.xsl")));
110
111
112 transformer.transform(new StreamSource(uri.toString()), result);
113
114 preferences = (Preferences)result.getResult();
115 } catch (Exception e) {
116 File oldFile = getOldFile();
117 file.renameTo(oldFile);
118
119 Logger.getLogger(XMLHammer.class).error("JAXB Error", e);
120 Logger.getLogger(XMLHammer.class).error("Unable to load preferences. Created new preferences file, the old preferences file has been renamed to \""+oldFile.getName()+"\".");
121 }
122 }
123
124 if (preferences == null) {
125 preferences = new Preferences();
126 }
127 }
128
129 initPreferences(preferences);
130
131 return preferences;
132 }
133
134 public void updateCatalogProperties() {
135 Catalogs catalogs = getPreferences().getCatalogs();
136 List<Catalog> srcs = getPreferences().getCatalogs().getCatalog();
137 List<Catalog> temp = new ArrayList<Catalog>(srcs);
138 StringBuffer buffer = new StringBuffer();
139
140 for (Catalog catalog : temp) {
141 if (catalog.getSrc() != null) {
142 if (catalog.isActive()) {
143 buffer.append(catalog.getSrc());
144 buffer.append(";");
145 }
146 } else {
147 srcs.remove(catalog);
148 }
149 }
150
151 CatalogManager.getStaticManager().setIgnoreMissingProperties(true);
152 CatalogManager.getStaticManager().setUseStaticCatalog(false);
153 CatalogManager.getStaticManager().setPreferPublic(catalogs.isPreferPublicIdentifiers());
154 CatalogManager.getStaticManager().setCatalogFiles(buffer.toString());
155 }
156
157 public void updateProxy() {
158 Proxy proxy = getPreferences().getProxy();
159
160 if (proxy.isEnabled()) {
161 System.setProperty("http.proxyHost", proxy.getAddress());
162 System.setProperty("http.proxyPort", proxy.getPort());
163 } else {
164 System.getProperties().remove("http.proxyHost");
165 System.getProperties().remove("http.proxyPort");
166 }
167 }
168
169 public void storePreferences(JFrame frame, JSplitPane split, JSplitPane horizontalSplit) throws JAXBException, FileNotFoundException {
170 if (!useDefault) {
171 Preferences preferences = getPreferences();
172
173 preferences.getFrame().setHeight(frame.getSize().height);
174 preferences.getFrame().setWidth(frame.getSize().width);
175 preferences.getFrame().setXPos(frame.getLocation().x);
176 preferences.getFrame().setYPos(frame.getLocation().y);
177
178 preferences.getFrame().getSplit().setVertical( split.getDividerLocation());
179 preferences.getFrame().getSplit().setHorizontal( horizontalSplit.getDividerLocation());
180
181 JAXBContext context = JAXBContext.newInstance("org.xmlhammer.model.preferences");
182
183 Marshaller marshaller = context.createMarshaller();
184 marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
185
186 File dir = new File( PREFERENCES_DIR);
187
188 if ( !dir.exists()) {
189 dir.mkdir();
190 }
191
192 File file = new File( dir, PREFERENCES_FILE);
193
194 marshaller.marshal( preferences, new FileOutputStream( file));
195 }
196 }
197
198 private void initPreferences(Preferences preferences) {
199 if (preferences.getFrame() == null) {
200 preferences.setFrame( new Frame());
201 preferences.getFrame().setSplit( new Split());
202 }
203
204 if (preferences.getExternalApplication() == null) {
205 preferences.setExternalApplication(new ExternalApplication());
206 preferences.getExternalApplication().setBrowserExtensions("htm,html,xhtm,xhtml");
207
208 String os = System.getProperty("os.name").toLowerCase();
209
210 if (os.indexOf("windows") > -1) {
211 preferences.getExternalApplication().setEditorCommand("notepad.exe");
212
213 if ( (os.indexOf("nt") > -1) || (os.indexOf("2000") > -1 ) || (os.indexOf("xp") > -1) ) {
214 preferences.getExternalApplication().setDefaultCommand("cmd.exe /c");
215 } else {
216 preferences.getExternalApplication().setDefaultCommand("command.com /c");
217 }
218 }
219 }
220
221 if (preferences.getProxy() == null) {
222 preferences.setProxy(new Proxy());
223 }
224
225 Settings settings = preferences.getJAXPSettings();
226 if (settings == null) {
227 settings = new Settings();
228 preferences.setJAXPSettings(settings);
229 }
230
231 if (settings.getJAXPDocumentBuilderFactory() == null) {
232 JAXPDocumentBuilderFactory domFactory = new JAXPDocumentBuilderFactory();
233 domFactory.setSettings( new JAXPDocumentBuilderFactory.Settings());
234 domFactory.setFeatures( new Features());
235 domFactory.setAttributes( new Attributes());
236 settings.setJAXPDocumentBuilderFactory( domFactory);
237 }
238
239 if (settings.getJAXPSAXParserFactory() == null) {
240 JAXPSAXParserFactory saxFactory = new JAXPSAXParserFactory();
241 saxFactory.setSettings( new JAXPSAXParserFactory.Settings());
242
243 Features features = new Features();
244
245 features.getFeature().add( createFeature( "http://xml.org/sax/features/external-general-entities", true));
246 features.getFeature().add( createFeature( "http://xml.org/sax/features/external-parameter-entities", true));
247 features.getFeature().add( createFeature( "http://xml.org/sax/features/namespace-prefixes", false));
248 features.getFeature().add( createFeature( "http://xml.org/sax/features/string-interning", true));
249 features.getFeature().add( createFeature( "http://xml.org/sax/features/lexical-handler/parameter-entities", true));
250 features.getFeature().add( createFeature( "http://xml.org/sax/features/unicode-normalization-checking", false));
251 features.getFeature().add( createFeature( "http://xml.org/sax/features/allow-dtd-events-after-endDTD", false));
252 saxFactory.setFeatures( features);
253 saxFactory.setProperties( new Properties());
254 settings.setJAXPSAXParserFactory( saxFactory);
255 }
256
257 if (settings.getJAXPTransformerFactory() == null) {
258 JAXPTransformerFactory transformerFactory = new JAXPTransformerFactory();
259 transformerFactory.setSettings( new JAXPTransformerFactory.Settings());
260 transformerFactory.setFeatures( new Features());
261 transformerFactory.setAttributes( new Attributes());
262 settings.setJAXPTransformerFactory( transformerFactory);
263 }
264
265 if (settings.getJAXPXPathFactory() == null) {
266 JAXPXPathFactory xpathFactory = new JAXPXPathFactory();
267 xpathFactory.setSettings( new JAXPXPathFactory.Settings());
268 xpathFactory.setFeatures( new Features());
269
270 Mappings mappings = new Mappings();
271
272 addMapping(mappings, "fo", "http://www.w3.org/1999/XSL/Format");
273 addMapping(mappings, "html", "http://www.w3.org/1999/xhtml");
274 addMapping(mappings, "math", "http://www.w3.org/1998/Math/MathML");
275 addMapping(mappings, "nrl", "http://www.thaiopensource.com/validate/nrl");
276 addMapping(mappings, "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
277 addMapping(mappings, "rng", "http://relaxng.org/ns/structure/1.0");
278 addMapping(mappings, "soap-env", "http://schemas.xmlsoap.org/soap/envelope/");
279 addMapping(mappings, "soap-enc", "http://schemas.xmlsoap.org/soap/encoding/");
280 addMapping(mappings, "svg", "http://www.w3.org/2000/svg");
281 addMapping(mappings, "wsdl", "http://schemas.xmlsoap.org/wsdl/");
282 addMapping(mappings, "xinclude", "http://www.w3.org/2001/XInclude");
283 addMapping(mappings, "xlink", "http://www.w3.org/1999/xlink");
284 addMapping(mappings, "xsd", "http://www.w3.org/2001/XMLSchema");
285 addMapping(mappings, "xsi", "http://www.w3.org/1999/XMLSchema-instance");
286 addMapping(mappings, "xsl", "http://www.w3.org/1999/XSL/Transform");
287
288 xpathFactory.setMappings( mappings);
289 settings.setJAXPXPathFactory( xpathFactory);
290 }
291
292 if (settings.getJAXPSchemaFactory() == null) {
293 JAXPSchemaFactory schemaFactory = new JAXPSchemaFactory();
294 SchemaFactoryProperties schemaProperties = new SchemaFactoryProperties();
295
296 SchemaFactoryProperty property = new SchemaFactoryProperty();
297 property.setLanguage(XMLConstants.W3C_XML_SCHEMA_NS_URI);
298 schemaProperties.getSchemaFactoryProperty().add( property);
299 property = new SchemaFactoryProperty();
300 property.setLanguage(XMLConstants.RELAXNG_NS_URI);
301 schemaProperties.getSchemaFactoryProperty().add( property);
302
303 schemaFactory.setSchemaFactoryProperties( schemaProperties);
304 schemaFactory.setSettings( new JAXPSchemaFactory.Settings());
305 schemaFactory.setFeatures( new Features());
306 schemaFactory.setProperties( new Properties());
307 settings.setJAXPSchemaFactory( schemaFactory);
308 }
309
310 if (preferences.getCatalogs() == null) {
311 preferences.setCatalogs(new Preferences.Catalogs());
312 }
313
314 if (preferences.getClasspath() == null) {
315 preferences.setClasspath(new Preferences.Classpath());
316 }
317
318 if (preferences.getViews() == null) {
319 preferences.setViews(new Preferences.Views());
320 }
321
322 if (preferences.getSocket() == null) {
323 Preferences.Socket socket = new Preferences.Socket();
324 socket.setServer(true);
325 socket.setPort(10097);
326 preferences.setSocket(socket);
327 }
328
329 if (preferences.getHelpmenu() == null) {
330 Helpmenu helpMenu = new Helpmenu();
331
332 Menu menu = new Menu();
333 menu.setTitle("XML Hammer Online");
334 menu.getMenuitem().add(newMenu("Homepage", "http://www.xmlhammer.org/"));
335 menu.getMenuitem().add(newMenu("Report Bugs", "http://sourceforge.net/tracker/?group_id=145971&atid=763631"));
336 menu.getMenuitem().add(newMenu("Request Features", "http://sourceforge.net/tracker/?group_id=145971&atid=763634"));
337 menu.getMenuitem().add(newMenu("User Mailing List", "http://lists.sourceforge.net/mailman/listinfo/xmlhammer-user"));
338 menu.getMenuitem().add(newMenu("Developer Mailing List", "http://lists.sourceforge.net/mailman/listinfo/xmlhammer-development"));
339 menu.getMenuitem().add(newMenu("Source Code (CVS)", "http://sourceforge.net/cvs/?group_id=145971"));
340 helpMenu.getMenu().add(menu);
341
342 menu = new Menu();
343 menu.setTitle("JAXP Resources");
344 menu.getMenuitem().add(newMenu("JAXP Implementations", "http://www.edankert.com/jaxpimplementations.html"));
345 menu.getMenuitem().add(newMenu("JAXP 1.3", "http://java.sun.com/webservices/jaxp/"));
346 helpMenu.getMenu().add(menu);
347
348 menu = new Menu();
349 menu.setTitle("XML Specifications");
350 menu.getMenuitem().add(newMenu("XML 1.0", "http://www.w3.org/TR/REC-xml/"));
351 menu.getMenuitem().add(newMenu("XPath 1.0", "http://www.w3.org/TR/xpath"));
352 menu.getMenuitem().add(newMenu("XSLT 1.0", "http://www.w3.org/TR/xslt"));
353 menu.getMenuitem().add(newMenu("XInclude 1.0", "http://www.w3.org/TR/xinclude/"));
354 menu.getMenuitem().add(newMenu("Namespaces in XML", "http://www.w3.org/TR/REC-xml-names/"));
355 menu.getMenuitem().add(newMenu("XML Schema Primer", "http://www.w3.org/TR/xmlschema-0/"));
356 menu.getMenuitem().add(newMenu("XML Schema Structures", "http://www.w3.org/TR/xmlschema-1/"));
357 menu.getMenuitem().add(newMenu("XML Schema Datatypes", "http://www.w3.org/TR/xmlschema-2/"));
358 helpMenu.getMenu().add(menu);
359
360 preferences.setHelpmenu(helpMenu);
361 }
362
363 History history = preferences.getHistory();
364
365 if (history == null) {
366 history = new History();
367 preferences.setHistory(history);
368 }
369
370 if (history.getProjects() == null) {
371 Projects projects = new Projects();
372 projects.setSize(10);
373 history.setProjects(projects);
374 }
375
376 if (history.getSources() == null) {
377 Sources sources = new Sources();
378 sources.setSize(25);
379 history.setSources(sources);
380 }
381
382 if (history.getResults() == null) {
383 Results results = new Results();
384 results.setSize(25);
385 history.setResults(results);
386 }
387
388 if (history.getSchemas() == null) {
389 Schemas schemas = new Schemas();
390 schemas.setSize(25);
391 history.setSchemas(schemas);
392 }
393
394 if (history.getExpressions() == null) {
395 Expressions expressions = new Expressions();
396 expressions.setSize(25);
397 history.setExpressions(expressions);
398 }
399
400 if (history.getPatterns() == null) {
401 Patterns patterns = new Patterns();
402 patterns.setSize(25);
403 history.setPatterns(patterns);
404 }
405
406 if (history.getDirectories() == null) {
407 Directories directories = new Directories();
408 directories.setSize(25);
409 history.setDirectories(directories);
410 }
411
412 if (history.getExtensions() == null) {
413 Extensions extensions = new Extensions();
414 extensions.setSize(25);
415 history.setExtensions(extensions);
416 }
417
418 if (history.getStylesheets() == null) {
419 Stylesheets stylesheets = new Stylesheets();
420 stylesheets.setSize(25);
421 history.setStylesheets(stylesheets);
422 }
423
424 if (history.getDoctypePublics() == null) {
425 DoctypePublics publics = new DoctypePublics();
426 publics.setSize(25);
427 history.setDoctypePublics(publics);
428 }
429
430 if (history.getDoctypeSystems() == null) {
431 DoctypeSystems systems = new DoctypeSystems();
432 systems.setSize(25);
433 history.setDoctypeSystems(systems);
434 }
435
436 if (history.getSearches() == null) {
437 Searches searches = new Searches();
438 searches.setSize(25);
439 history.setSearches(searches);
440 }
441
442 if (history.getCdataSectionElements() == null) {
443 CdataSectionElements elements = new CdataSectionElements();
444 elements.setSize(25);
445 history.setCdataSectionElements(elements);
446 }
447
448 if (history.getMedias() == null) {
449 Medias medias = new Medias();
450 medias.setSize(25);
451 history.setMedias(medias);
452 }
453
454 if (history.getTitles() == null) {
455 Titles titles = new Titles();
456 titles.setSize(25);
457 history.setTitles(titles);
458 }
459
460 if (history.getCharsets() == null) {
461 Charsets charsets = new Charsets();
462 charsets.setSize(25);
463 history.setCharsets(charsets);
464 }
465 }
466
467 private static void addMapping(Mappings mappings, String prefix, String uri) {
468 Mapping mapping = new Mapping();
469 mapping.setPrefix(prefix);
470 mapping.setUri(uri);
471 mappings.getMapping().add(mapping);
472 }
473
474 private static Feature createFeature( String name, boolean value) {
475 Feature feature = new Feature();
476 feature.setName( name);
477 feature.setEnabled( value);
478
479 return feature;
480 }
481
482 private static Menuitem newMenu(String title, String src) {
483 Menuitem item = new Menuitem();
484 item.setSrc(src);
485 item.setTitle(title);
486
487 return item;
488 }
489
490 private static File getOldFile() {
491 NumberFormat format = DecimalFormat.getNumberInstance();
492 format.setMinimumIntegerDigits(3);
493
494 int i = 1;
495 while (true) {
496 System.out.println(format.format(i));
497 File file = new File(PREFERENCES_DIR+"xmlhammer."+format.format(i));
498
499 if (!file.exists()) {
500 return file;
501 }
502
503 i++;
504 }
505 }
506 }