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