XmlQedeqFileDao.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.kernel.xml.dao;
017 
018 import java.io.File;
019 import java.io.FileOutputStream;
020 import java.io.IOException;
021 import java.io.OutputStream;
022 import java.io.Reader;
023 import java.util.Locale;
024 
025 import javax.xml.parsers.ParserConfigurationException;
026 
027 import org.qedeq.base.io.SourceArea;
028 import org.qedeq.base.io.TextOutput;
029 import org.qedeq.base.trace.Trace;
030 import org.qedeq.kernel.bo.common.QedeqBo;
031 import org.qedeq.kernel.bo.module.InternalKernelServices;
032 import org.qedeq.kernel.bo.module.KernelQedeqBo;
033 import org.qedeq.kernel.bo.module.QedeqFileDao;
034 import org.qedeq.kernel.se.base.module.Qedeq;
035 import org.qedeq.kernel.se.common.ModuleContext;
036 import org.qedeq.kernel.se.common.ModuleDataException;
037 import org.qedeq.kernel.se.common.Plugin;
038 import org.qedeq.kernel.se.common.SourceFileExceptionList;
039 import org.qedeq.kernel.xml.handler.common.SaxDefaultHandler;
040 import org.qedeq.kernel.xml.handler.module.QedeqHandler;
041 import org.qedeq.kernel.xml.mapper.Context2SimpleXPath;
042 import org.qedeq.kernel.xml.parser.SaxParser;
043 import org.qedeq.kernel.xml.tracker.SimpleXPath;
044 import org.qedeq.kernel.xml.tracker.XPathLocationParser;
045 import org.xml.sax.SAXException;
046 
047 import com.sun.syndication.io.XmlReader;
048 
049 
050 /**
051  * This class provides access methods for loading QEDEQ modules from XML files.
052  *
053  @author  Michael Meyling
054  */
055 public class XmlQedeqFileDao implements QedeqFileDao, Plugin {
056 
057     /** This class. */
058     private static final Class CLASS = XmlQedeqFileDao.class;
059 
060     /** Internal kernel services. */
061     private InternalKernelServices services;
062 
063     /**
064      * Constructor.
065      */
066     public XmlQedeqFileDao() {
067     }
068 
069     public void setServices(final InternalKernelServices services) {
070         this.services = services;
071     }
072 
073     public InternalKernelServices getServices() {
074         return this.services;
075     }
076 
077     public Qedeq loadQedeq(final QedeqBo prop, final File file)
078             throws SourceFileExceptionList {
079         final String method = "loadLocalModule";
080         SaxDefaultHandler handler = new SaxDefaultHandler(this);
081         QedeqHandler simple = new QedeqHandler(handler);
082         handler.setBasisDocumentHandler(simple);
083         SaxParser parser = null;
084         Locale.setDefault(Locale.US);   // TODO 20101228 m31: this is a Q & D Fix for the following problem:
085                                         // maybe there exists a better solution?
086 //org.qedeq.kernel.common.DefaultSourceFileExceptionList
087 //0: http://www.qedeq.org/0_04_00/sample/qedeq_error_sample_00.xml:1:1
088 //    9999: A programming error occurred.;
089 // For org.apache.xerces.impl.msg.XMLSchemaMessages_de_DE we searched for value of
090 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:164)
091 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:236)
092 //    at org.qedeq.kernel.xml.dao.XmlQedeqFileDao.loadQedeq(XmlQedeqFileDao.java:94)
093 //    at org.qedeq.kernel.bo.service.DefaultInternalKernelServices.loadBufferedModule(
094 //DefaultInternalKernelServices.java:315)
095 //    at org.qedeq.kernel.bo.service.DefaultInternalKernelServices.loadModule(DefaultInternalKernelServices.java:273)
096 //    at org.qedeq.kernel.bo.service.DefaultInternalKernelServices.checkModule(DefaultInternalKernelServices.java:908)
097 //    at org.qedeq.kernel.bo.context.KernelContext$3.checkModule(KernelContext.java:376)
098 //    at org.qedeq.kernel.bo.context.KernelContext.checkModule(KernelContext.java:628)
099 //    at org.qedeq.gui.se.control.CheckLogicAction$1.run(CheckLogicAction.java:66)
100 //Caused by: http://www.qedeq.org/0_04_00/sample/qedeq_error_sample_00.xml:1:1
101 //    9999: A programming error occurred.;
102 //For org.apache.xerces.impl.msg.XMLSchemaMessages_de_DE we searched for value of
103 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:188)
104 //    ... 8 more
105 //Caused by: org.qedeq.kernel.xml.common.XmlSyntaxException: A programming error occurred.
106 //    at org.qedeq.kernel.xml.common.XmlSyntaxException.createBySAXException(XmlSyntaxException.java:175)
107 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:187)
108 //    ... 8 more
109 //Caused by: java.util.MissingResourceException:
110 //Can't find bundle for base name org.apache.xerces.impl.msg.XMLSchemaMessages, locale de_DE
111 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:176)
112 //    ... 8 more
113 //Caused by: java.util.MissingResourceException:
114 //Can't find bundle for base name org.apache.xerces.impl.msg.XMLSchemaMessages, locale de_DE
115 //    at java.util.ResourceBundle.throwMissingResourceException(Unknown Source)
116 //    at java.util.ResourceBundle.getBundleImpl(Unknown Source)
117 //    at java.util.ResourceBundle.getBundle(Unknown Source)
118 //    at org.apache.xerces.impl.xs.XSMessageFormatter.formatMessage(Unknown Source)
119 //    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
120 //    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
121 //    at org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
122 //    at org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
123 //    at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
124 //    at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
125 //    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
126 //    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
127 //    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
128 //    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
129 //    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
130 //    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
131 //    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
132 //    at org.qedeq.kernel.xml.parser.SaxParser.parse(SaxParser.java:174)
133 //    ... 8 more
134 
135         try {
136             parser = new SaxParser(this, handler);
137         catch (SAXException e) {
138             Trace.fatal(CLASS, this, method, "XML Parser: Severe configuration problem.", e);
139             throw services.createSourceFileExceptionList(
140                 DaoErrors.PARSER_CONFIGURATION_ERROR_CODE,
141                 DaoErrors.PARSER_CONFIGURATION_ERROR_TEXT,
142                file + "", e);
143         catch (ParserConfigurationException e) {
144             Trace.fatal(CLASS, this, method, "XML Parser: Option not recognized or supported.", e);
145             throw services.createSourceFileExceptionList(
146                 DaoErrors.PARSER_CONFIGURATION_OPTION_ERROR_CODE,
147                 DaoErrors.PARSER_CONFIGURATION_OPTION_ERROR_TEXT,
148                 file + "", e);
149         }
150         try {
151             parser.parse(file, prop.getUrl());
152         catch (SourceFileExceptionList e) {
153             Trace.trace(CLASS, this, method, e);
154             throw e;
155         }
156         return simple.getQedeq();
157     }
158 
159     public void saveQedeq(final KernelQedeqBo prop, final File localFile)
160             throws SourceFileExceptionList, IOException {
161         final OutputStream outputStream = new FileOutputStream(localFile);
162         final TextOutput printer = new TextOutput(localFile.getName(), outputStream, "UTF-8");
163         Qedeq2Xml.print(this, prop, printer);
164     }
165 
166     public SourceArea createSourceArea(final Qedeq qedeq, final ModuleContext context) {
167         // copy constructor
168         final String method = "createSourceArea(Qedeq, ModuleContext)";
169         if (context == null) {
170             return null;
171         }
172         if (qedeq == null) {
173             return new SourceArea(context.getModuleLocation().getUrl());
174         }
175         ModuleContext ctext = new ModuleContext(context);
176         final SimpleXPath xpath;
177         try {
178             xpath = Context2SimpleXPath.getXPath(ctext, qedeq);
179         catch (ModuleDataException e) {
180             Trace.fatal(CLASS, method, "not found: \"" + ctext + "\"", e);
181             if (Boolean.TRUE.toString().equalsIgnoreCase(
182                     System.getProperty("qedeq.test.xmlLocationFailures"))) {
183                 throw new RuntimeException(e);
184             }
185             return new SourceArea(ctext.getModuleLocation().getUrl());
186         }
187 
188         final File local = services.getLocalFilePath(ctext.getModuleLocation());
189         return XPathLocationParser.findSourceArea(ctext.getModuleLocation().getUrl(), xpath,
190             ctext.getStartDelta(), ctext.getEndDelta(), local);
191     }
192 
193     public Reader getModuleReader(final KernelQedeqBo bo)
194             throws IOException {
195         return new XmlReader(services.getLocalFilePath(bo.getModuleAddress()));
196     }
197 
198     public String getPluginId() {
199         return CLASS.getName();
200     }
201 
202     public String getPluginActionName() {
203         return "XML Worker";
204     }
205 
206     public String getPluginDescription() {
207         return "can read and write XML QEDEQ modules";
208     }
209 
210 }