All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.qedeq.kernel.xml.mapper.Context2SimpleXPath Maven / Gradle / Ivy

/* This file is part of the project "Hilbert II" - http://www.qedeq.org
 *
 * Copyright 2000-2013,  Michael Meyling .
 *
 * "Hilbert II" is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

package org.qedeq.kernel.xml.mapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.qedeq.base.trace.Trace;
import org.qedeq.base.utility.Enumerator;
import org.qedeq.kernel.se.base.list.ElementList;
import org.qedeq.kernel.se.base.module.Add;
import org.qedeq.kernel.se.base.module.Author;
import org.qedeq.kernel.se.base.module.AuthorList;
import org.qedeq.kernel.se.base.module.Axiom;
import org.qedeq.kernel.se.base.module.ChangedRule;
import org.qedeq.kernel.se.base.module.ChangedRuleList;
import org.qedeq.kernel.se.base.module.Chapter;
import org.qedeq.kernel.se.base.module.ChapterList;
import org.qedeq.kernel.se.base.module.Conclusion;
import org.qedeq.kernel.se.base.module.ConditionalProof;
import org.qedeq.kernel.se.base.module.Existential;
import org.qedeq.kernel.se.base.module.FormalProof;
import org.qedeq.kernel.se.base.module.FormalProofLine;
import org.qedeq.kernel.se.base.module.FormalProofLineList;
import org.qedeq.kernel.se.base.module.FormalProofList;
import org.qedeq.kernel.se.base.module.Formula;
import org.qedeq.kernel.se.base.module.FunctionDefinition;
import org.qedeq.kernel.se.base.module.Header;
import org.qedeq.kernel.se.base.module.Hypothesis;
import org.qedeq.kernel.se.base.module.Import;
import org.qedeq.kernel.se.base.module.ImportList;
import org.qedeq.kernel.se.base.module.InitialPredicateDefinition;
import org.qedeq.kernel.se.base.module.Latex;
import org.qedeq.kernel.se.base.module.LatexList;
import org.qedeq.kernel.se.base.module.LinkList;
import org.qedeq.kernel.se.base.module.LiteratureItem;
import org.qedeq.kernel.se.base.module.LiteratureItemList;
import org.qedeq.kernel.se.base.module.Location;
import org.qedeq.kernel.se.base.module.LocationList;
import org.qedeq.kernel.se.base.module.ModusPonens;
import org.qedeq.kernel.se.base.module.Node;
import org.qedeq.kernel.se.base.module.PredicateDefinition;
import org.qedeq.kernel.se.base.module.Proof;
import org.qedeq.kernel.se.base.module.ProofList;
import org.qedeq.kernel.se.base.module.Proposition;
import org.qedeq.kernel.se.base.module.Qedeq;
import org.qedeq.kernel.se.base.module.Reason;
import org.qedeq.kernel.se.base.module.Rename;
import org.qedeq.kernel.se.base.module.Rule;
import org.qedeq.kernel.se.base.module.Section;
import org.qedeq.kernel.se.base.module.SectionList;
import org.qedeq.kernel.se.base.module.Specification;
import org.qedeq.kernel.se.base.module.Subsection;
import org.qedeq.kernel.se.base.module.SubsectionList;
import org.qedeq.kernel.se.base.module.SubstFree;
import org.qedeq.kernel.se.base.module.SubstFunc;
import org.qedeq.kernel.se.base.module.SubstPred;
import org.qedeq.kernel.se.base.module.Term;
import org.qedeq.kernel.se.base.module.Universal;
import org.qedeq.kernel.se.base.module.UsedByList;
import org.qedeq.kernel.se.common.ModuleContext;
import org.qedeq.kernel.se.common.ModuleDataException;
import org.qedeq.kernel.se.visitor.AbstractModuleVisitor;
import org.qedeq.kernel.se.visitor.QedeqNotNullTraverser;
import org.qedeq.kernel.xml.tracker.SimpleXPath;


/**
 * Map content string to SimpleXPath string. This class makes it possible to transfer an location
 * of an {@link org.qedeq.kernel.se.base.module.Qedeq} object into an XPath like position description
 * for an XML file representation of that object.
 *
 * 

* See {@link #getXPath(ModuleContext, Qedeq)} for further details. * *

* TODO mime 20070217: It seems to work this way but: this class assumes that we can find * QEDEQ/CHAPTER[2]/SECTION[4]/SUBSECTIONS/SUBSECTION[2] * even if we have some ../NODE s inbetween. * (Example: NODE, NODE, SUBSECTION, NODE, SUBSECTION, NODE..) * * Is this still a correct XPath? (Old solution was usage of "*") * Seems ok for official XPath specification, but does it work for our SimpleXPathFinder? * * @author Michael Meyling */ public final class Context2SimpleXPath extends AbstractModuleVisitor { /** This class. */ private static final Class CLASS = Context2SimpleXPath.class; /** Traverse QEDEQ module with this traverser. */ private QedeqNotNullTraverser traverser; /** QEDEQ object to work on. */ private Qedeq qedeq; /** Search for this context. */ private final ModuleContext find; /** We are currently at this position. */ private SimpleXPath current; /** Element stack. */ private final List elements; /** Current stack level. */ private int level; /** Is the current context already matching the beginning of the search context? */ private boolean matching; /** Last matching begin of search context. See {@link #matching}. */ private String matchingBegin; /** Corresponding XPath for the {@link #matchingBegin}. */ private SimpleXPath matchingPath; /** * Constructor. * * @param find Find this location. * @param qedeq Within this QEDEQ object. */ private Context2SimpleXPath(final ModuleContext find, final Qedeq qedeq) { this.qedeq = qedeq; traverser = new QedeqNotNullTraverser(find.getModuleLocation(), this); this.find = find; elements = new ArrayList(20); } /** * This method finds a {@link ModuleContext} something like
* * getChapterList().get(4).getSectionList().get(0).getSubsectionList().get(4).getLatex().get(0) *
* within a {@link Qedeq} module and returns a kind of XPath location for an associated * XML document:
* QEDEQ/CHAPTER[5]/SECTION/SUBSECTIONS/SUBSECTION[2]/TEXT/LATEX * *

* At this example one can already see that getSubsectionList().get(4) is * transformed into SUBSECTIONS/SUBSECTION[2]. This is due to the fact that * SUBSECTION contains a sequence of SUBSECTION or NODE * elements. The transformation depends not only from the context but also from * the concrete QEDEQ module. * *

* Especially the transformation of formula location information in their XML counterpart * demands parsing the whole formula. * * @param find Find this location. * @param qedeq Within this QEDEQ object. * @return XPath for this location in the XML document. * @throws ModuleDataException Problem with module data. */ public static SimpleXPath getXPath(final ModuleContext find, final Qedeq qedeq) throws ModuleDataException { final Context2SimpleXPath converter = new Context2SimpleXPath(find, qedeq); return converter.find(); } private final SimpleXPath find() throws ModuleDataException { final String method = "find()"; Trace.paramInfo(CLASS, this, method, "find", find); elements.clear(); level = 0; current = new SimpleXPath(); try { traverser.accept(qedeq); } catch (LocationFoundException e) { Trace.paramInfo(CLASS, this, method, "location found", current); return current; } Trace.param(CLASS, this, method, "level", level); // level should be equal to zero now Trace.info(CLASS, this, method, "location was not found"); // do we really want to fail? if (Boolean.TRUE.toString().equalsIgnoreCase( System.getProperty("qedeq.test.xmlLocationFailures"))) { throw new LocationNotFoundException(traverser.getCurrentContext(), matchingBegin, find.getLocationWithinModule()); } throw new LocationFoundException(new ModuleContext(find.getModuleLocation(), matchingBegin)); } public final void visitEnter(final Qedeq qedeq) throws ModuleDataException { enter("QEDEQ"); final String method = "visitEnter(Qedeq)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final Qedeq qedeq) { leave(); } public final void visitEnter(final Header header) throws ModuleDataException { enter("HEADER"); final String method = "visitEnter(Header)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getEmail()"); current.setAttribute("email"); checkIfFound(); } public final void visitLeave(final Header header) { leave(); } public final void visitEnter(final Specification specification) throws ModuleDataException { enter("SPECIFICATION"); final String method = "visitEnter(Specification)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getRuleVersion()"); current.setAttribute("ruleVersion"); checkIfFound(); } public final void visitLeave(final Specification specification) { leave(); } public final void visitEnter(final LatexList latexList) throws ModuleDataException { final String method = "visitEnter(LatexList)"; final String context = traverser.getCurrentContext().getLocationWithinModule(); final String name; if (context.endsWith(".getTitle()")) { name = "TITLE"; } else if (context.endsWith(".getSummary()")) { name = "ABSTRACT"; } else if (context.endsWith(".getIntroduction()")) { name = "INTRODUCTION"; } else if (context.endsWith(".getName()")) { name = "NAME"; } else if (context.endsWith(".getPrecedingText()")) { name = "PRECEDING"; } else if (context.endsWith(".getSucceedingText()")) { name = "SUCCEEDING"; } else if (context.endsWith(".getLatex()")) { name = "TEXT"; } else if (context.endsWith(".getDescription()")) { if (context.indexOf(".getChangedRuleList().get(") >= 0) { name = null; } else { name = "DESCRIPTION"; } } else if (context.endsWith(".getNonFormalProof()")) { // no extra XSD element name = null; } else if (context.endsWith(".getItem()")) { // no extra XSD element name = null; } else { // programming error throw new IllegalArgumentException("unknown LatexList " + context); } Trace.param(CLASS, this, method, "name", name); if (name != null) { enter(name); } Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final LatexList latexList) { final String context = traverser.getCurrentContext().getLocationWithinModule(); if (!context.endsWith(".getNonFormalProof()") // no extra XSD element && !context.endsWith(".getItem()") && !(context.endsWith(".getDescription()") && context.indexOf(".getChangedRuleList().get(") >= 0)) { leave(); } } public final void visitEnter(final Latex latex) throws ModuleDataException { final String context = traverser.getCurrentContext().getLocationWithinModule(); if (context.indexOf(".getAuthorList().get(") >= 0) { // TODO mime 20070216: why is the enter("NAME"); // XSD so cruel??? } enter("LATEX"); final String method = "visitEnter(Latex)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); traverser.setLocationWithinModule(context + ".getLanguage()"); current.setAttribute("language"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLatex()"); current.setAttribute(null); // element character data of LATEX is LaTeX content checkIfFound(); } public final void visitLeave(final Latex latex) { // because NAME of AUTHOR/NAME/LATEX has no equivalent in interfaces: final String context = traverser.getCurrentContext().getLocationWithinModule(); if (context.indexOf(".getAuthorList().get(") >= 0) { leave(); } leave(); } public final void visitEnter(final LocationList locationList) throws ModuleDataException { enter("LOCATIONS"); final String method = "visitEnter(LocationList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final LocationList locationList) { leave(); } public final void visitEnter(final Location location) throws ModuleDataException { enter("LOCATION"); final String method = "visitEnter(Location)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLocation()"); current.setAttribute("value"); checkIfFound(); } public final void visitLeave(final Location location) { leave(); } public final void visitEnter(final AuthorList authorList) throws ModuleDataException { enter("AUTHORS"); final String method = "visitEnter(AuthorList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final AuthorList authorList) { leave(); } public final void visitEnter(final Author author) throws ModuleDataException { enter("AUTHOR"); final String method = "visitEnter(Author)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getEmail()"); current.setAttribute("email"); checkIfFound(); } public final void visitLeave(final Author author) { leave(); } public final void visitEnter(final ImportList importList) throws ModuleDataException { enter("IMPORTS"); final String method = "visitEnter(ImportList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final ImportList importList) { leave(); } public final void visitEnter(final Import imp) throws ModuleDataException { enter("IMPORT"); final String method = "visitEnter(Import)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLabel()"); current.setAttribute("label"); checkIfFound(); } public final void visitLeave(final Import imp) { leave(); } public final void visitEnter(final UsedByList usedByList) throws ModuleDataException { enter("USEDBY"); final String method = "visitEnter(UsedByList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final UsedByList usedByList) { leave(); } public final void visitEnter(final ChapterList chapterList) throws ModuleDataException { final String method = "visitEnter(ChapterList)"; // because no equivalent level of "getChapterList()" exists in the XSD we simply // point to the current location that must be "QEDEQ" checkMatching(method); } public final void visitLeave(final ChapterList chapterList) { traverser.setBlocked(false); // free sub node search } public final void visitEnter(final Chapter chapter) throws ModuleDataException { enter("CHAPTER"); final String method = "visitEnter(Chapter)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getNoNumber()"); current.setAttribute("noNumber"); checkIfFound(); } public final void visitLeave(final Chapter chapter) { leave(); } public final void visitEnter(final SectionList sectionList) throws ModuleDataException { final String method = "visitEnter(SectionList)"; // because no equivalent level of "getSectionList()" exists in the XSD we simply // point to the current location that must be "QEDEQ/CHAPTER[x]" checkMatching(method); } public final void visitLeave(final SectionList sectionList) { traverser.setBlocked(false); // free node search again } public final void visitEnter(final Section section) throws ModuleDataException { enter("SECTION"); final String method = "visitEnter(Section)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getNoNumber()"); current.setAttribute("noNumber"); checkIfFound(); } public final void visitLeave(final Section section) { leave(); } public final void visitEnter(final SubsectionList subsectionList) throws ModuleDataException { enter("SUBSECTIONS"); final String method = "visitEnter(SubsectionList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final SubsectionList subsectionList) { leave(); } public final void visitEnter(final Subsection subsection) throws ModuleDataException { enter("SUBSECTION"); final String method = "visitEnter(Subsection)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getId()"); current.setAttribute("id"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLevel()"); current.setAttribute("level"); checkIfFound(); } public final void visitLeave(final Subsection subsection) { leave(); } public final void visitEnter(final Node node) throws ModuleDataException { enter("NODE"); final String method = "visitEnter(Node)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getId()"); current.setAttribute("id"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLevel()"); current.setAttribute("level"); checkIfFound(); // we dont't differentiate the different node types here and point to the parent element traverser.setLocationWithinModule(context + ".getNodeType()"); current.setAttribute(null); checkIfFound(); } public final void visitLeave(final Node node) { leave(); } public final void visitEnter(final Axiom axiom) throws ModuleDataException { enter("AXIOM"); final String method = "visitEnter(Axiom)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getDefinedOperator()"); current.setAttribute("definedOperator"); checkIfFound(); } public final void visitLeave(final Axiom axiom) { leave(); } public final void visitEnter(final Proposition proposition) throws ModuleDataException { enter("THEOREM"); final String method = "visitEnter(Proposition)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final Proposition proposition) { leave(); } public final void visitEnter(final ProofList proofList) throws ModuleDataException { final String method = "visitEnter(ProofList)"; // because no equivalent level of "getProofList()" exists in the XSD we simply // point to the current location that must be within the element "THEOREM" or "RULE" checkMatching(method); } public final void visitEnter(final Proof proof) throws ModuleDataException { enter("PROOF"); final String method = "visitEnter(Proof)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getKind()"); current.setAttribute("kind"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLevel()"); current.setAttribute("level"); checkIfFound(); } public final void visitLeave(final Proof proof) { leave(); } public final void visitEnter(final FormalProofList proofList) throws ModuleDataException { final String method = "visitEnter(FormalProofList)"; // because no equivalent level of "getProofList()" exists in the XSD we simply // point to the current location that must be within the element "THEOREM" checkMatching(method); } public final void visitEnter(final FormalProof proof) throws ModuleDataException { enter("FORMAL_PROOF"); final String method = "visitEnter(FormalProof)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final FormalProof proof) { leave(); } public final void visitEnter(final FormalProofLineList list) throws ModuleDataException { enter("LINES"); final String method = "visitEnter(FormalProofLineList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final FormalProofLineList list) { leave(); } public final void visitEnter(final FormalProofLine line) throws ModuleDataException { enter("L"); final String method = "visitEnter(FormalProofLine)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLabel()"); current.setAttribute("label"); checkIfFound(); } public final void visitLeave(final FormalProofLine line) { leave(); } public final void visitEnter(final ConditionalProof reason) throws ModuleDataException { enter("CP"); final String method = "visitEnter(ConditionalProof)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final ConditionalProof reason) { leave(); } public final void visitEnter(final Reason reason) throws ModuleDataException { // nothing to enter in XML final String method = "visitEnter(Reason)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final Reason reason) { // nothing to leave in XML } public final void visitEnter(final Add reason) throws ModuleDataException { enter("ADD"); final String method = "visitEnter(Add)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final Add reason) { leave(); } public final void visitEnter(final ModusPonens reason) throws ModuleDataException { enter("MP"); final String method = "visitEnter(ModusPonens)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference1()"); current.setAttribute("ref1"); checkIfFound(); traverser.setLocationWithinModule(context + ".getReference2()"); current.setAttribute("ref2"); checkIfFound(); } public final void visitLeave(final ModusPonens reason) { leave(); } public final void visitEnter(final Rename reason) throws ModuleDataException { enter("RENAME"); final String method = "visitEnter(Add)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); traverser.setLocationWithinModule(context + ".getOccurrence()"); current.setAttribute("occurrence"); checkIfFound(); } public final void visitLeave(final Rename reason) { leave(); } public final void visitEnter(final SubstFree reason) throws ModuleDataException { enter("SUBST_FREE"); final String method = "visitEnter(SubstFree)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final SubstFree reason) { leave(); } public final void visitEnter(final SubstFunc reason) throws ModuleDataException { enter("SUBST_FUNVAR"); final String method = "visitEnter(SubstFunc)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final SubstFunc reason) { leave(); } public final void visitEnter(final SubstPred reason) throws ModuleDataException { enter("SUBST_PREDVAR"); final String method = "visitEnter(SubstPred)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final SubstPred reason) { leave(); } public final void visitEnter(final Existential reason) throws ModuleDataException { enter("EXISTENTIAL"); final String method = "visitEnter(Existential)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final Existential reason) { leave(); } public final void visitEnter(final Universal reason) throws ModuleDataException { enter("UNIVERSAL"); final String method = "visitEnter(Universal)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getReference()"); current.setAttribute("ref"); checkIfFound(); } public final void visitLeave(final Universal reason) { leave(); } public final void visitEnter(final Hypothesis hypothesis) throws ModuleDataException { enter("HYPOTHESIS"); final String method = "visitEnter(Hypothesis)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLabel()"); current.setAttribute("label"); checkIfFound(); } public final void visitLeave(final Hypothesis hypothesis) { leave(); } public final void visitEnter(final Conclusion conclusion) throws ModuleDataException { enter("CONCLUSION"); final String method = "visitEnter(Conclusion)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLabel()"); current.setAttribute("label"); checkIfFound(); } public final void visitLeave(final Conclusion conclusion) { leave(); } public final void visitEnter(final InitialPredicateDefinition definition) throws ModuleDataException { enter("DEFINITION_PREDICATE_INITIAL"); final String method = "visitEnter(InitialPredicateDefinition)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getArgumentNumber()"); current.setAttribute("arguments"); checkIfFound(); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLatexPattern()"); enter("LATEXPATTERN"); if (find.getLocationWithinModule().equals(traverser.getCurrentContext() .getLocationWithinModule())) { if (definition.getLatexPattern() == null) { // NOT FOUND leave(); } throw new LocationFoundException(traverser.getCurrentContext()); } leave(); } public final void visitLeave(final InitialPredicateDefinition definition) { leave(); } public final void visitEnter(final PredicateDefinition definition) throws ModuleDataException { enter("DEFINITION_PREDICATE"); final String method = "visitEnter(PredicateDefinition)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getArgumentNumber()"); current.setAttribute("arguments"); checkIfFound(); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLatexPattern()"); enter("LATEXPATTERN"); if (find.getLocationWithinModule().equals(traverser.getCurrentContext() .getLocationWithinModule())) { if (definition.getLatexPattern() == null) { // NOT FOUND leave(); } throw new LocationFoundException(traverser.getCurrentContext()); } leave(); } public final void visitLeave(final PredicateDefinition definition) { leave(); } public final void visitEnter(final FunctionDefinition definition) throws ModuleDataException { enter("DEFINITION_FUNCTION"); final String method = "visitEnter(FunctionDefinition)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getArgumentNumber()"); current.setAttribute("arguments"); checkIfFound(); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getLatexPattern()"); enter("LATEXPATTERN"); if (find.getLocationWithinModule().equals(traverser.getCurrentContext() .getLocationWithinModule())) { if (definition.getLatexPattern() == null) { // NOT FOUND leave(); } throw new LocationFoundException(traverser.getCurrentContext()); } leave(); } public final void visitLeave(final FunctionDefinition definition) { leave(); } public final void visitEnter(final Rule rule) throws ModuleDataException { enter("RULE"); final String method = "visitEnter(Rule)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getVersion()"); current.setAttribute("version"); checkIfFound(); } public final void visitLeave(final Rule rule) { leave(); } public final void visitEnter(final ChangedRuleList list) throws ModuleDataException { final String method = "visitEnter(ChangedRuleList)"; // because no equivalent level of "getChangedRuleList()" exists in the XSD we simply // point to the current location that must be within the element "RULE" checkMatching(method); } public final void visitLeave(final ChangedRuleList list) { traverser.setBlocked(false); // free node search again } public final void visitEnter(final ChangedRule rule) throws ModuleDataException { enter("CHANGED_RULE"); final String method = "visitEnter(ChangedRule)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getName()"); current.setAttribute("name"); checkIfFound(); traverser.setLocationWithinModule(context + ".getVersion()"); current.setAttribute("version"); checkIfFound(); } public final void visitLeave(final ChangedRule rule) { leave(); } public final void visitEnter(final LinkList linkList) throws ModuleDataException { final String method = "visitEnter(LinkList)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); for (int i = 0; i < linkList.size(); i++) { enter("LINK"); if (linkList.get(i) != null) { traverser.setLocationWithinModule(context + ".get(" + i + ")"); current.setAttribute("id"); checkIfFound(); } leave(); }; } public final void visitLeave(final LinkList linkList) { // nothing to do } public final void visitEnter(final Formula formula) throws ModuleDataException { enter("FORMULA"); final String method = "visitEnter(Formula)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final Formula formula) { leave(); } public final void visitEnter(final Term term) throws ModuleDataException { enter("TERM"); final String method = "visitEnter(Term)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final Term term) { leave(); } public final void visitEnter(final ElementList list) throws ModuleDataException { final String operator = list.getOperator(); enter(operator); final String method = "visitEnter(ElementList)"; Trace.param(CLASS, this, method, "current", current); String context = traverser.getCurrentContext().getLocationWithinModule(); // to find something like getElement(0).getList().getElement(0) if (context.startsWith(find.getLocationWithinModule())) { throw new LocationFoundException(find); } checkMatching(method); traverser.setLocationWithinModule(context + ".getOperator()"); checkIfFound(); traverser.setLocationWithinModule(context); final boolean firstIsAtom = list.size() > 0 && list.getElement(0).isAtom(); if (firstIsAtom) { traverser.setLocationWithinModule(context + ".getElement(0)"); if ("VAR".equals(operator) || "PREDVAR".equals(operator) || "FUNVAR".equals(operator)) { current.setAttribute("id"); checkIfFound(); traverser.setLocationWithinModule(context + ".getElement(0).getAtom()"); checkIfFound(); } else if ("PREDCON".equals(operator) || "FUNCON".equals(operator)) { current.setAttribute("ref"); checkIfFound(); traverser.setLocationWithinModule(context + ".getElement(0).getAtom()"); checkIfFound(); } else { // should not occur, but just in case current.setAttribute(null); Trace.info(CLASS, this, method, "unknown operator " + operator); throw new LocationFoundException(traverser.getCurrentContext()); } } } public final void visitLeave(final ElementList list) { leave(); } /* we dont need it any more public final void visitEnter(final Atom atom) throws ModuleDataException { final String method = "visitEnter(Atom)"; Trace.param(this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); // mime 20070217: should never occur checkMatching(method); } */ public final void visitEnter(final LiteratureItemList list) throws ModuleDataException { enter("BIBLIOGRAPHY"); final String method = "visitEnter(LiteratureItemList)"; Trace.param(CLASS, this, method, "current", current); checkMatching(method); } public final void visitLeave(final LiteratureItemList list) { leave(); } public final void visitEnter(final LiteratureItem item) throws ModuleDataException { enter("ITEM"); final String method = "visitEnter(LiteratureItem)"; Trace.param(CLASS, this, method, "current", current); final String context = traverser.getCurrentContext().getLocationWithinModule(); checkMatching(method); traverser.setLocationWithinModule(context + ".getLabel()"); current.setAttribute("label"); checkIfFound(); } public final void visitLeave(final LiteratureItem item) { leave(); } /** * Check if searched for context is already reached. * * @throws LocationFoundException We have found it. */ private final void checkIfFound() throws LocationFoundException { if (find.getLocationWithinModule().equals(traverser.getCurrentContext() .getLocationWithinModule())) { throw new LocationFoundException(traverser.getCurrentContext()); } } /** * Checks if the current context matches the beginning of the context we want to find. * This method must be called at the beginning of the visitEnter method when * {@link #current} is correctly set. If the context of a previously visited node was already * matching and the current node doesn't start with the old matching context any longer we * throw a {@link LocationNotFoundException}. * * @param method Method we were called from. * @throws LocationNotFoundException Not found. * @throws LocationFoundException Success! */ private final void checkMatching(final String method) throws LocationNotFoundException, LocationFoundException { final String context = traverser.getCurrentContext().getLocationWithinModule(); if (find.getLocationWithinModule().startsWith(context)) { Trace.info(CLASS, this, method, "beginning matches"); Trace.paramInfo(CLASS, this, method, "context", context); matching = true; matchingBegin = context; // remember matching context matchingPath = new SimpleXPath(current); // remember last matching XPath } else { if (context.startsWith(find.getLocationWithinModule())) { // our current location is more specific than our search location // so the current location is the best match for our search throw new LocationFoundException(traverser.getCurrentContext()); } if (matching) { // for example we are looking for "getHeader().getImportList().getImport(2)" // getHeader() matches, we remember "getHeader()" // getHeader().getSpecification() doesn't match, but still starts with "getHeader()" // getHeader().getImportList() matches, we remember "getHeader.getImportList()" // getHeader().getImportList().get(0) doesn't match but still starts with // "getHeader.getImportList()" if (!context.startsWith(matchingBegin)) { // Matching lost, that means we will never found the location // so what can we do? We just return the last matching location and hope // it is close enough to the searched one. But at least we do some // logging here: Trace.info(CLASS, this, method, "matching lost, when finding error location"); Trace.paramInfo(CLASS, this, method, "last match ", matchingBegin); Trace.paramInfo(CLASS, this, method, "current context", context); Trace.paramInfo(CLASS, this, method, "find context ", find.getLocationWithinModule()); Trace.traceStack(CLASS, this, method); Trace.info(CLASS, this, method, "changing XPath to last matching one"); // do we really want to fail? if (Boolean.TRUE.toString().equalsIgnoreCase( System.getProperty("qedeq.test.xmlLocationFailures"))) { throw new LocationNotFoundException(traverser.getCurrentContext(), matchingBegin, find.getLocationWithinModule()); } // now we change the current XPath to the last matching one because the // contents of "current" is used as the resulting XPath later on when // catching the exception in {@link #find()} current = matchingPath; throw new LocationFoundException(new ModuleContext(find.getModuleLocation(), matchingBegin)); } } traverser.setBlocked(true); // block further search in sub nodes } checkIfFound(); } /** * Enter new XML element. * * @param element Element name. */ private final void enter(final String element) { level++; current.addElement(element, addOccurence(element)); } /** * Leave last XML element. */ private final void leave() { level--; current.deleteLastElement(); traverser.setBlocked(false); // enable further search in nodes } /** * Add element occurrence. For example we have getHeader().getImportList().get(2) * and we want to get QEDEQ/HEADER/IMPORTS/IMPORT[3]. * So we call enter("QEDEQ"), enter("HEADER"), * enter("IMPORTS") and last but not least * three times the sequence enter("IMPORT"), leave("IMPORT"), * * @param name Element that occurred. * @return Number of occurrences including this one. */ private final int addOccurence(final String name) { while (level < elements.size()) { elements.remove(elements.size() - 1); } while (level > elements.size()) { elements.add(new HashMap()); } final Map levelMap = (Map) elements.get(level - 1); final Enumerator counter; if (levelMap.containsKey(name)) { counter = (Enumerator) levelMap.get(name); counter.increaseNumber(); } else { counter = new Enumerator(1); levelMap.put(name, counter); } return counter.getNumber(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy