0001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
0002 *
0003 * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>.
0004 *
0005 * "Hilbert II" is free software; you can redistribute
0006 * it and/or modify it under the terms of the GNU General Public
0007 * License as published by the Free Software Foundation; either
0008 * version 2 of the License, or (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0013 * GNU General Public License for more details.
0014 */
0015
0016 package org.qedeq.kernel.xml.mapper;
0017
0018 import java.util.ArrayList;
0019 import java.util.HashMap;
0020 import java.util.List;
0021 import java.util.Map;
0022
0023 import org.qedeq.base.trace.Trace;
0024 import org.qedeq.base.utility.Enumerator;
0025 import org.qedeq.kernel.se.base.list.ElementList;
0026 import org.qedeq.kernel.se.base.module.Add;
0027 import org.qedeq.kernel.se.base.module.Author;
0028 import org.qedeq.kernel.se.base.module.AuthorList;
0029 import org.qedeq.kernel.se.base.module.Axiom;
0030 import org.qedeq.kernel.se.base.module.ChangedRule;
0031 import org.qedeq.kernel.se.base.module.ChangedRuleList;
0032 import org.qedeq.kernel.se.base.module.Chapter;
0033 import org.qedeq.kernel.se.base.module.ChapterList;
0034 import org.qedeq.kernel.se.base.module.Conclusion;
0035 import org.qedeq.kernel.se.base.module.ConditionalProof;
0036 import org.qedeq.kernel.se.base.module.Existential;
0037 import org.qedeq.kernel.se.base.module.FormalProof;
0038 import org.qedeq.kernel.se.base.module.FormalProofLine;
0039 import org.qedeq.kernel.se.base.module.FormalProofLineList;
0040 import org.qedeq.kernel.se.base.module.FormalProofList;
0041 import org.qedeq.kernel.se.base.module.Formula;
0042 import org.qedeq.kernel.se.base.module.FunctionDefinition;
0043 import org.qedeq.kernel.se.base.module.Header;
0044 import org.qedeq.kernel.se.base.module.Hypothesis;
0045 import org.qedeq.kernel.se.base.module.Import;
0046 import org.qedeq.kernel.se.base.module.ImportList;
0047 import org.qedeq.kernel.se.base.module.InitialFunctionDefinition;
0048 import org.qedeq.kernel.se.base.module.InitialPredicateDefinition;
0049 import org.qedeq.kernel.se.base.module.Latex;
0050 import org.qedeq.kernel.se.base.module.LatexList;
0051 import org.qedeq.kernel.se.base.module.LinkList;
0052 import org.qedeq.kernel.se.base.module.LiteratureItem;
0053 import org.qedeq.kernel.se.base.module.LiteratureItemList;
0054 import org.qedeq.kernel.se.base.module.Location;
0055 import org.qedeq.kernel.se.base.module.LocationList;
0056 import org.qedeq.kernel.se.base.module.ModusPonens;
0057 import org.qedeq.kernel.se.base.module.Node;
0058 import org.qedeq.kernel.se.base.module.PredicateDefinition;
0059 import org.qedeq.kernel.se.base.module.Proof;
0060 import org.qedeq.kernel.se.base.module.ProofList;
0061 import org.qedeq.kernel.se.base.module.Proposition;
0062 import org.qedeq.kernel.se.base.module.Qedeq;
0063 import org.qedeq.kernel.se.base.module.Reason;
0064 import org.qedeq.kernel.se.base.module.Rename;
0065 import org.qedeq.kernel.se.base.module.Rule;
0066 import org.qedeq.kernel.se.base.module.Section;
0067 import org.qedeq.kernel.se.base.module.SectionList;
0068 import org.qedeq.kernel.se.base.module.Specification;
0069 import org.qedeq.kernel.se.base.module.Subsection;
0070 import org.qedeq.kernel.se.base.module.SubsectionList;
0071 import org.qedeq.kernel.se.base.module.SubstFree;
0072 import org.qedeq.kernel.se.base.module.SubstFunc;
0073 import org.qedeq.kernel.se.base.module.SubstPred;
0074 import org.qedeq.kernel.se.base.module.Term;
0075 import org.qedeq.kernel.se.base.module.Universal;
0076 import org.qedeq.kernel.se.base.module.UsedByList;
0077 import org.qedeq.kernel.se.common.ModuleContext;
0078 import org.qedeq.kernel.se.common.ModuleDataException;
0079 import org.qedeq.kernel.se.visitor.AbstractModuleVisitor;
0080 import org.qedeq.kernel.se.visitor.QedeqNotNullTraverser;
0081 import org.qedeq.kernel.xml.tracker.SimpleXPath;
0082
0083
0084 /**
0085 * Map content string to SimpleXPath string. This class makes it possible to transfer an location
0086 * of an {@link org.qedeq.kernel.se.base.module.Qedeq} object into an XPath like position description
0087 * for an XML file representation of that object.
0088 *
0089 * <p>
0090 * See {@link #getXPath(ModuleContext, Qedeq)} for further details.
0091 *
0092 * <p>
0093 * TODO mime 20070217: It seems to work this way but: this class assumes that we can find
0094 * QEDEQ/CHAPTER[2]/SECTION[4]/SUBSECTIONS/SUBSECTION[2]
0095 * even if we have some ../NODE s inbetween.
0096 * (Example: NODE, NODE, SUBSECTION, NODE, SUBSECTION, NODE..)
0097 *
0098 * Is this still a correct XPath? (Old solution was usage of "*")
0099 * Seems ok for official XPath specification, but does it work for our SimpleXPathFinder?
0100 *
0101 * @author Michael Meyling
0102 */
0103 public final class Context2SimpleXPath extends AbstractModuleVisitor {
0104
0105 /** This class. */
0106 private static final Class CLASS = Context2SimpleXPath.class;
0107
0108 /** Traverse QEDEQ module with this traverser. */
0109 private QedeqNotNullTraverser traverser;
0110
0111 /** QEDEQ object to work on. */
0112 private Qedeq qedeq;
0113
0114 /** Search for this context. */
0115 private final ModuleContext find;
0116
0117 /** We are currently at this position. */
0118 private SimpleXPath current;
0119
0120 /** Element stack. */
0121 private final List elements;
0122
0123 /** Current stack level. */
0124 private int level;
0125
0126 /** Is the current context already matching the beginning of the search context? */
0127 private boolean matching;
0128
0129 /** Last matching begin of search context. See {@link #matching}. */
0130 private String matchingBegin;
0131
0132 /** Corresponding XPath for the {@link #matchingBegin}. */
0133 private SimpleXPath matchingPath;
0134
0135 /**
0136 * Constructor.
0137 *
0138 * @param find Find this location.
0139 * @param qedeq Within this QEDEQ object.
0140 */
0141 private Context2SimpleXPath(final ModuleContext find, final Qedeq qedeq) {
0142 this.qedeq = qedeq;
0143 traverser = new QedeqNotNullTraverser(find.getModuleLocation(), this);
0144 this.find = find;
0145 elements = new ArrayList(20);
0146 }
0147
0148 /**
0149 * This method finds a {@link ModuleContext} something like<br>
0150 * <code>
0151 * getChapterList().get(4).getSectionList().get(0).getSubsectionList().get(4).getLatex().get(0)
0152 * </code><br>
0153 * within a {@link Qedeq} module and returns a kind of XPath location for an associated
0154 * XML document:<br>
0155 * <code>QEDEQ/CHAPTER[5]/SECTION/SUBSECTIONS/SUBSECTION[2]/TEXT/LATEX</code>
0156 *
0157 * <p>
0158 * At this example one can already see that <code>getSubsectionList().get(4)</code> is
0159 * transformed into <code>SUBSECTIONS/SUBSECTION[2]</code>. This is due to the fact that
0160 * <code>SUBSECTION</code> contains a sequence of <code>SUBSECTION</code> or <code>NODE</code>
0161 * elements. The transformation depends not only from the context but also from
0162 * the concrete QEDEQ module.
0163 *
0164 * <p>
0165 * Especially the transformation of formula location information in their XML counterpart
0166 * demands parsing the whole formula.
0167 *
0168 * @param find Find this location.
0169 * @param qedeq Within this QEDEQ object.
0170 * @return XPath for this location in the XML document.
0171 * @throws ModuleDataException Problem with module data.
0172 */
0173 public static SimpleXPath getXPath(final ModuleContext find, final Qedeq qedeq)
0174 throws ModuleDataException {
0175 final Context2SimpleXPath converter = new Context2SimpleXPath(find, qedeq);
0176 return converter.find();
0177 }
0178
0179 private final SimpleXPath find() throws ModuleDataException {
0180 final String method = "find()";
0181 Trace.paramInfo(CLASS, this, method, "find", find);
0182 elements.clear();
0183 level = 0;
0184 current = new SimpleXPath();
0185 try {
0186 traverser.accept(qedeq);
0187 } catch (LocationFoundException e) {
0188 Trace.paramInfo(CLASS, this, method, "location found", current);
0189 return current;
0190 }
0191 Trace.param(CLASS, this, method, "level", level); // level should be equal to zero now
0192 Trace.info(CLASS, this, method, "location was not found");
0193 // do we really want to fail?
0194 if (Boolean.TRUE.toString().equalsIgnoreCase(
0195 System.getProperty("qedeq.test.xmlLocationFailures"))) {
0196 throw new LocationNotFoundException(traverser.getCurrentContext(),
0197 matchingBegin, find.getLocationWithinModule());
0198 }
0199 throw new LocationFoundException(new ModuleContext(find.getModuleLocation(),
0200 matchingBegin));
0201 }
0202
0203 public final void visitEnter(final Qedeq qedeq) throws ModuleDataException {
0204 enter("QEDEQ");
0205 final String method = "visitEnter(Qedeq)";
0206 Trace.param(CLASS, this, method, "current", current);
0207 checkMatching(method);
0208 }
0209
0210 public final void visitLeave(final Qedeq qedeq) {
0211 leave();
0212 }
0213
0214 public final void visitEnter(final Header header) throws ModuleDataException {
0215 enter("HEADER");
0216 final String method = "visitEnter(Header)";
0217 Trace.param(CLASS, this, method, "current", current);
0218 final String context = traverser.getCurrentContext().getLocationWithinModule();
0219 checkMatching(method);
0220
0221 traverser.setLocationWithinModule(context + ".getEmail()");
0222 current.setAttribute("email");
0223 checkIfFound();
0224 }
0225
0226 public final void visitLeave(final Header header) {
0227 leave();
0228 }
0229
0230 public final void visitEnter(final Specification specification) throws ModuleDataException {
0231 enter("SPECIFICATION");
0232 final String method = "visitEnter(Specification)";
0233 Trace.param(CLASS, this, method, "current", current);
0234 final String context = traverser.getCurrentContext().getLocationWithinModule();
0235 checkMatching(method);
0236
0237 traverser.setLocationWithinModule(context + ".getName()");
0238 current.setAttribute("name");
0239 checkIfFound();
0240
0241 traverser.setLocationWithinModule(context + ".getRuleVersion()");
0242 current.setAttribute("ruleVersion");
0243 checkIfFound();
0244 }
0245
0246 public final void visitLeave(final Specification specification) {
0247 leave();
0248 }
0249
0250 public final void visitEnter(final LatexList latexList) throws ModuleDataException {
0251 final String method = "visitEnter(LatexList)";
0252 final String context = traverser.getCurrentContext().getLocationWithinModule();
0253 final String name;
0254 if (context.endsWith(".getTitle()")) {
0255 name = "TITLE";
0256 } else if (context.endsWith(".getSummary()")) {
0257 name = "ABSTRACT";
0258 } else if (context.endsWith(".getIntroduction()")) {
0259 name = "INTRODUCTION";
0260 } else if (context.endsWith(".getName()")) {
0261 name = "NAME";
0262 } else if (context.endsWith(".getPrecedingText()")) {
0263 name = "PRECEDING";
0264 } else if (context.endsWith(".getSucceedingText()")) {
0265 name = "SUCCEEDING";
0266 } else if (context.endsWith(".getLatex()")) {
0267 name = "TEXT";
0268 } else if (context.endsWith(".getDescription()")) {
0269 if (context.indexOf(".getChangedRuleList().get(") >= 0) {
0270 name = null;
0271 } else {
0272 name = "DESCRIPTION";
0273 }
0274 } else if (context.endsWith(".getNonFormalProof()")) { // no extra XSD element
0275 name = null;
0276 } else if (context.endsWith(".getItem()")) { // no extra XSD element
0277 name = null;
0278 } else { // programming error
0279 throw new IllegalArgumentException("unknown LatexList " + context);
0280 }
0281 Trace.param(CLASS, this, method, "name", name);
0282 if (name != null) {
0283 enter(name);
0284 }
0285 Trace.param(CLASS, this, method, "current", current);
0286
0287 checkMatching(method);
0288 }
0289
0290 public final void visitLeave(final LatexList latexList) {
0291 final String context = traverser.getCurrentContext().getLocationWithinModule();
0292 if (!context.endsWith(".getNonFormalProof()") // no extra XSD element
0293 && !context.endsWith(".getItem()") && !(context.endsWith(".getDescription()")
0294 && context.indexOf(".getChangedRuleList().get(") >= 0)) {
0295 leave();
0296 }
0297 }
0298
0299 public final void visitEnter(final Latex latex) throws ModuleDataException {
0300 final String context = traverser.getCurrentContext().getLocationWithinModule();
0301 if (context.indexOf(".getAuthorList().get(") >= 0) { // TODO mime 20070216: why is the
0302 enter("NAME"); // XSD so cruel???
0303 }
0304 enter("LATEX");
0305 final String method = "visitEnter(Latex)";
0306 Trace.param(CLASS, this, method, "current", current);
0307 checkMatching(method);
0308
0309 traverser.setLocationWithinModule(context + ".getLanguage()");
0310 current.setAttribute("language");
0311 checkIfFound();
0312
0313 traverser.setLocationWithinModule(context + ".getLatex()");
0314 current.setAttribute(null); // element character data of LATEX is LaTeX content
0315 checkIfFound();
0316 }
0317
0318 public final void visitLeave(final Latex latex) {
0319 // because NAME of AUTHOR/NAME/LATEX has no equivalent in interfaces:
0320 final String context = traverser.getCurrentContext().getLocationWithinModule();
0321 if (context.indexOf(".getAuthorList().get(") >= 0) {
0322 leave();
0323 }
0324 leave();
0325 }
0326
0327 public final void visitEnter(final LocationList locationList) throws ModuleDataException {
0328 enter("LOCATIONS");
0329 final String method = "visitEnter(LocationList)";
0330 Trace.param(CLASS, this, method, "current", current);
0331 checkMatching(method);
0332
0333 }
0334
0335 public final void visitLeave(final LocationList locationList) {
0336 leave();
0337 }
0338
0339 public final void visitEnter(final Location location) throws ModuleDataException {
0340 enter("LOCATION");
0341 final String method = "visitEnter(Location)";
0342 Trace.param(CLASS, this, method, "current", current);
0343 final String context = traverser.getCurrentContext().getLocationWithinModule();
0344 checkMatching(method);
0345
0346 traverser.setLocationWithinModule(context + ".getLocation()");
0347 current.setAttribute("value");
0348 checkIfFound();
0349 }
0350
0351 public final void visitLeave(final Location location) {
0352 leave();
0353 }
0354
0355 public final void visitEnter(final AuthorList authorList) throws ModuleDataException {
0356 enter("AUTHORS");
0357 final String method = "visitEnter(AuthorList)";
0358 Trace.param(CLASS, this, method, "current", current);
0359 checkMatching(method);
0360 }
0361
0362 public final void visitLeave(final AuthorList authorList) {
0363 leave();
0364 }
0365
0366 public final void visitEnter(final Author author) throws ModuleDataException {
0367 enter("AUTHOR");
0368 final String method = "visitEnter(Author)";
0369 Trace.param(CLASS, this, method, "current", current);
0370 final String context = traverser.getCurrentContext().getLocationWithinModule();
0371 checkMatching(method);
0372
0373 traverser.setLocationWithinModule(context + ".getEmail()");
0374 current.setAttribute("email");
0375 checkIfFound();
0376 }
0377
0378 public final void visitLeave(final Author author) {
0379 leave();
0380 }
0381
0382 public final void visitEnter(final ImportList importList) throws ModuleDataException {
0383 enter("IMPORTS");
0384 final String method = "visitEnter(ImportList)";
0385 Trace.param(CLASS, this, method, "current", current);
0386 checkMatching(method);
0387 }
0388
0389 public final void visitLeave(final ImportList importList) {
0390 leave();
0391 }
0392
0393 public final void visitEnter(final Import imp) throws ModuleDataException {
0394 enter("IMPORT");
0395 final String method = "visitEnter(Import)";
0396 Trace.param(CLASS, this, method, "current", current);
0397 final String context = traverser.getCurrentContext().getLocationWithinModule();
0398 checkMatching(method);
0399
0400 traverser.setLocationWithinModule(context + ".getLabel()");
0401 current.setAttribute("label");
0402 checkIfFound();
0403 }
0404
0405 public final void visitLeave(final Import imp) {
0406 leave();
0407 }
0408
0409 public final void visitEnter(final UsedByList usedByList) throws ModuleDataException {
0410 enter("USEDBY");
0411 final String method = "visitEnter(UsedByList)";
0412 Trace.param(CLASS, this, method, "current", current);
0413 checkMatching(method);
0414 }
0415
0416 public final void visitLeave(final UsedByList usedByList) {
0417 leave();
0418 }
0419
0420 public final void visitEnter(final ChapterList chapterList) throws ModuleDataException {
0421 final String method = "visitEnter(ChapterList)";
0422 // because no equivalent level of "getChapterList()" exists in the XSD we simply
0423 // point to the current location that must be "QEDEQ"
0424 checkMatching(method);
0425 }
0426
0427 public final void visitLeave(final ChapterList chapterList) {
0428 traverser.setBlocked(false); // free sub node search
0429 }
0430
0431 public final void visitEnter(final Chapter chapter) throws ModuleDataException {
0432 enter("CHAPTER");
0433 final String method = "visitEnter(Chapter)";
0434 Trace.param(CLASS, this, method, "current", current);
0435 final String context = traverser.getCurrentContext().getLocationWithinModule();
0436 checkMatching(method);
0437
0438 traverser.setLocationWithinModule(context + ".getNoNumber()");
0439 current.setAttribute("noNumber");
0440 checkIfFound();
0441 }
0442
0443 public final void visitLeave(final Chapter chapter) {
0444 leave();
0445 }
0446
0447 public final void visitEnter(final SectionList sectionList) throws ModuleDataException {
0448 final String method = "visitEnter(SectionList)";
0449 // because no equivalent level of "getSectionList()" exists in the XSD we simply
0450 // point to the current location that must be "QEDEQ/CHAPTER[x]"
0451 checkMatching(method);
0452 }
0453
0454 public final void visitLeave(final SectionList sectionList) {
0455 traverser.setBlocked(false); // free node search again
0456 }
0457
0458 public final void visitEnter(final Section section) throws ModuleDataException {
0459 enter("SECTION");
0460 final String method = "visitEnter(Section)";
0461 Trace.param(CLASS, this, method, "current", current);
0462 final String context = traverser.getCurrentContext().getLocationWithinModule();
0463 checkMatching(method);
0464
0465 traverser.setLocationWithinModule(context + ".getNoNumber()");
0466 current.setAttribute("noNumber");
0467 checkIfFound();
0468 }
0469
0470 public final void visitLeave(final Section section) {
0471 leave();
0472 }
0473
0474 public final void visitEnter(final SubsectionList subsectionList) throws ModuleDataException {
0475 enter("SUBSECTIONS");
0476 final String method = "visitEnter(SubsectionList)";
0477 Trace.param(CLASS, this, method, "current", current);
0478 checkMatching(method);
0479 }
0480
0481 public final void visitLeave(final SubsectionList subsectionList) {
0482 leave();
0483 }
0484
0485 public final void visitEnter(final Subsection subsection) throws ModuleDataException {
0486 enter("SUBSECTION");
0487 final String method = "visitEnter(Subsection)";
0488 Trace.param(CLASS, this, method, "current", current);
0489 final String context = traverser.getCurrentContext().getLocationWithinModule();
0490 checkMatching(method);
0491
0492 traverser.setLocationWithinModule(context + ".getId()");
0493 current.setAttribute("id");
0494 checkIfFound();
0495
0496 traverser.setLocationWithinModule(context + ".getLevel()");
0497 current.setAttribute("level");
0498 checkIfFound();
0499 }
0500
0501 public final void visitLeave(final Subsection subsection) {
0502 leave();
0503 }
0504
0505 public final void visitEnter(final Node node) throws ModuleDataException {
0506 enter("NODE");
0507 final String method = "visitEnter(Node)";
0508 Trace.param(CLASS, this, method, "current", current);
0509 final String context = traverser.getCurrentContext().getLocationWithinModule();
0510 checkMatching(method);
0511
0512 traverser.setLocationWithinModule(context + ".getId()");
0513 current.setAttribute("id");
0514 checkIfFound();
0515
0516 traverser.setLocationWithinModule(context + ".getLevel()");
0517 current.setAttribute("level");
0518 checkIfFound();
0519
0520 // we dont't differentiate the different node types here and point to the parent element
0521 traverser.setLocationWithinModule(context + ".getNodeType()");
0522 current.setAttribute(null);
0523 checkIfFound();
0524
0525 }
0526
0527 public final void visitLeave(final Node node) {
0528 leave();
0529 }
0530
0531 public final void visitEnter(final Axiom axiom) throws ModuleDataException {
0532 enter("AXIOM");
0533 final String method = "visitEnter(Axiom)";
0534 Trace.param(CLASS, this, method, "current", current);
0535 final String context = traverser.getCurrentContext().getLocationWithinModule();
0536 checkMatching(method);
0537
0538 traverser.setLocationWithinModule(context + ".getDefinedOperator()");
0539 current.setAttribute("definedOperator");
0540 checkIfFound();
0541 }
0542
0543 public final void visitLeave(final Axiom axiom) {
0544 leave();
0545 }
0546
0547 public final void visitEnter(final Proposition proposition) throws ModuleDataException {
0548 enter("THEOREM");
0549 final String method = "visitEnter(Proposition)";
0550 Trace.param(CLASS, this, method, "current", current);
0551 checkMatching(method);
0552 }
0553
0554 public final void visitLeave(final Proposition proposition) {
0555 leave();
0556 }
0557
0558 public final void visitEnter(final ProofList proofList) throws ModuleDataException {
0559 final String method = "visitEnter(ProofList)";
0560 // because no equivalent level of "getProofList()" exists in the XSD we simply
0561 // point to the current location that must be within the element "THEOREM" or "RULE"
0562 checkMatching(method);
0563 }
0564
0565 public final void visitEnter(final Proof proof) throws ModuleDataException {
0566 enter("PROOF");
0567 final String method = "visitEnter(Proof)";
0568 Trace.param(CLASS, this, method, "current", current);
0569 final String context = traverser.getCurrentContext().getLocationWithinModule();
0570 checkMatching(method);
0571
0572 traverser.setLocationWithinModule(context + ".getKind()");
0573 current.setAttribute("kind");
0574 checkIfFound();
0575
0576 traverser.setLocationWithinModule(context + ".getLevel()");
0577 current.setAttribute("level");
0578 checkIfFound();
0579 }
0580
0581 public final void visitLeave(final Proof proof) {
0582 leave();
0583 }
0584
0585 public final void visitEnter(final FormalProofList proofList) throws ModuleDataException {
0586 final String method = "visitEnter(FormalProofList)";
0587 // because no equivalent level of "getProofList()" exists in the XSD we simply
0588 // point to the current location that must be within the element "THEOREM"
0589 checkMatching(method);
0590 }
0591
0592 public final void visitEnter(final FormalProof proof) throws ModuleDataException {
0593 enter("FORMAL_PROOF");
0594 final String method = "visitEnter(FormalProof)";
0595 Trace.param(CLASS, this, method, "current", current);
0596 checkMatching(method);
0597 }
0598
0599 public final void visitLeave(final FormalProof proof) {
0600 leave();
0601 }
0602
0603 public final void visitEnter(final FormalProofLineList list) throws ModuleDataException {
0604 enter("LINES");
0605 final String method = "visitEnter(FormalProofLineList)";
0606 Trace.param(CLASS, this, method, "current", current);
0607 checkMatching(method);
0608 }
0609
0610 public final void visitLeave(final FormalProofLineList list) {
0611 leave();
0612 }
0613
0614 public final void visitEnter(final FormalProofLine line) throws ModuleDataException {
0615 enter("L");
0616 final String method = "visitEnter(FormalProofLine)";
0617 Trace.param(CLASS, this, method, "current", current);
0618 final String context = traverser.getCurrentContext().getLocationWithinModule();
0619 checkMatching(method);
0620
0621 traverser.setLocationWithinModule(context + ".getLabel()");
0622 current.setAttribute("label");
0623 checkIfFound();
0624 }
0625
0626 public final void visitLeave(final FormalProofLine line) {
0627 leave();
0628 }
0629
0630 public final void visitEnter(final ConditionalProof reason) throws ModuleDataException {
0631 enter("CP");
0632 final String method = "visitEnter(ConditionalProof)";
0633 Trace.param(CLASS, this, method, "current", current);
0634 checkMatching(method);
0635 }
0636
0637 public final void visitLeave(final ConditionalProof reason) {
0638 leave();
0639 }
0640
0641 public final void visitEnter(final Reason reason) throws ModuleDataException {
0642 // nothing to enter in XML
0643 final String method = "visitEnter(Reason)";
0644 Trace.param(CLASS, this, method, "current", current);
0645 checkMatching(method);
0646
0647 }
0648
0649 public final void visitLeave(final Reason reason) {
0650 // nothing to leave in XML
0651 }
0652
0653 public final void visitEnter(final Add reason) throws ModuleDataException {
0654 enter("ADD");
0655 final String method = "visitEnter(Add)";
0656 Trace.param(CLASS, this, method, "current", current);
0657 final String context = traverser.getCurrentContext().getLocationWithinModule();
0658 checkMatching(method);
0659
0660 traverser.setLocationWithinModule(context + ".getReference()");
0661 current.setAttribute("ref");
0662 checkIfFound();
0663 }
0664
0665 public final void visitLeave(final Add reason) {
0666 leave();
0667 }
0668
0669 public final void visitEnter(final ModusPonens reason) throws ModuleDataException {
0670 enter("MP");
0671 final String method = "visitEnter(ModusPonens)";
0672 Trace.param(CLASS, this, method, "current", current);
0673 final String context = traverser.getCurrentContext().getLocationWithinModule();
0674 checkMatching(method);
0675
0676 traverser.setLocationWithinModule(context + ".getReference1()");
0677 current.setAttribute("ref1");
0678 checkIfFound();
0679
0680 traverser.setLocationWithinModule(context + ".getReference2()");
0681 current.setAttribute("ref2");
0682 checkIfFound();
0683 }
0684
0685 public final void visitLeave(final ModusPonens reason) {
0686 leave();
0687 }
0688
0689 public final void visitEnter(final Rename reason) throws ModuleDataException {
0690 enter("RENAME");
0691 final String method = "visitEnter(Add)";
0692 Trace.param(CLASS, this, method, "current", current);
0693 final String context = traverser.getCurrentContext().getLocationWithinModule();
0694 checkMatching(method);
0695
0696 traverser.setLocationWithinModule(context + ".getReference()");
0697 current.setAttribute("ref");
0698 checkIfFound();
0699
0700 traverser.setLocationWithinModule(context + ".getOccurrence()");
0701 current.setAttribute("occurrence");
0702 checkIfFound();
0703 }
0704
0705 public final void visitLeave(final Rename reason) {
0706 leave();
0707 }
0708
0709 public final void visitEnter(final SubstFree reason) throws ModuleDataException {
0710 enter("SUBST_FREE");
0711 final String method = "visitEnter(SubstFree)";
0712 Trace.param(CLASS, this, method, "current", current);
0713 final String context = traverser.getCurrentContext().getLocationWithinModule();
0714 checkMatching(method);
0715
0716 traverser.setLocationWithinModule(context + ".getReference()");
0717 current.setAttribute("ref");
0718 checkIfFound();
0719 }
0720
0721 public final void visitLeave(final SubstFree reason) {
0722 leave();
0723 }
0724
0725 public final void visitEnter(final SubstFunc reason) throws ModuleDataException {
0726 enter("SUBST_FUNVAR");
0727 final String method = "visitEnter(SubstFunc)";
0728 Trace.param(CLASS, this, method, "current", current);
0729 final String context = traverser.getCurrentContext().getLocationWithinModule();
0730 checkMatching(method);
0731
0732 traverser.setLocationWithinModule(context + ".getReference()");
0733 current.setAttribute("ref");
0734 checkIfFound();
0735 }
0736
0737 public final void visitLeave(final SubstFunc reason) {
0738 leave();
0739 }
0740
0741 public final void visitEnter(final SubstPred reason) throws ModuleDataException {
0742 enter("SUBST_PREDVAR");
0743 final String method = "visitEnter(SubstPred)";
0744 Trace.param(CLASS, this, method, "current", current);
0745 final String context = traverser.getCurrentContext().getLocationWithinModule();
0746 checkMatching(method);
0747
0748 traverser.setLocationWithinModule(context + ".getReference()");
0749 current.setAttribute("ref");
0750 checkIfFound();
0751 }
0752
0753 public final void visitLeave(final SubstPred reason) {
0754 leave();
0755 }
0756
0757 public final void visitEnter(final Existential reason) throws ModuleDataException {
0758 enter("EXISTENTIAL");
0759 final String method = "visitEnter(Existential)";
0760 Trace.param(CLASS, this, method, "current", current);
0761 final String context = traverser.getCurrentContext().getLocationWithinModule();
0762 checkMatching(method);
0763
0764 traverser.setLocationWithinModule(context + ".getReference()");
0765 current.setAttribute("ref");
0766 checkIfFound();
0767 }
0768
0769 public final void visitLeave(final Existential reason) {
0770 leave();
0771 }
0772
0773 public final void visitEnter(final Universal reason) throws ModuleDataException {
0774 enter("UNIVERSAL");
0775 final String method = "visitEnter(Universal)";
0776 Trace.param(CLASS, this, method, "current", current);
0777 final String context = traverser.getCurrentContext().getLocationWithinModule();
0778 checkMatching(method);
0779
0780 traverser.setLocationWithinModule(context + ".getReference()");
0781 current.setAttribute("ref");
0782 checkIfFound();
0783 }
0784
0785 public final void visitLeave(final Universal reason) {
0786 leave();
0787 }
0788
0789 public final void visitEnter(final Hypothesis hypothesis) throws ModuleDataException {
0790 enter("HYPOTHESIS");
0791 final String method = "visitEnter(Hypothesis)";
0792 Trace.param(CLASS, this, method, "current", current);
0793 final String context = traverser.getCurrentContext().getLocationWithinModule();
0794 checkMatching(method);
0795
0796 traverser.setLocationWithinModule(context + ".getLabel()");
0797 current.setAttribute("label");
0798 checkIfFound();
0799 }
0800
0801 public final void visitLeave(final Hypothesis hypothesis) {
0802 leave();
0803 }
0804
0805 public final void visitEnter(final Conclusion conclusion) throws ModuleDataException {
0806 enter("CONCLUSION");
0807 final String method = "visitEnter(Conclusion)";
0808 Trace.param(CLASS, this, method, "current", current);
0809 final String context = traverser.getCurrentContext().getLocationWithinModule();
0810 checkMatching(method);
0811
0812 traverser.setLocationWithinModule(context + ".getLabel()");
0813 current.setAttribute("label");
0814 checkIfFound();
0815 }
0816
0817 public final void visitLeave(final Conclusion conclusion) {
0818 leave();
0819 }
0820
0821 public final void visitEnter(final InitialPredicateDefinition definition) throws ModuleDataException {
0822 enter("DEFINITION_PREDICATE_INITIAL");
0823 final String method = "visitEnter(InitialPredicateDefinition)";
0824 Trace.param(CLASS, this, method, "current", current);
0825 final String context = traverser.getCurrentContext().getLocationWithinModule();
0826 checkMatching(method);
0827
0828 traverser.setLocationWithinModule(context + ".getArgumentNumber()");
0829 current.setAttribute("arguments");
0830 checkIfFound();
0831
0832 traverser.setLocationWithinModule(context + ".getName()");
0833 current.setAttribute("name");
0834 checkIfFound();
0835
0836 traverser.setLocationWithinModule(context + ".getLatexPattern()");
0837 enter("LATEXPATTERN");
0838 if (find.getLocationWithinModule().equals(traverser.getCurrentContext()
0839 .getLocationWithinModule())) {
0840 if (definition.getLatexPattern() == null) { // NOT FOUND
0841 leave();
0842 }
0843 throw new LocationFoundException(traverser.getCurrentContext());
0844 }
0845 leave();
0846 }
0847
0848 public final void visitLeave(final InitialPredicateDefinition definition) {
0849 leave();
0850 }
0851
0852 public final void visitEnter(final PredicateDefinition definition) throws ModuleDataException {
0853 enter("DEFINITION_PREDICATE");
0854 final String method = "visitEnter(PredicateDefinition)";
0855 Trace.param(CLASS, this, method, "current", current);
0856 final String context = traverser.getCurrentContext().getLocationWithinModule();
0857 checkMatching(method);
0858
0859 traverser.setLocationWithinModule(context + ".getArgumentNumber()");
0860 current.setAttribute("arguments");
0861 checkIfFound();
0862
0863 traverser.setLocationWithinModule(context + ".getName()");
0864 current.setAttribute("name");
0865 checkIfFound();
0866
0867 traverser.setLocationWithinModule(context + ".getLatexPattern()");
0868 enter("LATEXPATTERN");
0869 if (find.getLocationWithinModule().equals(traverser.getCurrentContext()
0870 .getLocationWithinModule())) {
0871 if (definition.getLatexPattern() == null) { // NOT FOUND
0872 leave();
0873 }
0874 throw new LocationFoundException(traverser.getCurrentContext());
0875 }
0876 leave();
0877 }
0878
0879 public final void visitLeave(final PredicateDefinition definition) {
0880 leave();
0881 }
0882
0883 public final void visitEnter(final InitialFunctionDefinition definition) throws ModuleDataException {
0884 enter("DEFINITION_FUNCTION_INITIAL");
0885 final String method = "visitEnter(InitialFunctionDefinition)";
0886 Trace.param(CLASS, this, method, "current", current);
0887 final String context = traverser.getCurrentContext().getLocationWithinModule();
0888 checkMatching(method);
0889
0890 traverser.setLocationWithinModule(context + ".getArgumentNumber()");
0891 current.setAttribute("arguments");
0892 checkIfFound();
0893
0894 traverser.setLocationWithinModule(context + ".getName()");
0895 current.setAttribute("name");
0896 checkIfFound();
0897
0898 traverser.setLocationWithinModule(context + ".getLatexPattern()");
0899 enter("LATEXPATTERN");
0900 if (find.getLocationWithinModule().equals(traverser.getCurrentContext()
0901 .getLocationWithinModule())) {
0902 if (definition.getLatexPattern() == null) { // NOT FOUND
0903 leave();
0904 }
0905 throw new LocationFoundException(traverser.getCurrentContext());
0906 }
0907 leave();
0908 }
0909
0910 public final void visitLeave(final InitialFunctionDefinition definition) {
0911 leave();
0912 }
0913
0914 public final void visitEnter(final FunctionDefinition definition) throws ModuleDataException {
0915 enter("DEFINITION_FUNCTION");
0916 final String method = "visitEnter(FunctionDefinition)";
0917 Trace.param(CLASS, this, method, "current", current);
0918 final String context = traverser.getCurrentContext().getLocationWithinModule();
0919 checkMatching(method);
0920
0921 traverser.setLocationWithinModule(context + ".getArgumentNumber()");
0922 current.setAttribute("arguments");
0923 checkIfFound();
0924
0925 traverser.setLocationWithinModule(context + ".getName()");
0926 current.setAttribute("name");
0927 checkIfFound();
0928
0929 traverser.setLocationWithinModule(context + ".getLatexPattern()");
0930 enter("LATEXPATTERN");
0931 if (find.getLocationWithinModule().equals(traverser.getCurrentContext()
0932 .getLocationWithinModule())) {
0933 if (definition.getLatexPattern() == null) { // NOT FOUND
0934 leave();
0935 }
0936 throw new LocationFoundException(traverser.getCurrentContext());
0937 }
0938 leave();
0939 }
0940
0941 public final void visitLeave(final FunctionDefinition definition) {
0942 leave();
0943 }
0944
0945 public final void visitEnter(final Rule rule) throws ModuleDataException {
0946 enter("RULE");
0947 final String method = "visitEnter(Rule)";
0948 Trace.param(CLASS, this, method, "current", current);
0949 final String context = traverser.getCurrentContext().getLocationWithinModule();
0950 checkMatching(method);
0951
0952 traverser.setLocationWithinModule(context + ".getName()");
0953 current.setAttribute("name");
0954 checkIfFound();
0955
0956 traverser.setLocationWithinModule(context + ".getVersion()");
0957 current.setAttribute("version");
0958 checkIfFound();
0959 }
0960
0961 public final void visitLeave(final Rule rule) {
0962 leave();
0963 }
0964
0965 public final void visitEnter(final ChangedRuleList list) throws ModuleDataException {
0966 final String method = "visitEnter(ChangedRuleList)";
0967 // because no equivalent level of "getChangedRuleList()" exists in the XSD we simply
0968 // point to the current location that must be within the element "RULE"
0969 checkMatching(method);
0970 }
0971
0972 public final void visitLeave(final ChangedRuleList list) {
0973 traverser.setBlocked(false); // free node search again
0974 }
0975
0976 public final void visitEnter(final ChangedRule rule) throws ModuleDataException {
0977 enter("CHANGED_RULE");
0978 final String method = "visitEnter(ChangedRule)";
0979 Trace.param(CLASS, this, method, "current", current);
0980 final String context = traverser.getCurrentContext().getLocationWithinModule();
0981 checkMatching(method);
0982
0983 traverser.setLocationWithinModule(context + ".getName()");
0984 current.setAttribute("name");
0985 checkIfFound();
0986
0987 traverser.setLocationWithinModule(context + ".getVersion()");
0988 current.setAttribute("version");
0989 checkIfFound();
0990 }
0991
0992 public final void visitLeave(final ChangedRule rule) {
0993 leave();
0994 }
0995
0996 public final void visitEnter(final LinkList linkList) throws ModuleDataException {
0997 final String method = "visitEnter(LinkList)";
0998 Trace.param(CLASS, this, method, "current", current);
0999 final String context = traverser.getCurrentContext().getLocationWithinModule();
1000 checkMatching(method);
1001
1002 for (int i = 0; i < linkList.size(); i++) {
1003 enter("LINK");
1004 if (linkList.get(i) != null) {
1005 traverser.setLocationWithinModule(context + ".get(" + i + ")");
1006 current.setAttribute("id");
1007 checkIfFound();
1008 }
1009 leave();
1010 };
1011 }
1012
1013 public final void visitLeave(final LinkList linkList) {
1014 // nothing to do
1015 }
1016
1017 public final void visitEnter(final Formula formula) throws ModuleDataException {
1018 enter("FORMULA");
1019 final String method = "visitEnter(Formula)";
1020 Trace.param(CLASS, this, method, "current", current);
1021 checkMatching(method);
1022 }
1023
1024 public final void visitLeave(final Formula formula) {
1025 leave();
1026 }
1027
1028 public final void visitEnter(final Term term) throws ModuleDataException {
1029 enter("TERM");
1030 final String method = "visitEnter(Term)";
1031 Trace.param(CLASS, this, method, "current", current);
1032 checkMatching(method);
1033 }
1034
1035 public final void visitLeave(final Term term) {
1036 leave();
1037 }
1038
1039 public final void visitEnter(final ElementList list) throws ModuleDataException {
1040 final String operator = list.getOperator();
1041 enter(operator);
1042 final String method = "visitEnter(ElementList)";
1043 Trace.param(CLASS, this, method, "current", current);
1044 String context = traverser.getCurrentContext().getLocationWithinModule();
1045
1046 // to find something like getElement(0).getList().getElement(0)
1047 if (context.startsWith(find.getLocationWithinModule())) {
1048 throw new LocationFoundException(find);
1049 }
1050
1051 checkMatching(method);
1052
1053 traverser.setLocationWithinModule(context + ".getOperator()");
1054 checkIfFound();
1055 traverser.setLocationWithinModule(context);
1056 final boolean firstIsAtom = list.size() > 0 && list.getElement(0).isAtom();
1057 if (firstIsAtom) {
1058 traverser.setLocationWithinModule(context + ".getElement(0)");
1059 if ("VAR".equals(operator) || "PREDVAR".equals(operator)
1060 || "FUNVAR".equals(operator)) {
1061 current.setAttribute("id");
1062 checkIfFound();
1063 traverser.setLocationWithinModule(context + ".getElement(0).getAtom()");
1064 checkIfFound();
1065 } else if ("PREDCON".equals(operator) || "FUNCON".equals(operator)) {
1066 current.setAttribute("ref");
1067 checkIfFound();
1068 traverser.setLocationWithinModule(context + ".getElement(0).getAtom()");
1069 checkIfFound();
1070 } else { // should not occur, but just in case
1071 current.setAttribute(null);
1072 Trace.info(CLASS, this, method, "unknown operator " + operator);
1073 throw new LocationFoundException(traverser.getCurrentContext());
1074 }
1075 }
1076 }
1077
1078 public final void visitLeave(final ElementList list) {
1079 leave();
1080 }
1081
1082 /* we dont need it any more
1083 public final void visitEnter(final Atom atom) throws ModuleDataException {
1084 final String method = "visitEnter(Atom)";
1085 Trace.param(this, method, "current", current);
1086 final String context = traverser.getCurrentContext().getLocationWithinModule();
1087 // mime 20070217: should never occur
1088 checkMatching(method);
1089 }
1090 */
1091 public final void visitEnter(final LiteratureItemList list) throws ModuleDataException {
1092 enter("BIBLIOGRAPHY");
1093 final String method = "visitEnter(LiteratureItemList)";
1094 Trace.param(CLASS, this, method, "current", current);
1095 checkMatching(method);
1096 }
1097
1098 public final void visitLeave(final LiteratureItemList list) {
1099 leave();
1100 }
1101
1102 public final void visitEnter(final LiteratureItem item) throws ModuleDataException {
1103 enter("ITEM");
1104 final String method = "visitEnter(LiteratureItem)";
1105 Trace.param(CLASS, this, method, "current", current);
1106 final String context = traverser.getCurrentContext().getLocationWithinModule();
1107 checkMatching(method);
1108
1109 traverser.setLocationWithinModule(context + ".getLabel()");
1110 current.setAttribute("label");
1111 checkIfFound();
1112 }
1113
1114 public final void visitLeave(final LiteratureItem item) {
1115 leave();
1116 }
1117
1118 /**
1119 * Check if searched for context is already reached.
1120 *
1121 * @throws LocationFoundException We have found it.
1122 */
1123 private final void checkIfFound() throws LocationFoundException {
1124 if (find.getLocationWithinModule().equals(traverser.getCurrentContext()
1125 .getLocationWithinModule())) {
1126 throw new LocationFoundException(traverser.getCurrentContext());
1127 }
1128 }
1129
1130 /**
1131 * Checks if the current context matches the beginning of the context we want to find.
1132 * This method must be called at the beginning of the <code>visitEnter</code> method when
1133 * {@link #current} is correctly set. If the context of a previously visited node was already
1134 * matching and the current node doesn't start with the old matching context any longer we
1135 * throw a {@link LocationNotFoundException}.
1136 *
1137 * @param method Method we were called from.
1138 * @throws LocationNotFoundException Not found.
1139 * @throws LocationFoundException Success!
1140 */
1141 private final void checkMatching(final String method)
1142 throws LocationNotFoundException, LocationFoundException {
1143 final String context = traverser.getCurrentContext().getLocationWithinModule();
1144 if (find.getLocationWithinModule().startsWith(context)) {
1145 Trace.info(CLASS, this, method, "beginning matches");
1146 Trace.paramInfo(CLASS, this, method, "context", context);
1147 matching = true;
1148 matchingBegin = context; // remember matching context
1149 matchingPath = new SimpleXPath(current); // remember last matching XPath
1150 } else {
1151 if (context.startsWith(find.getLocationWithinModule())) {
1152 // our current location is more specific than our search location
1153 // so the current location is the best match for our search
1154 throw new LocationFoundException(traverser.getCurrentContext());
1155 }
1156 if (matching) {
1157 // for example we are looking for "getHeader().getImportList().getImport(2)"
1158 // getHeader() matches, we remember "getHeader()"
1159 // getHeader().getSpecification() doesn't match, but still starts with "getHeader()"
1160 // getHeader().getImportList() matches, we remember "getHeader.getImportList()"
1161 // getHeader().getImportList().get(0) doesn't match but still starts with
1162 // "getHeader.getImportList()"
1163 if (!context.startsWith(matchingBegin)) {
1164 // Matching lost, that means we will never found the location
1165 // so what can we do? We just return the last matching location and hope
1166 // it is close enough to the searched one. But at least we do some
1167 // logging here:
1168 Trace.info(CLASS, this, method, "matching lost, when finding error location");
1169 Trace.paramInfo(CLASS, this, method, "last match ", matchingBegin);
1170 Trace.paramInfo(CLASS, this, method, "current context", context);
1171 Trace.paramInfo(CLASS, this, method, "find context ", find.getLocationWithinModule());
1172
1173 Trace.traceStack(CLASS, this, method);
1174 Trace.info(CLASS, this, method, "changing XPath to last matching one");
1175
1176 // do we really want to fail?
1177 if (Boolean.TRUE.toString().equalsIgnoreCase(
1178 System.getProperty("qedeq.test.xmlLocationFailures"))) {
1179 throw new LocationNotFoundException(traverser.getCurrentContext(),
1180 matchingBegin, find.getLocationWithinModule());
1181 }
1182
1183 // now we change the current XPath to the last matching one because the
1184 // contents of "current" is used as the resulting XPath later on when
1185 // catching the exception in {@link #find()}
1186 current = matchingPath;
1187 throw new LocationFoundException(new ModuleContext(find.getModuleLocation(),
1188 matchingBegin));
1189 }
1190 }
1191 traverser.setBlocked(true); // block further search in sub nodes
1192 }
1193 checkIfFound();
1194 }
1195
1196 /**
1197 * Enter new XML element.
1198 *
1199 * @param element Element name.
1200 */
1201 private final void enter(final String element) {
1202 level++;
1203 current.addElement(element, addOccurence(element));
1204 }
1205
1206 /**
1207 * Leave last XML element.
1208 */
1209 private final void leave() {
1210 level--;
1211 current.deleteLastElement();
1212 traverser.setBlocked(false); // enable further search in nodes
1213 }
1214
1215 /**
1216 * Add element occurrence. For example we have <code>getHeader().getImportList().get(2)</code>
1217 * and we want to get <code>QEDEQ/HEADER/IMPORTS/IMPORT[3]</code>.
1218 * So we call <code>enter("QEDEQ")</code>, <code>enter("HEADER")</code>,
1219 * <code>enter("IMPORTS")</code> and last but not least
1220 * three times the sequence <code>enter("IMPORT")</code>, <code>leave("IMPORT")</code>,
1221 *
1222 * @param name Element that occurred.
1223 * @return Number of occurrences including this one.
1224 */
1225 private final int addOccurence(final String name) {
1226 while (level < elements.size()) {
1227 elements.remove(elements.size() - 1);
1228 }
1229 while (level > elements.size()) {
1230 elements.add(new HashMap());
1231 }
1232 final Map levelMap = (Map) elements.get(level - 1);
1233 final Enumerator counter;
1234 if (levelMap.containsKey(name)) {
1235 counter = (Enumerator) levelMap.get(name);
1236 counter.increaseNumber();
1237 } else {
1238 counter = new Enumerator(1);
1239 levelMap.put(name, counter);
1240 }
1241 return counter.getNumber();
1242 }
1243
1244 }
|