fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major/**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * The contents of this file are subject to the terms
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * of the Common Development and Distribution License
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * (the License). You may not use this file except in
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * compliance with the License.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * You can obtain a copy of the License at
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * https://opensso.dev.java.net/public/CDDLv1.0.html or
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * opensso/legal/CDDLv1.0.txt
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * See the License for the specific language governing
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * permission and limitations under the License.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * When distributing Covered Code, include this CDDL
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Header Notice in each file and include the License file
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * at opensso/legal/CDDLv1.0.txt.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * If applicable, add the following below the CDDL Header,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * with the fields enclosed by brackets [] replaced by
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * your own identifying information:
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * "Portions Copyrighted [year] [name of copyright owner]"
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * $Id: XMLDocument.java,v 1.3 2008/06/25 05:51:31 qcheng Exp $
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorpackage com.sun.identity.install.tools.util.xml;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.BufferedWriter;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.File;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.FileInputStream;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.FileWriter;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.InputStreamReader;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.io.StringReader;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.util.ArrayList;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorimport java.util.Iterator;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major/**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Represents a simple XML document in memory that may be edited and stored.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * This implementation relies exlusively on the syntactic correctness of the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * underlying document such as balancing of quotes and delimiters etc. If an
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * XML document meets these requirements, it can be used to instantiate this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * class and can then be edited using the public methods available in this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * class as well as in <code>XMLElement</code> class.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * <p>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * The in-memroy XML representation does not include any meta information such
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * as <code>DOCTYPE</code> tags, processing instructions, or any commets. Such
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * tags are filtered out before the final in-memory representation of the XML
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document is constructed. However, when this document is saved, these meta
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * information tags are re-inserted in the appropriate places so as to preserve
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the original format of the document in all respects possible. Even white
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * spaces are preserved as far as possible.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * </p>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * <p>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * This implementation uses an adhoc scanner/parser and does not rely on any
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * third party libraries.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * </p>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Majorpublic class XMLDocument implements IXMLUtilsConstants {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Creates an instance of XMLDocument using the specified <code>File</code>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * object. No checking is done to ensure the availablity and readability of
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the file passed in as the argument. It is expected that the caller has
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * completed such checks and taken the necessary backups before creating
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * this instance.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param file
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * representing the XML document on file system.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in case an error occurse during the parsing of this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLDocument(File file) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setDocumentFile(file);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setParser(new XMLParser());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major initDocument(file);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the root element for the given XML document. This element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * represents the entire XML document in memory and can be used to traverse
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * and edit various portions of the document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return the root element of the XML tree
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLElement getRootElement() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return root;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * A factory method used for the creation of new XML elements that can be
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added to this XML document at a later stage. When this method is called,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * a new <code>XMLElement</code> object is returned to the caller.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * However, this newly created element is still not attached to the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document anywhere and it is the responsiblity of the caller to attach it
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in the appropriate location.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param name
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the name of the new element to be created
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return the newly created element that can be added to the document
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in case the creation of the new element fails due to any
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * reason
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLElement newElement(String name) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return newElement(name, null, null);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * A factory method used for the creation of new XML elements that can be
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added to this XML document at a later stage. When this method is called,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * a new <code>XMLElement</code> object is returned to the caller.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * However, this newly created element is still not attached to the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document anywhere and it is the responsiblity of the caller to attach it
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in the appropriate location. Further, the element returned from this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * method is a collapsed element that is contained within a single bounded
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * token.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param name
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the name of the new element to be created
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return the newly created element that can be added to the document
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in case the creation of the new element fails due to any
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * reason
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLElement newCollapsedElement(String name) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return newElement(name, null, null, true);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * A factory method used for the creation of new XML elements that can be
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added to this XML document at a later stage. When this method is called,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * a new <code>XMLElement</code> object is returned to the caller.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * However, this newly created element is still not attached to the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document anywhere and it is the responsiblity of the caller to attach it
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in the appropriate location. Note that the supplied parameter
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * <code>xmlFragement</code> must be a valid well-formed xml element.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param xmlFragment
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the xml fragment which will be parsed into an element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return the newly created element that can be added to the document
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in case the creation of the new element fails due to any
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * reason
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLElement newElementFromXMLFragment(String xmlFragment)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major StringReader reader = new StringReader(xmlFragment);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList newTokens = getParser().parse(reader);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList filteredTokens = getFilteredTokens(newTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList elements = getElements(filteredTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (elements == null || elements.size() != 1) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to parse fragment into new element");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return (XMLElement) elements.get(0);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * A factory method used for the creation of new XML elements that can be
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added to this XML document at a later stage. When this method is called,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * a new <code>XMLElement</code> object is returned to the caller.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * However, this newly created element is still not attached to the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document anywhere and it is the responsiblity of the caller to attach it
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in the appropriate location.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param name
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the name of the new element to be created
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param value
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the value of the new element to be created
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return the newly created element that can be added to the document
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * in case the creation of the new element fails due to any
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * reason
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public XMLElement newElement(String name, String value) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return newElement(name, value, null);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Stores the in-memory XML data to the file system.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * If the save operation did not succeed.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public void store() throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BufferedWriter writer = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major try {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major writer = new BufferedWriter(new FileWriter(getDocumentFile()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < rawTokens.size(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major writer.write(((Token) rawTokens.get(i)).toString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major writer.flush();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major writer.close();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } catch (Exception ex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw ex;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } finally {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (writer != null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major writer.close();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the number of spaces used for denoting one indent level. The
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * default indent level is set to <code>4</code> spaces. However, this can
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * be changed by calling this method anytime. This value comes into effect
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * only when any new element is added to the XML document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param spaces
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the number of spaces used to denote one level of indentation
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public void setIndentDepth(int spaces) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentDepth = spaces;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets a flag that is used by the document to indent value tokens when
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * adding child elements that have value. The default behavior is to indent
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * value tokens, but that can be changed to no indent by calling this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * method.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public void setNoValueIndent() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentValueTokenFlag = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets a flag that is used by the document to indent value tokens when
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * adding child elements that have value. The default behavior is to indent
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * value tokens, but changed by calling <code>setNoValueIndent</code>
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * method, it can be reset back to its original state by calling this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * method.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public void setValueIndent() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentValueTokenFlag = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the DOCTYPE string associated with the first DOCTYPE element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * present in this document. This method may return null if no DOCTYPE
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * token is already present in the document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public String getDoctypeString() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String result = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major DoctypeToken dctoken = getDoctypeToken();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (dctoken != null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result = dctoken.getDoctypeString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return result;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * This methods provides a means to update the DOCTYPE element of the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document with a new value as supplied in the argument. This method will
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * throw an Exception if the given document does not contain a predefined
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * DOCTYPE element.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param newDoctypeString
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major public void updatedDoctypeString(String newDoctypeString) throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major DoctypeToken dctoken = getDoctypeToken();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (dctoken != null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major dctoken.updateDoctypeString(newDoctypeString);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("FAILED to update DOCTYPE - no such element");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Adds a value token for the given element with the given value.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param value
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major void addValueTokenForElement(XMLElement element, String value)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major UnboundedToken valueToken = newValueToken(value);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int startTokenIndex = element.getStartToken().getTokenIndex();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int indentLevel = getIndentLevel(startTokenIndex);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major WhiteSpaceToken valueIndentToken = new WhiteSpaceToken(NEW_LINE
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + getIndentStringForIndentLevel(indentLevel + 1));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean added = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < rawTokens.size(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) rawTokens.get(i);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == startTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int insertIndex = i + 1;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major valueIndentToken.setTokenIndex(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(insertIndex, valueIndentToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major insertIndex++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(insertIndex, valueToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major added = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!added) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to add value token");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setValueToken(valueToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Adds the given XMLElement after the token whoes index matches the given
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * lastTokenIndex value. If the flag addAfterNewLine is true, a new line is
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added before the addition of the new element to this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param lastTokenIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param addAfterNewLine
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major void addXMLElementAfterTokenIndex(int lastTokenIndex, XMLElement element,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean addAfterNewLine) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major addXMLElementAfterTokenIndex(lastTokenIndex, element, addAfterNewLine,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major true);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Adds the given XMLElement after the token whoes index matches the given
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * lastTokenIndex value. If the flag addAfterNewLine is true, a new line is
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * added before the addition of the new element to this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param lastTokenIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param addAfterNewLine
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param addOuterWhitespace
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major void addXMLElementAfterTokenIndex(int lastTokenIndex, XMLElement element,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean addAfterNewLine, boolean addOuterWhitespace)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String outerIndentString = "";
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String indentIncrementString = "";
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (addAfterNewLine) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major outerIndentString = getIndentStringForIndentLevel(getIndentLevel(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major lastTokenIndex));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentIncrementString = getIndentIncrementString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean outerIndent = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!addOuterWhitespace) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major outerIndent = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList newTokens = element.getCollapsedTokens(outerIndentString,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentIncrementString, indentValueToken(), outerIndent);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean added = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < rawTokens.size(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) rawTokens.get(i);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == lastTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int lastIndexPosition = i;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (nextToken instanceof WhiteSpaceToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major lastIndexPosition++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major nextToken = (Token) rawTokens.get(i);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int insertIndex = lastIndexPosition + 1;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (addAfterNewLine) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major WhiteSpaceToken wstoken = new WhiteSpaceToken(NEW_LINE);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major wstoken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(insertIndex++, wstoken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int j = 0; j < newTokens.size(); j++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token newToken = (Token) newTokens.get(j);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(insertIndex + j, newToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major added = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!added) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Parent element not found: index "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + lastTokenIndex);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setRawTokens(rawTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Inserts the ending token for a given element which was initially added
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * or parsed into a collapsed element.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major void insertEndTokenForElement(XMLElement element) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int startTokenIndex = element.getStartToken().getTokenIndex();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int indentLevel = getIndentLevel(startTokenIndex);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String indentString = NEW_LINE
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + getIndentStringForIndentLevel(indentLevel - 1);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major WhiteSpaceToken indentToken = new WhiteSpaceToken(indentString);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major indentToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token endToken = element.getEndToken();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major endToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean added = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < rawTokens.size(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) rawTokens.get(i);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == startTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(i + 1, indentToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major rawTokens.add(i + 2, endToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major added = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!added) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to add end token for element: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + element);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Deletes the tokens from the token whoes index matches with startIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * upto the token whoes index matches with endIndex. Both these tokens are
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * included in the deletion as well.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param startIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param endIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major void deleteTokens(int startIndex, int endIndex) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList updatedRawTokens = new ArrayList();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major updatedRawTokens.addAll(getRawTokens());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = updatedRawTokens.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean delete = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int deleteCount = 0;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token lastToken = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!delete) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == startIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (lastToken != null
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major && lastToken instanceof WhiteSpaceToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major lastToken.markDeleted();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major nextToken.markDeleted();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major deleteCount++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (startIndex != endIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major delete = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major deleteCount++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major nextToken.markDeleted();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == endIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major delete = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major lastToken = nextToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (delete == true) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to find last token: index " +
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major endIndex);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (startIndex != endIndex && deleteCount < 2) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to delete tokens for range: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + startIndex + "-" + endIndex);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (startIndex == endIndex && deleteCount != 1) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Failed to delete token at index: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + startIndex + ", delete count: " + deleteCount);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setRawTokens(updatedRawTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns an xml fragment that represents this element and any contained
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * child elements.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param beginTokenIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the index of the token where the string begins
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param endTokenIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the index of the token where the string ends
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return an xml fragment representing this element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String toXMLFragment(int beginTokenIndex, int endTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major StringBuffer buff = new StringBuffer();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = this.getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = rawTokens.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int index = 0;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boolean inRange = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!inRange) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == beginTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major inRange = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (inRange) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major buff.append(nextToken.toString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == endTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major inRange = false;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return buff.toString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Factory method for creation a new value token with the given value.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param value
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private UnboundedToken newValueToken(String value) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (value == null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major value = "";
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major UnboundedToken valueToken = new UnboundedToken(value);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major valueToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return valueToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Factory method for creating a new element with the given name, given
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * value and given attributes. The value and the attributes may be null.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param name
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param value
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param attributes
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private XMLElement newElement(String name, String value,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList attributes) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return newElement(name, value, attributes, false);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Factory method for creating a new element with the given name, given
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * value and given attributes. The value and the attributes may be null. If
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * the boolean argument <code>collapsed</code> is set to true, the element
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * will have a single token for start and end marks. In this case if a
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * value is specified, it will result in the throwing of an exception to
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * indicate an invalid request.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param name
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param value
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param attributes
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param collapsed
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private XMLElement newElement(String name, String value,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList attributes, boolean collapsed) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major XMLElement result = new XMLElement(this, name);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String startTokenString = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (collapsed) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major startTokenString = "<" + name + "/>";
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major startTokenString = "<" + name + ">";
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken startToken = new BoundedToken(startTokenString);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major startToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.setStartToken(startToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (value != null && value.trim().length() > 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (collapsed) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major "Cannot add a collapsed element with specified value");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major UnboundedToken valueToken = new UnboundedToken(value);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major valueToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.setValueToken(valueToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!collapsed) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken endToken = new BoundedToken("</" + name + ">");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major endToken.setTokenIndex(getParser().getNextTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.setEndToken(endToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (attributes != null && attributes.size() > 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = attributes.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major XMLElementAttribute attr = (XMLElementAttribute) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.updateAttribute(attr.getName(), attr.getValue());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return result;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the indent level for the given token.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param tokenIndex
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private int getIndentLevel(int tokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return getRootElement().getIndentLevelForToken(tokenIndex, 0);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns a whitespace string which represents the indentation to be used
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * for a given indentLevel value.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param indentLevel
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private String getIndentStringForIndentLevel(int indentLevel) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major StringBuffer buff = new StringBuffer("");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String indentIncrementString = getIndentIncrementString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < indentLevel; i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major buff.append(indentIncrementString);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return buff.toString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns a string with the number of spaces corresponding to the indent
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * depth set for this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private String getIndentIncrementString() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major StringBuffer buff = new StringBuffer("");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = 0; i < getIndentDepth(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major buff.append(' ');
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return buff.toString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Initializes the document with the given File object.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param file
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void initDocument(File file) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setRawTokens(getParser().parse(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major new InputStreamReader(new FileInputStream(file))));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major initXMLTree();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = rawTokens.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken instanceof DoctypeToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setDoctypeTokenIndex(nextToken.getTokenIndex());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the DOCTYPE token associated with this document. May return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * <code>null</code> if no such token is present.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private DoctypeToken getDoctypeToken() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major DoctypeToken result = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int doctypeTokenIndex = getDoctypeTokenIndex();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (doctypeTokenIndex != -1) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList rawTokens = getRawTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = rawTokens.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken.getTokenIndex() == doctypeTokenIndex) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result = (DoctypeToken) nextToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return result;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Creats an in-memory XML tree based on the parsed tokens in this
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void initXMLTree() throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major updateFilteredTokens();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList elements = getElements(getFilteredTokens());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (elements.size() > 1) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("More than one root elements encountered");
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setRootElement((XMLElement) elements.get(0));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns a list of tokens that do not contain any whitespace tokens.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param rawTokens
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return filtered tokens
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getFilteredTokens(ArrayList rawTokens) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList filteredTokens = new ArrayList();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Iterator it = rawTokens.iterator();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (it.hasNext()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) it.next();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!nextToken.isDeleted()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken instanceof BoundedToken
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major || nextToken instanceof UnboundedToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major filteredTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return filteredTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Updates the tokens to create a set of filtered tokens that make up the
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * various XML elements etc for final creation of in-memory XML
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * representation.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void updateFilteredTokens() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major setFilteredTokens(getFilteredTokens(getRawTokens()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the attributes from the given attribute string.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param attributeString
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getAttributes(String attributeString) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return getAttributes(attributeString, null);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the attributes from the given attribute strings of the starting
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * and the ending tokens of any element.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param attributeStringBegin
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param attributeStringEnd
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getAttributes(String attributeStringBegin,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String attributeStringEnd) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String attributeString = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (attributeStringBegin != null
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major && attributeStringBegin.trim().length() > 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major attributeString = attributeStringBegin;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (attributeStringEnd != null
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major && attributeStringEnd.trim().length() > 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major attributeString += attributeStringEnd;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return getParser().parseAttributes(attributeString);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Walks through the filtered token set to create an in-memory
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * representation of the XML document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param tokenList
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @throws Exception
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getElements(ArrayList tokenList) throws Exception {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList result = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (tokenList != null && tokenList.size() > 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result = new ArrayList();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int count = 0;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major while (count < tokenList.size()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String elementName = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String elementValue = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList attributeList = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList childElements = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major XMLElement element = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token firstToken = (Token) tokenList.get(count);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!(firstToken instanceof BoundedToken)) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("First token not bounded: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + firstToken.toDebugString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken token = (BoundedToken) firstToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major elementName = token.getName();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major String attributeString = token.getAttributeString();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (token.elementComplete()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element = new XMLElement(this, elementName);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setStartToken(token);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setAttributes(getAttributes(token
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.add(element);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major count++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (tokenList.size() > count + 1) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token secondToken = (Token) tokenList.get(count + 1);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (secondToken instanceof BoundedToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken secondBoundedToken = (BoundedToken)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major secondToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!secondBoundedToken.elementStart()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (secondBoundedToken.getName()
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .equals(elementName)) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (secondBoundedToken.elementEnd()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element = new XMLElement(this,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major elementName);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setStartToken(token);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setEndToken(secondBoundedToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setAttributes(getAttributes(token
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString(),
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major secondBoundedToken
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.add(element);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major count = count + 2;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Malformed element: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + secondBoundedToken
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .toDebugString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (element == null && tokenList.size() >= count + 3) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token midToken = (Token) tokenList.get(count + 1);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major UnboundedToken ubToken = null;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (midToken instanceof UnboundedToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ubToken = (UnboundedToken) midToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major elementValue = ubToken.getValue();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (elementValue != null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token thirdToken = (Token) tokenList.get(count + 2);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!(thirdToken instanceof BoundedToken)) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Malformed token encountered: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + thirdToken.toDebugString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken thirdBoundedToken = (BoundedToken)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major thirdToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!thirdBoundedToken.getName().equals(elementName)) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Malformed token encountered: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + thirdToken.toDebugString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (!thirdBoundedToken.elementEnd()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Malformed token encountered: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + thirdToken.toDebugString());
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element = new XMLElement(this, elementName,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major elementValue);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setStartToken(token);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setValueToken(ubToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setEndToken(thirdBoundedToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setAttributes(getAttributes(token
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString(), thirdBoundedToken
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.add(element);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major count = count + 3;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (element == null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major ArrayList innerTokens = new ArrayList();
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major int boundCount = 1;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major for (int i = count + 1; i < tokenList.size(); i++) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major Token nextToken = (Token) tokenList.get(i);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextToken instanceof BoundedToken) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major BoundedToken nextBoundedToken = (BoundedToken)
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major nextToken;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextBoundedToken.getName().equals(elementName))
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (nextBoundedToken.elementEnd()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if(!nextBoundedToken.elementStart()) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boundCount--;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (boundCount == 0) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major childElements = getElements(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element = new XMLElement(this,
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major elementName, childElements);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setStartToken(token);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setEndToken(nextBoundedToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major element.setAttributes(getAttributes(
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major token.getAttributeString(),
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major nextBoundedToken
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major .getAttributeString()));
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major result.add(element);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major count = i + 1;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major break;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major boundCount++;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major } else {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major innerTokens.add(nextToken);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major if (element == null) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major throw new Exception("Element not terminated: "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + elementName + ", innerTokens = "
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major + innerTokens);
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return result;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the raw tokens for this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getRawTokens() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return rawTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the raw tokens for this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param rawTokens
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setRawTokens(ArrayList rawTokens) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major this.rawTokens = rawTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the filtered tokens for this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param filteredTokens
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setFilteredTokens(ArrayList filteredTokens) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major this.filteredTokens = filteredTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the filted tokens for this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList getFilteredTokens() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return filteredTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the root element of this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param root
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setRootElement(XMLElement root) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major this.root = root;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the parser to be used with this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param parser
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setParser(XMLParser parser) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major this.parser = parser;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the parser that is used with this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private XMLParser getParser() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return parser;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the file object which is the source of this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param file
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setDocumentFile(File file) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major documentFile = file;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the file object that is the source of this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private File getDocumentFile() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return documentFile;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the preffered indentation depth of this document.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private int getIndentDepth() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return indentDepth;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns true if the value token should be indented while adding new
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * elements to this document, false otherwise.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private boolean indentValueToken() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return indentValueTokenFlag;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Sets the document type token index
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @param index
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private void setDoctypeTokenIndex(int index) {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major doctypeTokenIndex = index;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major /**
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * Returns the document type token index. May return <code>-1</code> if no
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * document type token was found.
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major *
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major * @return
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major */
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private int getDoctypeTokenIndex() {
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major return doctypeTokenIndex;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major }
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private File documentFile;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList rawTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private ArrayList filteredTokens;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private XMLElement root;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private XMLParser parser;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private int indentDepth = 4;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private boolean indentValueTokenFlag = true;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major private int doctypeTokenIndex = -1;
fb379c70e3fd8a537f311b99be4759ae41e02750Peter Major}