Clover coverage report - QedeqKernelSe Coverage Report
Coverage timestamp: Do Mai 10 2007 03:16:40 CEST
file stats: LOC: 881   Methods: 74
NCLOC: 611   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Context2SimpleXPath.java 85,5% 92,2% 86,5% 90,5%
coverage coverage
 1    /* $Id: Context2SimpleXPath.java,v 1.7 2007/04/12 23:50:10 m31 Exp $
 2    *
 3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
 4    *
 5    * Copyright 2000-2007, Michael Meyling <mime@qedeq.org>.
 6    *
 7    * "Hilbert II" is free software; you can redistribute
 8    * it and/or modify it under the terms of the GNU General Public
 9    * License as published by the Free Software Foundation; either
 10    * version 2 of the License, or (at your option) any later version.
 11    *
 12    * This program is distributed in the hope that it will be useful,
 13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15    * GNU General Public License for more details.
 16    */
 17   
 18    package org.qedeq.kernel.xml.mapper;
 19   
 20    import java.util.ArrayList;
 21    import java.util.HashMap;
 22    import java.util.List;
 23    import java.util.Map;
 24   
 25    import org.qedeq.kernel.base.list.ElementList;
 26    import org.qedeq.kernel.base.module.Author;
 27    import org.qedeq.kernel.base.module.AuthorList;
 28    import org.qedeq.kernel.base.module.Axiom;
 29    import org.qedeq.kernel.base.module.Chapter;
 30    import org.qedeq.kernel.base.module.ChapterList;
 31    import org.qedeq.kernel.base.module.Formula;
 32    import org.qedeq.kernel.base.module.FunctionDefinition;
 33    import org.qedeq.kernel.base.module.Header;
 34    import org.qedeq.kernel.base.module.Import;
 35    import org.qedeq.kernel.base.module.ImportList;
 36    import org.qedeq.kernel.base.module.Latex;
 37    import org.qedeq.kernel.base.module.LatexList;
 38    import org.qedeq.kernel.base.module.LinkList;
 39    import org.qedeq.kernel.base.module.LiteratureItem;
 40    import org.qedeq.kernel.base.module.LiteratureItemList;
 41    import org.qedeq.kernel.base.module.Location;
 42    import org.qedeq.kernel.base.module.LocationList;
 43    import org.qedeq.kernel.base.module.Node;
 44    import org.qedeq.kernel.base.module.PredicateDefinition;
 45    import org.qedeq.kernel.base.module.Proof;
 46    import org.qedeq.kernel.base.module.ProofList;
 47    import org.qedeq.kernel.base.module.Proposition;
 48    import org.qedeq.kernel.base.module.Qedeq;
 49    import org.qedeq.kernel.base.module.Rule;
 50    import org.qedeq.kernel.base.module.Section;
 51    import org.qedeq.kernel.base.module.SectionList;
 52    import org.qedeq.kernel.base.module.Specification;
 53    import org.qedeq.kernel.base.module.Subsection;
 54    import org.qedeq.kernel.base.module.SubsectionList;
 55    import org.qedeq.kernel.base.module.Term;
 56    import org.qedeq.kernel.base.module.UsedByList;
 57    import org.qedeq.kernel.base.module.VariableList;
 58    import org.qedeq.kernel.bo.module.ModuleContext;
 59    import org.qedeq.kernel.bo.module.ModuleDataException;
 60    import org.qedeq.kernel.bo.visitor.AbstractModuleVisitor;
 61    import org.qedeq.kernel.bo.visitor.QedeqNotNullTransverser;
 62    import org.qedeq.kernel.dto.list.Enumerator;
 63    import org.qedeq.kernel.trace.Trace;
 64    import org.qedeq.kernel.xml.tracker.SimpleXPath;
 65   
 66   
 67    /**
 68    * Map content string to SimpleXPath string. This class makes it possible to transfer an location
 69    * of an {@link org.qedeq.kernel.base.module.Qedeq} object into an XPath like position description
 70    * for an XML file representation of that object.
 71    *
 72    * <p>
 73    * See {@link #getXPath(ModuleContext, Qedeq)} for further details.
 74    *
 75    * <p>
 76    * TODO mime 20070217: It seems to work this way but: this class assumes that we can find
 77    * QEDEQ/CHAPTER[2]/SECTION[4]/SUBSECTIONS/SUBSECTION[2]
 78    * even if we have some ../NODE s inbetween.
 79    * (Example: NODE, NODE, SUBSECTION, NODE, SUBSECTION, NODE..)
 80    *
 81    * Is this still a correct XPath? (Old solution was usage of "*")
 82    * Seems ok for official XPath specification, but does it work for our SimpleXPathFinder?
 83    *
 84    * @version $Revision: 1.7 $
 85    * @author Michael Meyling
 86    */
 87    public final class Context2SimpleXPath extends AbstractModuleVisitor {
 88   
 89    /** Transverse QEDEQ module with this transverser. */
 90    private QedeqNotNullTransverser transverser;
 91   
 92    /** QEDEQ object to work on. */
 93    private Qedeq qedeq;
 94   
 95    /** Search for this context. */
 96    private final ModuleContext find;
 97   
 98    /** We are currently at this position. */
 99    private SimpleXPath current;
 100   
 101    /** Element stack. */
 102    private final List elements;
 103   
 104    /** Current stack level. */
 105    private int level;
 106   
 107    /** Is the current context already matching the beginning of the search context? */
 108    private boolean matching;
 109   
 110    /** Last matching begin of search context. See {@link #matching}. */
 111    private String matchingBegin;
 112   
 113    /** Corresponding XPath for the {@link #matchingBegin}. */
 114    private SimpleXPath matchingPath;
 115   
 116    /**
 117    * Constructor.
 118    *
 119    * @param find Find this location.
 120    * @param qedeq Within this QEDEQ object.
 121    */
 122  28955 private Context2SimpleXPath(final ModuleContext find, final Qedeq qedeq) {
 123  28955 this.qedeq = qedeq;
 124  28955 transverser = new QedeqNotNullTransverser(find.getModuleLocation(), this);
 125  28955 this.find = find;
 126  28955 elements = new ArrayList(20);
 127    }
 128   
 129    /**
 130    * This method finds a {@link ModuleContext} something like<br>
 131    * <code>
 132    * getChapterList().get(4).getSectionList().get(0).getSubsectionList().get(4).getLatex().get(0)
 133    * </code><br>
 134    * within a {@link Qedeq} module and returns a kind of XPath location for an associated
 135    * XML document:<br>
 136    * <code>QEDEQ/CHAPTER[5]/SECTION/SUBSECTIONS/SUBSECTION[2]/TEXT/LATEX</code>
 137    *
 138    * <p>
 139    * At this example one can already see that <code>getSubsectionList().get(4)</code> is
 140    * transformed into <code>SUBSECTIONS/SUBSECTION[2]</code>. This is due to the fact that
 141    * <code>SUBSECTION</code> contains a sequence of <code>SUBSECTION</code> or <code>NODE</code>
 142    * elements. The transformation depends not only from the context but also from
 143    * the concrete QEDEQ module.
 144    *
 145    * <p>
 146    * Especially the transformation of formula location information in their XML counterpart
 147    * demands parsing the whole formula.
 148    *
 149    * @param find Find this location.
 150    * @param qedeq Within this QEDEQ object.
 151    * @return XPath for this location in the XML document.
 152    * @throws ModuleDataException
 153    */
 154  28955 public static SimpleXPath getXPath(final ModuleContext find, final Qedeq qedeq)
 155    throws ModuleDataException {
 156  28955 final Context2SimpleXPath converter = new Context2SimpleXPath(find, qedeq);
 157  28955 return converter.find();
 158    }
 159   
 160  28955 private final SimpleXPath find() throws ModuleDataException {
 161  28955 final String method = "find()";
 162  28955 Trace.paramInfo(this, method, "find", find);
 163  28955 elements.clear();
 164  28955 level = 0;
 165  28955 current = new SimpleXPath();
 166  28955 try {
 167  28955 transverser.accept(qedeq);
 168    } catch (LocationFoundException e) {
 169  28955 Trace.paramInfo(this, method, "location found", current);
 170  28955 return current;
 171    }
 172  0 Trace.param(this, method, "level", level); // level should be equal to zero now
 173  0 Trace.info(this, method, "location was not found");
 174  0 throw new LocationNotFoundException(find);
 175    }
 176   
 177  28955 public final void visitEnter(final Qedeq qedeq) throws ModuleDataException {
 178  28955 enter("QEDEQ");
 179  28955 final String method = "visitEnter(Qedeq)";
 180  28955 Trace.param(this, method, "current", current);
 181  28955 checkMatching(method);
 182    }
 183   
 184  0 public final void visitLeave(final Qedeq qedeq) {
 185  0 leave();
 186    }
 187   
 188  28953 public final void visitEnter(final Header header) throws ModuleDataException {
 189  28953 enter("HEADER");
 190  28953 final String method = "visitEnter(Header)";
 191  28953 Trace.param(this, method, "current", current);
 192  28953 final String context = transverser.getCurrentContext().getLocationWithinModule();
 193  28953 checkMatching(method);
 194   
 195  28940 transverser.setLocationWithinModule(context + ".getEmail()");
 196  28940 current.setAttribute("email");
 197  28940 checkIfFound();
 198    }
 199   
 200  28489 public final void visitLeave(final Header header) {
 201  28489 leave();
 202    }
 203   
 204  563 public final void visitEnter(final Specification specification) throws ModuleDataException {
 205  563 enter("SPECIFICATION");
 206  563 final String method = "visitEnter(Specification)";
 207  563 Trace.param(this, method, "current", current);
 208  563 final String context = transverser.getCurrentContext().getLocationWithinModule();
 209  563 checkMatching(method);
 210   
 211  511 transverser.setLocationWithinModule(context + ".getName()");
 212  511 current.setAttribute("name");
 213  511 checkIfFound();
 214   
 215  487 transverser.setLocationWithinModule(context + ".getRuleVersion()");
 216  487 current.setAttribute("ruleVersion");
 217  487 checkIfFound();
 218    }
 219   
 220  335 public final void visitLeave(final Specification specification) {
 221  335 leave();
 222    }
 223   
 224  154207 public final void visitEnter(final LatexList latexList) throws ModuleDataException {
 225  154207 final String method = "visitEnter(LatexList)";
 226  154207 final String context = transverser.getCurrentContext().getLocationWithinModule();
 227  154207 final String name;
 228  154207 if (context.endsWith(".getTitle()")) {
 229  65264 name = "TITLE";
 230  88943 } else if (context.endsWith(".getSummary()")) {
 231  289 name = "ABSTRACT";
 232  88654 } else if (context.endsWith(".getIntroduction()")) {
 233  54814 name = "INTRODUCTION";
 234  33840 } else if (context.endsWith(".getName()")) {
 235  9827 name = "NAME";
 236  24013 } else if (context.endsWith(".getPrecedingText()")) {
 237  23303 name = "PRECEDING";
 238  710 } else if (context.endsWith(".getSucceedingText()")) {
 239  276 name = "SUCCEEDING";
 240  434 } else if (context.endsWith(".getLatex()")) {
 241  150 name = "TEXT";
 242  284 } else if (context.endsWith(".getDescription()")) {
 243  120 name = "DESCRIPTION";
 244  164 } else if (context.endsWith(".getNonFormalProof()")) { // no extra XSD element
 245  66 name = null;
 246  98 } else if (context.endsWith(".getItem()")) { // no extra XSD element
 247  98 name = null;
 248    } else { // programming error
 249  0 throw new IllegalArgumentException("unknown LatexList " + context);
 250    }
 251  154207 Trace.param(this, method, "name", name);
 252  154207 if (name != null) {
 253  154043 enter(name);
 254    }
 255  154207 Trace.param(this, method, "current", current);
 256   
 257  154207 checkMatching(method);
 258    }
 259   
 260  149187 public final void visitLeave(final LatexList latexList) {
 261  149187 final String context = transverser.getCurrentContext().getLocationWithinModule();
 262  149187 if (!context.endsWith(".getNonFormalProof()") // no extra XSD element
 263    && !context.endsWith(".getItem()")) {
 264  149187 leave();
 265    }
 266    }
 267   
 268  3843 public final void visitEnter(final Latex latex) throws ModuleDataException {
 269  3843 final String context = transverser.getCurrentContext().getLocationWithinModule();
 270  3843 if (context.indexOf(".getAuthorList().get(") >= 0) { // TODO mime 20070216: why is the
 271  13 enter("NAME"); // XSD so cruel???
 272    }
 273  3843 enter("LATEX");
 274  3843 final String method = "visitEnter(Latex)";
 275  3843 Trace.param(this, method, "current", current);
 276  3843 checkMatching(method);
 277   
 278  1198 transverser.setLocationWithinModule(context + ".getLanguage()");
 279  1198 current.setAttribute("language");
 280  1198 checkIfFound();
 281   
 282  1198 transverser.setLocationWithinModule(context + ".getLatex()");
 283  1198 current.setAttribute(null); // element character data of LATEX is LaTeX content
 284  1198 checkIfFound();
 285    }
 286   
 287  1198 public final void visitLeave(final Latex latex) {
 288    // because NAME of AUTHOR/NAME/LATEX has no equivalent in interfaces:
 289  1198 final String context = transverser.getCurrentContext().getLocationWithinModule();
 290  1198 if (context.indexOf(".getAuthorList().get(") >= 0) {
 291  0 leave();
 292    }
 293  1198 leave();
 294    }
 295   
 296  128 public final void visitEnter(final LocationList locationList) throws ModuleDataException {
 297  128 enter("LOCATIONS");
 298  128 final String method = "visitEnter(LocationList)";
 299  128 Trace.param(this, method, "current", current);
 300  128 checkMatching(method);
 301   
 302    }
 303   
 304  0 public final void visitLeave(final LocationList locationList) {
 305  0 leave();
 306    }
 307   
 308  76 public final void visitEnter(final Location location) throws ModuleDataException {
 309  76 enter("LOCATION");
 310  76 final String method = "visitEnter(Location)";
 311  76 Trace.param(this, method, "current", current);
 312  76 final String context = transverser.getCurrentContext().getLocationWithinModule();
 313  76 checkMatching(method);
 314   
 315  24 transverser.setLocationWithinModule(context + ".getLocation()");
 316  24 current.setAttribute("value");
 317  24 checkIfFound();
 318    }
 319   
 320  0 public final void visitLeave(final Location location) {
 321  0 leave();
 322    }
 323   
 324  243 public final void visitEnter(final AuthorList authorList) throws ModuleDataException {
 325  243 enter("AUTHORS");
 326  243 final String method = "visitEnter(AuthorList)";
 327  243 Trace.param(this, method, "current", current);
 328  243 checkMatching(method);
 329    }
 330   
 331  171 public final void visitLeave(final AuthorList authorList) {
 332  171 leave();
 333    }
 334   
 335  48 public final void visitEnter(final Author author) throws ModuleDataException {
 336  48 enter("AUTHOR");
 337  48 final String method = "visitEnter(Author)";
 338  48 Trace.param(this, method, "current", current);
 339  48 final String context = transverser.getCurrentContext().getLocationWithinModule();
 340  48 checkMatching(method);
 341   
 342  24 transverser.setLocationWithinModule(context + ".getEmail()");
 343  24 current.setAttribute("email");
 344  24 checkIfFound();
 345    }
 346   
 347  0 public final void visitLeave(final Author author) {
 348  0 leave();
 349    }
 350   
 351  149 public final void visitEnter(final ImportList importList) throws ModuleDataException {
 352  149 enter("IMPORTS");
 353  149 final String method = "visitEnter(ImportList)";
 354  149 Trace.param(this, method, "current", current);
 355  149 checkMatching(method);
 356    }
 357   
 358  33 public final void visitLeave(final ImportList importList) {
 359  33 leave();
 360    }
 361   
 362  140 public final void visitEnter(final Import imp) throws ModuleDataException {
 363  140 enter("IMPORT");
 364  140 final String method = "visitEnter(Import)";
 365  140 Trace.param(this, method, "current", current);
 366  140 final String context = transverser.getCurrentContext().getLocationWithinModule();
 367  140 checkMatching(method);
 368   
 369  122 transverser.setLocationWithinModule(context + ".getLabel()");
 370  122 current.setAttribute("label");
 371  122 checkIfFound();
 372    }
 373   
 374  36 public final void visitLeave(final Import imp) {
 375  36 leave();
 376    }
 377   
 378  55 public final void visitEnter(final UsedByList usedByList) throws ModuleDataException {
 379  55 enter("USEDBY");
 380  55 final String method = "visitEnter(UsedByList)";
 381  55 Trace.param(this, method, "current", current);
 382  55 checkMatching(method);
 383    }
 384   
 385  0 public final void visitLeave(final UsedByList usedByList) {
 386  0 leave();
 387    }
 388   
 389  28489 public final void visitEnter(final ChapterList chapterList) throws ModuleDataException {
 390  28489 final String method = "visitEnter(ChapterList)";
 391    // because no equivalent level of "getChapterList()" exists in the XSD we simply
 392    // point to the current location that must be "QEDEQ"
 393  28489 checkMatching(method);
 394    }
 395   
 396  170 public final void visitLeave(final ChapterList chapterList) {
 397  170 transverser.setBlocked(false); // free sub node search
 398    }
 399   
 400  119587 public final void visitEnter(final Chapter chapter) throws ModuleDataException {
 401  119587 enter("CHAPTER");
 402  119587 final String method = "visitEnter(Chapter)";
 403  119587 Trace.param(this, method, "current", current);
 404  119587 final String context = transverser.getCurrentContext().getLocationWithinModule();
 405  119587 checkMatching(method);
 406   
 407  119462 transverser.setLocationWithinModule(context + ".getNoNumber()");
 408  119462 current.setAttribute("noNumber");
 409  119462 checkIfFound();
 410    }
 411   
 412  91280 public final void visitLeave(final Chapter chapter) {
 413  91280 leave();
 414    }
 415   
 416  27683 public final void visitEnter(final SectionList sectionList) throws ModuleDataException {
 417  27683 final String method = "visitEnter(SectionList)";
 418    // because no equivalent level of "getSectionList()" exists in the XSD we simply
 419    // point to the current location that must be "QEDEQ/CHAPTER[x]"
 420  27683 checkMatching(method);
 421    }
 422   
 423  0 public final void visitLeave(final SectionList sectionList) {
 424  0 transverser.setBlocked(false); // free sub node search
 425    }
 426   
 427  69278 public final void visitEnter(final Section section) throws ModuleDataException {
 428  69278 enter("SECTION");
 429  69278 final String method = "visitEnter(Section)";
 430  69278 Trace.param(this, method, "current", current);
 431  69278 final String context = transverser.getCurrentContext().getLocationWithinModule();
 432  69278 checkMatching(method);
 433   
 434  69045 transverser.setLocationWithinModule(context + ".getNoNumber()");
 435  69045 current.setAttribute("noNumber");
 436  69045 checkIfFound();
 437    }
 438   
 439  41670 public final void visitLeave(final Section section) {
 440  41670 leave();
 441    }
 442   
 443  26463 public final void visitEnter(final SubsectionList subsectionList) throws ModuleDataException {
 444  26463 enter("SUBSECTIONS");
 445  26463 final String method = "visitEnter(SubsectionList)";
 446  26463 Trace.param(this, method, "current", current);
 447  26463 checkMatching(method);
 448    }
 449   
 450  0 public final void visitLeave(final SubsectionList subsectionList) {
 451  0 leave();
 452    }
 453   
 454  3354 public final void visitEnter(final Subsection subsection) throws ModuleDataException {
 455  3354 enter("SUBSECTION");
 456  3354 final String method = "visitEnter(Subsection)";
 457  3354 Trace.param(this, method, "current", current);
 458  3354 final String context = transverser.getCurrentContext().getLocationWithinModule();
 459  3354 checkMatching(method);
 460   
 461  3260 transverser.setLocationWithinModule(context + ".getId()");
 462  3260 current.setAttribute("id");
 463  3260 checkIfFound();
 464   
 465  3260 transverser.setLocationWithinModule(context + ".getLevel()");
 466  3260 current.setAttribute("level");
 467  3260 checkIfFound();
 468    }
 469   
 470  2990 public final void visitLeave(final Subsection subsection) {
 471  2990 leave();
 472    }
 473   
 474  134807 public final void visitEnter(final Node node) throws ModuleDataException {
 475  134807 enter("NODE");
 476  134807 final String method = "visitEnter(Node)";
 477  134807 Trace.param(this, method, "current", current);
 478  134807 final String context = transverser.getCurrentContext().getLocationWithinModule();
 479  134807 checkMatching(method);
 480   
 481  134178 transverser.setLocationWithinModule(context + ".getId()");
 482  134178 current.setAttribute("id");
 483  134178 checkIfFound();
 484   
 485  133953 transverser.setLocationWithinModule(context + ".getLevel()");
 486  133953 current.setAttribute("level");
 487  133953 checkIfFound();
 488   
 489    // we dont't differentiate the different node types here and point to the parent element
 490  133809 transverser.setLocationWithinModule(context + ".getNodeType()");
 491  133809 current.setAttribute(null);
 492  133809 checkIfFound();
 493   
 494    }
 495   
 496  108821 public final void visitLeave(final Node node) {
 497  108821 leave();
 498    }
 499   
 500  2145 public final void visitEnter(final Axiom axiom) throws ModuleDataException {
 501  2145 enter("AXIOM");
 502  2145 final String method = "visitEnter(Axiom)";
 503  2145 Trace.param(this, method, "current", current);
 504  2145 checkMatching(method);
 505    }
 506   
 507  68 public final void visitLeave(final Axiom axiom) {
 508  68 leave();
 509    }
 510   
 511  16282 public final void visitEnter(final Proposition proposition) throws ModuleDataException {
 512  16282 enter("THEOREM");
 513  16282 final String method = "visitEnter(Proposition)";
 514  16282 Trace.param(this, method, "current", current);
 515  16282 checkMatching(method);
 516    }
 517   
 518  56 public final void visitLeave(final Proposition proposition) {
 519  56 leave();
 520    }
 521   
 522  152 public final void visitEnter(final ProofList proofList) throws ModuleDataException {
 523  152 final String method = "visitEnter(ProofList)";
 524    // because no equivalent level of "getProofList()" exists in the XSD we simply
 525    // point to the current location that must be within the element "THEOREM"
 526  152 checkMatching(method);
 527    }
 528   
 529  124 public final void visitEnter(final Proof proof) throws ModuleDataException {
 530  124 enter("PROOF");
 531  124 final String method = "visitEnter(Proof)";
 532  124 Trace.param(this, method, "current", current);
 533  124 final String context = transverser.getCurrentContext().getLocationWithinModule();
 534  124 checkMatching(method);
 535   
 536  86 transverser.setLocationWithinModule(context + ".getKind()");
 537  86 current.setAttribute("kind");
 538  86 checkIfFound();
 539   
 540  76 transverser.setLocationWithinModule(context + ".getLevel()");
 541  76 current.setAttribute("level");
 542  76 checkIfFound();
 543    }
 544   
 545  0 public final void visitLeave(final Proof proof) {
 546  0 leave();
 547    }
 548   
 549  1376 public final void visitEnter(final PredicateDefinition definition) throws ModuleDataException {
 550  1376 enter("DEFINITION_PREDICATE");
 551  1376 final String method = "visitEnter(PredicateDefinition)";
 552  1376 Trace.param(this, method, "current", current);
 553  1376 final String context = transverser.getCurrentContext().getLocationWithinModule();
 554  1376 checkMatching(method);
 555   
 556  1302 transverser.setLocationWithinModule(context + ".getArgumentNumber()");
 557  1302 current.setAttribute("arguments");
 558  1302 checkIfFound();
 559   
 560  1272 transverser.setLocationWithinModule(context + ".getName()");
 561  1272 current.setAttribute("name");
 562  1272 checkIfFound();
 563   
 564  1242 transverser.setLocationWithinModule(context + ".getLatexPattern()");
 565  1242 enter("LATEXPATTERN");
 566  1242 if (find.getLocationWithinModule().equals(transverser.getCurrentContext()
 567    .getLocationWithinModule())) {
 568  30 if (definition.getLatexPattern() == null) { // NOT FOUND
 569  0 leave();
 570    }
 571  30 throw new LocationFoundException(transverser.getCurrentContext());
 572    }
 573  1212 leave();
 574    }
 575   
 576  80 public final void visitLeave(final PredicateDefinition definition) {
 577  80 leave();
 578    }
 579   
 580  2062 public final void visitEnter(final FunctionDefinition definition) throws ModuleDataException {
 581  2062 enter("DEFINITION_FUNCTION");
 582  2062 final String method = "visitEnter(FunctionDefinition)";
 583  2062 Trace.param(this, method, "current", current);
 584  2062 final String context = transverser.getCurrentContext().getLocationWithinModule();
 585  2062 checkMatching(method);
 586   
 587  1966 transverser.setLocationWithinModule(context + ".getArgumentNumber()");
 588  1966 current.setAttribute("arguments");
 589  1966 checkIfFound();
 590   
 591  1934 transverser.setLocationWithinModule(context + ".getName()");
 592  1934 current.setAttribute("name");
 593  1934 checkIfFound();
 594   
 595  1902 transverser.setLocationWithinModule(context + ".getLatexPattern()");
 596  1902 enter("LATEXPATTERN");
 597  1902 if (find.getLocationWithinModule().equals(transverser.getCurrentContext()
 598    .getLocationWithinModule())) {
 599  32 if (definition.getLatexPattern() == null) { // NOT FOUND
 600  0 leave();
 601    }
 602  32 throw new LocationFoundException(transverser.getCurrentContext());
 603    }
 604  1870 leave();
 605    }
 606   
 607  42 public final void visitLeave(final FunctionDefinition definition) {
 608  42 leave();
 609    }
 610   
 611  162 public final void visitEnter(final Rule rule) throws ModuleDataException {
 612  162 enter("RULE");
 613  162 final String method = "visitEnter(Rule)";
 614  162 Trace.param(this, method, "current", current);
 615  162 final String context = transverser.getCurrentContext().getLocationWithinModule();
 616  162 checkMatching(method);
 617   
 618  128 transverser.setLocationWithinModule(context + ".getName()");
 619  128 current.setAttribute("name");
 620  128 checkIfFound();
 621    }
 622   
 623  30 public final void visitLeave(final Rule rule) {
 624  30 leave();
 625    }
 626   
 627  22 public final void visitEnter(final LinkList linkList) throws ModuleDataException {
 628  22 final String method = "visitEnter(LinkList)";
 629  22 Trace.param(this, method, "current", current);
 630  22 final String context = transverser.getCurrentContext().getLocationWithinModule();
 631  22 checkMatching(method);
 632   
 633  16 for (int i = 0; i < linkList.size(); i++) {
 634  16 enter("LINK");
 635  16 if (linkList.get(i) != null) {
 636  16 transverser.setLocationWithinModule(context + ".get(" + i + ")");
 637  16 current.setAttribute("id");
 638  16 checkIfFound();
 639    }
 640  14 leave();
 641    };
 642    }
 643   
 644  14 public final void visitLeave(final LinkList linkList) {
 645    }
 646   
 647  18797 public final void visitEnter(final Formula formula) throws ModuleDataException {
 648  18797 enter("FORMULA");
 649  18797 final String method = "visitEnter(Formula)";
 650  18797 Trace.param(this, method, "current", current);
 651  18797 checkMatching(method);
 652    }
 653   
 654  220 public final void visitLeave(final Formula formula) {
 655  220 leave();
 656    }
 657   
 658  1576 public final void visitEnter(final Term term) throws ModuleDataException {
 659  1576 enter("TERM");
 660  1576 final String method = "visitEnter(Term)";
 661  1576 Trace.param(this, method, "current", current);
 662  1576 checkMatching(method);
 663    }
 664   
 665  42 public final void visitLeave(final Term term) {
 666  42 leave();
 667    }
 668   
 669  2834 public final void visitEnter(final VariableList variableList) throws ModuleDataException {
 670  2834 enter("VARLIST");
 671  2834 final String method = "visitEnter(VariableList)";
 672  2834 Trace.param(this, method, "current", current);
 673  2834 checkMatching(method);
 674    }
 675   
 676  2270 public final void visitLeave(final VariableList variableList) {
 677  2270 leave();
 678    }
 679   
 680  163974 public final void visitEnter(final ElementList list) throws ModuleDataException {
 681  163974 final String operator = list.getOperator();
 682  163974 enter(operator);
 683  163974 final String method = "visitEnter(ElementList)";
 684  163974 Trace.param(this, method, "current", current);
 685  163974 final String context = transverser.getCurrentContext().getLocationWithinModule();
 686   
 687    // to find something like getElement(0).getList().getElement(0)
 688  163974 if (context.startsWith(find.getLocationWithinModule())) {
 689  17537 throw new LocationFoundException(find);
 690    }
 691   
 692  146437 checkMatching(method);
 693   
 694  146437 transverser.setLocationWithinModule(context + ".getOperator()");
 695  146437 checkIfFound();
 696  146437 transverser.setLocationWithinModule(context);
 697  146437 final boolean firstIsAtom = list.size() > 0 && list.getElement(0).isAtom();
 698  146437 if (firstIsAtom) {
 699  57182 transverser.setLocationWithinModule(context + ".getElement(0).getAtom()");
 700  57182 if ("VAR".equals(operator) || "PREDVAR".equals(operator)
 701    || "FUNVAR".equals(operator)) {
 702  12157 current.setAttribute("id");
 703  12157 checkIfFound();
 704  45025 } else if ("PREDCON".equals(operator) || "FUNCON".equals(operator)) {
 705  45025 current.setAttribute("ref");
 706  45025 checkIfFound();
 707    } else { // should not occur, but just in case
 708  0 current.setAttribute(null);
 709  0 Trace.info(this, method, "unknown operator " + operator);
 710  0 throw new LocationFoundException(transverser.getCurrentContext());
 711    }
 712    }
 713    }
 714   
 715    /* TODO remove method
 716    public final void visitEnter(final Atom atom) throws ModuleDataException {
 717    final String method = "visitEnter(Atom)";
 718    Trace.param(this, method, "current", current);
 719    final String context = transverser.getCurrentContext().getLocationWithinModule();
 720    // mime 20070217: should never occur
 721    checkMatching(method);
 722    }
 723    */
 724  91927 public final void visitLeave(final ElementList list) {
 725  91927 leave();
 726    }
 727   
 728  170 public final void visitEnter(final LiteratureItemList list) throws ModuleDataException {
 729  170 enter("BIBLIOGRAPHY");
 730  170 final String method = "visitEnter(LiteratureItemList)";
 731  170 Trace.param(this, method, "current", current);
 732  170 checkMatching(method);
 733    }
 734   
 735  0 public final void visitLeave(final LiteratureItemList list) {
 736  0 leave();
 737    }
 738   
 739  524 public final void visitEnter(final LiteratureItem item) throws ModuleDataException {
 740  524 enter("ITEM");
 741  524 final String method = "visitEnter(LiteratureItem)";
 742  524 Trace.param(this, method, "current", current);
 743  524 final String context = transverser.getCurrentContext().getLocationWithinModule();
 744  524 checkMatching(method);
 745   
 746  478 transverser.setLocationWithinModule(context + ".getLabel()");
 747  478 current.setAttribute("label");
 748  478 checkIfFound();
 749    }
 750   
 751  360 public final void visitLeave(final LiteratureItem item) {
 752  360 leave();
 753    }
 754   
 755    /**
 756    * Check if searched for context is already reached.
 757    *
 758    * @throws LocationFoundException We have found it.
 759    */
 760  1660032 private final void checkIfFound() throws LocationFoundException {
 761  1660032 if (find.getLocationWithinModule().equals(transverser.getCurrentContext()
 762    .getLocationWithinModule())) {
 763  11356 throw new LocationFoundException(transverser.getCurrentContext());
 764    }
 765    }
 766   
 767    /**
 768    * Checks if the current context matches the beginning of the context we want to find.
 769    * This method must be called at the beginning of the <code>visitEnter</code> method when
 770    * {@link #current} is correctly set. If the context of a previously visited node was already
 771    * matching and the current node doesn't start with the old matching context any longer we
 772    * throw a {@link LocationNotFoundException}.
 773    *
 774    * @param method Method we were called from.
 775    * @throws LocationNotFoundException
 776    * @throws LocationFoundException
 777    */
 778  819684 private final void checkMatching(final String method)
 779    throws LocationNotFoundException, LocationFoundException {
 780  819684 final String context = transverser.getCurrentContext().getLocationWithinModule();
 781  819684 if (find.getLocationWithinModule().startsWith(context)) {
 782  300195 Trace.info(this, method, "beginning matches");
 783  300195 Trace.paramInfo(this, method, "context", context);
 784  300195 matching = true;
 785  300195 matchingBegin = context; // remember matching context
 786  300195 matchingPath = new SimpleXPath(current); // remember last matching XPath
 787    } else {
 788  519489 if (matching) {
 789    // for example we are looking for "getHeader().getImportList().getImport(2)"
 790    // getHeader() matches, we remember "getHeader()"
 791    // getHeader().getSpecification() doesn't match, but still starts with "getHeader()"
 792    // getHeader().getImportList() matches, we remember "getHeader.getImportList()"
 793    // getHeader().getImportList().get(0) doesn't match but still starts with
 794    // "getHeader.getImportList()"
 795  519489 if (!context.startsWith(matchingBegin)) {
 796    // Matching lost, that means we will never found the location
 797    // so what can we do? We just return the last matching location and hope
 798    // it is close enough to the searched one. But at least we do some
 799    // logging here:
 800  0 Trace.info(this, method, "matching lost");
 801  0 Trace.paramInfo(this, method, "last match ", matchingBegin);
 802  0 Trace.paramInfo(this, method, "current context", context);
 803  0 Trace.paramInfo(this, method, "find context ",
 804    find.getLocationWithinModule());
 805   
 806    // throw new LocationNotFoundException(find); // when we really want to fail
 807   
 808  0 Trace.traceStack(this, method);
 809  0 Trace.info(this, method, "changing XPath to last matching one");
 810    // now we change the current XPath to the last matching one because the
 811    // contents of "current" is used as the resulting XPath later on when
 812    // catching the exception in {@link #find()}
 813  0 current = matchingPath;
 814  0 throw new LocationFoundException(new ModuleContext(find.getModuleLocation(),
 815    matchingBegin));
 816    }
 817    }
 818  519489 transverser.setBlocked(true); // block further search in sub nodes
 819    }
 820  819684 checkIfFound();
 821    }
 822   
 823    /**
 824    * Enter new XML element.
 825    *
 826    * @param element Element name.
 827    */
 828  783884 private final void enter(final String element) {
 829  783884 level++;
 830  783884 current.addElement(element, addOccurence(element));
 831    }
 832   
 833    /**
 834    * Enter first occurrence of XML element of one level.
 835    *
 836    * @param element
 837    */
 838  0 private final void enterFirst(final String element) {
 839  0 level++;
 840  0 current.addElement(element);
 841    }
 842   
 843    /**
 844    * Leave last XML element.
 845    */
 846  522401 private final void leave() {
 847  522401 level--;
 848  522401 current.deleteLastElement();
 849  522401 transverser.setBlocked(false); // enable further search in sub notes
 850    }
 851   
 852    /**
 853    * Add element occurrence. For example we have <code>getHeader().getImportList().get(2)</code>
 854    * and we want to get <code>QEDEQ/HEADER/IMPORTS/IMPORT[3]</code>.
 855    * So we call <code>enter("QEDEQ")</code>, <code>enter("HEADER")</code>,
 856    * <code>enter("IMPORTS")</code> and last but not least
 857    * three times the sequence <code>enter("IMPORT")</code>, <code>leave("IMPORT")</code>,
 858    *
 859    * @param name Element that occurred.
 860    * @return Number of occurrences including this one.
 861    */
 862  783884 private final int addOccurence(final String name) {
 863  783884 while (level < elements.size()) {
 864  122 elements.remove(elements.size() - 1);
 865    }
 866  783884 while (level > elements.size()) {
 867  261720 elements.add(new HashMap());
 868    }
 869  783884 final Map levelMap = (Map) elements.get(level - 1);
 870  783884 final Enumerator counter;
 871  783884 if (levelMap.containsKey(name)) {
 872  311913 counter = (Enumerator) levelMap.get(name);
 873  311913 counter.increaseNumber();
 874    } else {
 875  471971 counter = new Enumerator(1);
 876  471971 levelMap.put(name, counter);
 877    }
 878  783884 return counter.getNumber();
 879    }
 880   
 881    }