2 * Created on Oct 31, 2003
4 package isac.util.parser;
6 import isac.util.CalcChanged;
7 import isac.util.Message;
8 import isac.util.ResponseWrapper;
9 import isac.util.formulae.Assumptions;
10 import isac.util.formulae.CalcHead;
11 import isac.util.formulae.KEStoreID;
12 import isac.util.formulae.Model;
13 import isac.util.formulae.ModelItem;
14 import isac.util.formulae.ModelItemList;
15 import isac.util.formulae.CalcHeadSimpleID;
16 import isac.util.formulae.FormHeadsContainer;
17 import isac.util.formulae.Formula;
18 import isac.util.formulae.CalcFormula;
19 import isac.util.formulae.Position;
20 import isac.util.formulae.Specification;
21 import isac.util.tactics.Rewrite;
22 import isac.util.tactics.RewriteInst;
23 import isac.util.tactics.RewriteSet;
24 import isac.util.tactics.RewriteSetInst;
25 import isac.util.tactics.SimpleTactic;
26 import isac.util.tactics.StringListTactic;
27 import isac.util.tactics.SubProblemTactic;
28 import isac.util.tactics.TacticsContainer;
29 import isac.util.tactics.Theorem;
31 import java.io.BufferedReader;
32 import java.io.FileNotFoundException;
33 import java.io.FileReader;
34 import java.io.IOException;
35 import java.io.StringReader;
37 import org.apache.commons.digester.Digester;
38 import org.apache.log4j.Logger;
39 import org.xml.sax.EntityResolver;
40 import org.xml.sax.ErrorHandler;
41 import org.xml.sax.InputSource;
42 import org.xml.sax.SAXException;
43 import org.xml.sax.SAXParseException;
46 * parses Objects from XML-Output of the Kernel.
48 * @author Richard Gradischnegg
50 public class XMLParserDigest {
52 private Digester digester_;
54 private String dtd_path_;
56 class BridgeErrorHandler implements ErrorHandler {
58 public void error(SAXParseException e) {
59 System.out.println("---xml-error " + e);
62 public void fatalError(SAXParseException e) {
63 System.out.println("---xml-fatalerror " + e);
66 public void warning(SAXParseException e) {
67 System.out.println("---xml-warning " + e);
71 // auxillary class for feeding the dtd_
72 class BridgeEntityResolver implements EntityResolver {
76 public BridgeEntityResolver(String dtd) {
80 public InputSource resolveEntity(String publicId, String systemId)
81 throws SAXException, IOException {
82 if ((systemId != null) && systemId.endsWith("isac.dtd")) {
83 return new InputSource(new StringReader(dtd_));
85 System.out.println("BridgeEntityResolver: return null");
91 static Logger logger_ = Logger.getLogger(XMLParserDigest.class.getName());
94 * Constructor: create a new XMLParserDigest object and fill it with the
98 * Path to the DTD-File (Document Type Description)
100 public XMLParserDigest(String dtdPath) {
101 logger_.debug("XMLParserDigest: dtd_path_=" + dtdPath);
102 digester_ = new Digester();
103 digester_.setErrorHandler(new BridgeErrorHandler());
104 this.dtd_path_ = dtdPath;
105 //dtd_-File --> String (faster validating)
108 BufferedReader br = new BufferedReader(new FileReader(dtdPath));
109 sb = new StringBuffer();
111 sb.append(br.readLine() + "\n");
113 // Set dtd_ for parser validation
115 .setEntityResolver(new BridgeEntityResolver(sb.toString()));
116 } catch (FileNotFoundException e) {
118 } catch (IOException e) {
122 // Rules for the digester_ to create Objects and fill them from
124 digester_.addObjectCreate("ISAC", ResponseWrapper.class);
125 digester_.addObjectCreate("*/CALCID", CalcHeadSimpleID.class);
126 digester_.addCallMethod("*/CALCID", "setID", 0);
127 digester_.addSetRoot("*/CALCID", "setCalcID");
129 // Rules for parsing Position
130 digester_.addObjectCreate("*/POSITION", Position.class);
131 digester_.addCallMethod("*/POSITION/INTLIST/INT", "addInt", 0);
132 digester_.addCallMethod("*/POSITION/POS", "setKind", 0);
133 digester_.addSetNext("*/POSITION", "setResponse");
134 // digester_.addSetNext("*/POSITION", "setPosition");
136 // 3 different Positions in CalcChangedEvent
137 digester_.addObjectCreate("*/UNCHANGED", Position.class);
138 digester_.addCallMethod("*/UNCHANGED/INTLIST/INT", "addInt", 0);
139 digester_.addCallMethod("*/UNCHANGED/POS", "setKind", 0);
140 digester_.addSetNext("*/UNCHANGED", "setLastUnchanged");
142 digester_.addObjectCreate("*/DELETED", Position.class);
143 digester_.addCallMethod("*/DELETED/INTLIST/INT", "addInt", 0);
144 digester_.addCallMethod("*/DELETED/POS", "setKind", 0);
145 digester_.addSetNext("*/DELETED", "setLastDeleted");
147 digester_.addObjectCreate("*/GENERATED", Position.class);
148 digester_.addCallMethod("*/GENERATED/INTLIST/INT", "addInt", 0);
149 digester_.addCallMethod("*/GENERATED/POS", "setKind", 0);
150 digester_.addSetNext("*/GENERATED", "setLastGenerated");
152 // Rules for parsing Formula
153 digester_.addObjectCreate("*/FORMULA", Formula.class);
154 //CalcHeadItems have no <FORMULA> ...
155 digester_.addCallMethod("*/MATHML/ISA", "setText", 0);
156 digester_.addSetNext("*/FORMULA", "setFormula");
158 // Rules for parsing CalcFormula with Position
159 digester_.addObjectCreate("*/CALCFORMULA", CalcFormula.class);
160 digester_.addSetNext("*/CALCFORMULA", "setResponse");
162 //============== Rules for parsing CalcHead
163 digester_.addObjectCreate("*/CALCHEAD", CalcHead.class);
164 digester_.addSetProperties("*/CALCHEAD", "status", "statusString");
166 digester_.addObjectCreate("*/HEAD/MATHML", Formula.class);
167 digester_.addSetNext("*/HEAD/MATHML", "setHeadLine");
169 digester_.addCallMethod("*/CALCHEAD/BELONGSTO", "setBelongsTo", 0);
171 digester_.addObjectCreate("*/CALCHEAD/MODEL", Model.class);
172 //..........................................................WN050624xx
173 addItemList(digester_, "Given");
174 addItemList(digester_, "Where");
175 addItemList(digester_, "Find");
176 addItemList(digester_, "Relate");
177 digester_.addSetNext("*/CALCHEAD/MODEL", "setModel");
178 //..........................................................WN050624xx
180 digester_.addObjectCreate("*/CALCHEAD/SPECIFICATION",
181 Specification.class);
182 digester_.addObjectCreate("*/CALCHEAD/SPECIFICATION/THEORYID",
183 CalcHeadSimpleID.class);
185 .addCallMethod("*/CALCHEAD/SPECIFICATION/THEORYID", "setID", 0);
186 digester_.addSetNext("*/CALCHEAD/SPECIFICATION/THEORYID", "setTheory");
187 digester_.addObjectCreate("*/CALCHEAD/SPECIFICATION/PROBLEMID",
189 digester_.addCallMethod(
190 "*/CALCHEAD/SPECIFICATION/PROBLEMID/STRINGLIST/STRING",
193 .addSetNext("*/CALCHEAD/SPECIFICATION/PROBLEMID", "setProblem");
194 digester_.addObjectCreate("*/CALCHEAD/SPECIFICATION/METHODID",
196 digester_.addCallMethod(
197 "*/CALCHEAD/SPECIFICATION/METHODID/STRINGLIST/STRING",
199 digester_.addSetNext("*/CALCHEAD/SPECIFICATION/METHODID", "setMethod");
200 digester_.addSetNext("*/CALCHEAD/SPECIFICATION", "setSpecification");
201 digester_.addSetNext("*/CALCHEAD", "setResponse");
203 //============== Rules for parsing various Tactic Objects
204 // Rules for parsing SimpleTactic
205 digester_.addObjectCreate("*/SIMPLETACTIC", SimpleTactic.class);
206 digester_.addCallMethod("*/SIMPLETACTIC/MATHML/ISA", "setArgument", 0);
207 digester_.addSetProperties("*/SIMPLETACTIC", "name", "name");
208 digester_.addSetNext("*/SIMPLETACTIC", "setResponse");
210 // Rules for parsing KeyListTactic
211 digester_.addObjectCreate("*/STRINGLISTTACTIC", StringListTactic.class);
212 digester_.addCallMethod("*/STRINGLISTTACTIC/STRINGLIST/STRING",
214 digester_.addSetProperties("*/STRINGLISTTACTIC", "name", "name");
215 digester_.addSetNext("*/STRINGLISTTACTIC", "setResponse");
217 // Rules for parsing Theorem
218 digester_.addObjectCreate("*/THEOREM", Theorem.class);
219 digester_.addCallMethod("*/THEOREM/ID", "setId", 0);
221 .addCallMethod("*/THEOREM/FORMULA/MATHML/ISA", "setFormula", 0);
222 digester_.addSetNext("*/THEOREM", "setTheorem");
224 // Rules for parsing RewriteTactic
225 digester_.addObjectCreate("*/REWRITETACTIC", Rewrite.class);
226 digester_.addSetProperties("*/REWRITETACTIC", "name", "name");
227 digester_.addSetNext("*/REWRITETACTIC", "setResponse");
229 // Rules for parsing RewriteInstTactic
230 digester_.addObjectCreate("*/REWRITEINSTTACTIC", RewriteInst.class);
231 digester_.addSetProperties("*/REWRITEINSTTACTIC", "name", "name");
232 digester_.addSetNext("*/REWRITEINSTTACTIC", "setResponse");
233 digester_.addCallMethod(
234 "*/REWRITEINSTTACTIC/SUBSTITUTION/PAIR/VARIABLE/MATHML/ISA",
235 "setVariable", //WN0501 ^^^ this seems to work only on
238 digester_.addCallMethod(
239 "*/REWRITEINSTTACTIC/SUBSTITUTION/PAIR/VALUE/MATHML/ISA",
240 "setValue", //WN0501 ^^^ this seems to work only on spec_.case
243 // Rules for parsing RewriteSetTactic
244 digester_.addObjectCreate("*/REWRITESETTACTIC", RewriteSet.class);
245 digester_.addCallMethod("*/REWRITESETTACTIC/RULESET", "setRuleSet", 0);
246 digester_.addSetProperties("*/REWRITESETTACTIC", "name", "name");
247 digester_.addSetNext("*/REWRITESETTACTIC", "setResponse");
249 // Rules for parsing RewriteSetInstTactic
250 digester_.addObjectCreate("*/REWRITESETINSTTACTIC",
251 RewriteSetInst.class);
252 digester_.addCallMethod("*/REWRITESETINSTTACTIC/RULESET", "setRuleSet",
254 digester_.addCallMethod(
255 "*/REWRITESETINSTTACTIC/SUBSTITUTION/PAIR/VARIABLE/MATHML/ISA",
256 "setVariable", //WN0501 ^^^ this seems to work only on
259 digester_.addCallMethod(
260 "*/REWRITESETINSTTACTIC/SUBSTITUTION/PAIR/VALUE/MATHML/ISA",
261 "setValue", //WN0501 ^^^ this seems to work only on spec_.case
263 digester_.addSetProperties("*/REWRITESETINSTTACTIC", "name", "name");
264 digester_.addSetNext("*/REWRITESETINSTTACTIC", "setResponse");
266 // Rules for parsing SubProblemTactic
267 digester_.addObjectCreate("*/SUBPROBLEMTACTIC", SubProblemTactic.class);
268 digester_.addCallMethod("*/SUBPROBLEMTACTIC/THEORY", "setTheoryID", 0);
269 digester_.addCallMethod("*/SUBPROBLEMTACTIC/PROBLEM/STRINGLIST/STRING",
270 "addProblemString", 0);
271 digester_.addSetProperties("*/SUBPROBLEMTACTIC", "name", "name");
272 digester_.addSetNext("*/SUBPROBLEMTACTIC", "setResponse");
274 // Rules for parsing CalcIterator move message
275 digester_.addObjectCreate("*/CALCITERATOR/ERROR", Message.class);
276 digester_.addCallMethod("*/CALCITERATOR/ERROR", "setError", 0);
277 digester_.addSetNext("*/CALCITERATOR/ERROR", "setResponse");
279 // Rules for parsing CalcIterator constructor message
280 digester_.addObjectCreate("*/ADDUSER", CalcHeadSimpleID.class);
281 digester_.addCallMethod("*/ADDUSER/USERID", "setID", 0);
282 digester_.addSetNext("*/ADDUSER", "setResponse");
284 // Rules for parsing autoCalculateResponse
285 digester_.addCallMethod("*/AUTOCALC/ERROR", "setError", 0);
286 digester_.addObjectCreate("*/CALCCHANGED", CalcChanged.class);
287 digester_.addSetNext("*/CALCCHANGED", "setResponse");
289 // Rules for parsing fetchApplicableTactics
290 digester_.addObjectCreate("*/APPLICABLETACTICS/TACLIST",
291 TacticsContainer.class);
292 digester_.addSetNext("*/APPLICABLETACTICS/TACLIST", "setResponse");
294 // Rules for getElementsFromTo
295 digester_.addObjectCreate("*/GETELEMENTSFROMTO/FORMHEADS",
296 FormHeadsContainer.class);
297 digester_.addSetNext("*/GETELEMENTSFROMTO/FORMHEADS", "setResponse");
299 // getAssumptions (and still getAccumulatedAsms)
300 digester_.addObjectCreate("*/ASMLIST", Assumptions.class);
301 digester_.addSetNext("*/ASMLIST", "setResponse");
305 * parse a ModelItemList
308 * is "GIVEN" or "WHERE" or "FIND" or "RELATE"
310 private void addItemList(Digester digester, String modPart) {
311 String modPartUp = modPart.toUpperCase();
312 // Rules for parsing ItemLists in the model part of a CalcHead: Given
314 digester.addObjectCreate("*/CALCHEAD/MODEL/" + modPartUp,
315 ModelItemList.class);
316 digester.addObjectCreate("*/CALCHEAD/MODEL/" + modPartUp + "/ITEM",
318 digester.addSetProperties("*/CALCHEAD/MODEL/" + modPartUp + "/ITEM",
319 "status", "itemStatus");
320 digester.addCallMethod("*/CALCHEAD/MODEL/" + modPartUp
321 + "/ITEM/MATHML/ISA", "setText", 0);
322 digester.addSetNext("*/CALCHEAD/MODEL/" + modPartUp + "/ITEM",
324 digester.addSetNext("*/CALCHEAD/MODEL/" + modPartUp, "set" + modPart);
328 * Set whether or not using the DTD for validating
332 * <LI>true: XML is tested for validity against DTD
334 * <LI>false: XML is only tested for well-formed-ness
338 public void setValidating(boolean validating) {
339 logger_.warn("setValidating: validating=" + validating);
340 digester_.setValidating(validating);
344 * Parse an XML string to Java Object(s)
347 * the string containing the XML content
348 * @return ResponseWrapper containing the CalcID and the parsed Object
350 public ResponseWrapper parse(String xmlString) {
352 xmlString = "<?xml version=\"1.0\"?><!DOCTYPE ISAC SYSTEM \""
353 + dtd_path_ + "\"><ISAC>" + xmlString + "</ISAC>";
355 encodeEntities(xmlString);
358 o = digester_.parse(new InputSource(new StringReader(xmlString)));
359 } catch (IOException e) {
361 } catch (SAXException e) {
364 ResponseWrapper wrapper = (ResponseWrapper) o;
365 //System.out.println(wrapper.getCalcID().toSMLString());
369 public static void encodeEntities(String xmlString) {
370 xmlString = xmlString.replaceAll(" & ", "&");
371 xmlString = xmlString.replaceAll(" > ", ">");
372 xmlString = xmlString.replaceAll(" < ", "<");
375 public static void decodeEntities(String xmlString) {
376 xmlString = xmlString.replaceAll("&", " & ");
377 xmlString = xmlString.replaceAll(">", " > ");
378 xmlString = xmlString.replaceAll("<", " < ");