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

uk.ac.ed.ph.snuggletex.internal.DOMBuildingController Maven / Gradle / Ivy

/* $Id: DOMBuildingController.java 525 2010-01-05 14:07:36Z davemckain $
 *
 * Copyright (c) 2010, The University of Edinburgh.
 * All Rights Reserved
 */
package uk.ac.ed.ph.snuggletex.internal;

import uk.ac.ed.ph.snuggletex.DOMOutputOptions;
import uk.ac.ed.ph.snuggletex.DOMPostProcessor;
import uk.ac.ed.ph.snuggletex.SnuggleConstants;
import uk.ac.ed.ph.snuggletex.internal.util.XMLUtilities;
import uk.ac.ed.ph.snuggletex.tokens.FlowToken;

import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This is the main entry point into the DOM generation process. This uses a {@link DOMBuilder} to
 * build the raw DOM and then does any further work on the resulting DOM as specified by the {@link
 * DOMOutputOptions}.
 *
 * @author David McKain
 * @version $Revision: 525 $
 */
public final class DOMBuildingController {

  private final SessionContext sessionContext;
  private final DOMOutputOptions options;

  public DOMBuildingController(
      final SessionContext sessionContext, final DOMOutputOptions options) {
    this.sessionContext = sessionContext;
    this.options = options;
  }

  public void buildDOMSubtree(final Element targetRoot, final List fixedTokens)
      throws SnuggleParseException {
    DOMPostProcessor[] domPostProcessors = options.getDOMPostProcessors();
    if (domPostProcessors != null && domPostProcessors.length > 0) {
      /* We run through each Post-Processor in turn, building a temporary "outputDocument"
       * and then using it as an input for the next stage. The final outputDocument is
       * used to decide what gets added into the target Document.
       */
      Document workDocument = XMLUtilities.createNSAwareDocumentBuilder().newDocument();
      Element workRoot =
          workDocument.createElementNS(SnuggleConstants.SNUGGLETEX_NAMESPACE, "root");
      workDocument.appendChild(workRoot);

      /* Do raw DOM Building */
      DOMBuilder domBuilder = new DOMBuilder(sessionContext, workRoot, options);
      domBuilder.buildDOMSubtree(fixedTokens);

      /* Now let each post-processor mess around with the DOM */
      for (int processorIndex = 0; processorIndex < domPostProcessors.length; processorIndex++) {
        DOMPostProcessor domPostProcessor = domPostProcessors[processorIndex];

        /* Now let post-processor do its thing */
        Document outputDocument =
            domPostProcessor.postProcessDOM(
                workDocument, options, sessionContext.getStylesheetManager());

        Element adoptRoot;
        if (processorIndex == domPostProcessors.length - 1) {
          /* This is the final step, so add to targetRoot */
          adoptRoot = targetRoot;
        } else {
          /* Still go more steps to do, so we will be reusing workRoot.... */
          adoptRoot = workRoot;
          /* ...but need to remove existing child Nodes first */
          NodeList toDelete = workRoot.getChildNodes();
          for (int i = toDelete.getLength() - 1; i >= 0; i--) {
            workRoot.removeChild(toDelete.item(i));
          }
        }
        /* Adopt nodes from outputDocument to adoptRoot */
        Element resultRoot = outputDocument.getDocumentElement();
        NodeList childNodes = resultRoot.getChildNodes();
        Node childNode;
        for (int i = 0, size = childNodes.getLength(); i < size; i++) {
          childNode = childNodes.item(0); /* (Adopting each child moves subsequent ones back!) */
          adoptRoot.appendChild(adoptRoot.getOwnerDocument().adoptNode(childNode));
        }
      }
    } else {
      /* Just build as normal */
      DOMBuilder domBuilder = new DOMBuilder(sessionContext, targetRoot, options);
      domBuilder.buildDOMSubtree(fixedTokens);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy