View Javadoc

1   /*
2    * Copyright 2009 - 2010 JEuclid, http://jeuclid.sf.net
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id $ */
18  
19  package net.sourceforge.jeuclid.biparser;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import net.sourceforge.jeuclid.elements.JEuclidElementFactory;
25  
26  import org.xml.sax.Attributes;
27  import org.xml.sax.SAXParseException;
28  
29  /**
30   * this class if for creating a BiTree with ABiNodes while parsing a text.
31   * 
32   * @version $Revision: 0b66106c7ff7 $
33   */
34  public class BiTreeCreationHelper {
35  
36      /** current position in tree. */
37      private IBiNode currentBiNode;
38      /** root of tree. */
39      private IBiNode root;
40      /** save positions of open tags. */
41      private final List<Integer> startPositions;
42  
43      /**
44       * create a new BiTreeHelper. get result (tree of ABiNodes) with getRoot()
45       */
46      public BiTreeCreationHelper() {
47          this.startPositions = new ArrayList<Integer>();
48      }
49  
50      /**
51       * get root of BiTree.
52       * 
53       * @return root of BiTree
54       */
55      public final IBiNode getRoot() {
56          return this.root;
57      }
58  
59      /**
60       * create and append a new BiNode at current position in BiTree.
61       * 
62       * @param totalOffset
63       *            of node in text
64       * @param childOffset
65       *            position of first child (length of open tag)
66       * @param namespaceURI
67       *            namespace
68       * @param eName
69       *            name of node
70       * @param attrs
71       *            attributes of node
72       * @throws SAXParseException 
73       *            if the element cannot be recognized by JEuclid.
74       */
75      public final void createBiNode(final int totalOffset,
76              final int childOffset, final String namespaceURI,
77              final String eName, final Attributes attrs) throws SAXParseException {
78  
79          if (JEuclidElementFactory.getJEuclidElementConstructor(namespaceURI,
80                  eName) == null) {
81              throw new NonIncrementalElementException(eName);
82          }
83          BiNode biNode;
84  
85          this.startPositions.add(totalOffset);
86  
87          // new root node
88          if (this.root == null) {
89              this.root = new BiNode(childOffset, namespaceURI, eName, attrs);
90              this.currentBiNode = this.root;
91          } else {
92              biNode = new BiNode(childOffset, namespaceURI, eName, attrs);
93  
94              // append child (only possible at start
95              if (this.currentBiNode.getType() == BiType.EMPTY) {
96                  this.currentBiNode.addSibling(biNode);
97              } else {
98                  // add child (default case)
99                  ((BiNode) this.currentBiNode).addChild(biNode);
100             }
101 
102             this.currentBiNode = biNode;
103         }
104     }
105 
106     /**
107      * close BiNode (set length of node).
108      * 
109      * @param length
110      *            length of node
111      */
112     public final void closeBiNode(final int length) {
113         BiNode parent;
114         final int last = this.startPositions.size() - 1;
115 
116         this.currentBiNode.setLength(length - this.startPositions.get(last));
117 
118         // move current position to parent
119         parent = this.currentBiNode.getParent();
120         if (parent != null) {
121             this.currentBiNode = parent;
122         }
123 
124         this.startPositions.remove(last);
125     }
126 
127     /**
128      * check if current position in BiTree allows a TextNode as child.
129      * 
130      * @return true if a TextNode is allowed
131      */
132     public final boolean allowNewTextNode() {
133         return ((BiNode) this.currentBiNode).getChild() == null;
134     }
135 
136     /**
137      * create a new TextNode at current position.
138      * 
139      * @param length
140      *            length of TextNode
141      * @param t
142      *            text of TextNode
143      */
144     public final void createTextNode(final int length, final String t) {
145         ((BiNode) this.currentBiNode).addChild(new TextNode(length, t));
146     }
147 
148     /**
149      * create a new EmptyNode at current position in BiTree.
150      * 
151      * @param length
152      *            length of EmtpyNode
153      */
154     public final void createEmtpyNode(final int length) {
155         // EmptyNode is new root
156         if (this.root == null) {
157             this.root = new EmptyNode(length);
158             this.currentBiNode = this.root;
159         } else {
160             ((BiNode) this.currentBiNode).addChild(new EmptyNode(length));
161         }
162     }
163 }