001 /*
002 * Copyright 2009 - 2010 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id $ */
018
019 package net.sourceforge.jeuclid.biparser;
020
021 import org.w3c.dom.Document;
022 import org.w3c.dom.Node;
023
024 /**
025 * this class is used to store specific information about a empty node. the node
026 * cannot have children, but a sibling
027 *
028 * @version $Revision: 0b66106c7ff7 $
029 */
030 public final class EmptyNode extends AbstractBiNode {
031
032 /**
033 * create a new EmptyNode.
034 *
035 * @param length
036 * of EmptyNode
037 */
038 public EmptyNode(final int length) {
039 this.setLength(length);
040 }
041
042 /**
043 * get the type of node.
044 *
045 * @return EMPTY
046 */
047 public BiType getType() {
048 return BiType.EMPTY;
049 }
050
051 /**
052 * insert characters in EmptyNode, reparse if characters contain '<' or '>'.
053 * else change length of EmptyNode
054 * {@inheritDoc}
055 */
056 public void insert(final BiTree biTree, final int offset, final int length,
057 final int totalOffset) throws ReparseException,
058 NonIncrementalElementException {
059 int position;
060 String insert;
061
062 // System.out.println("insert " + toString() + " offset=" +
063 // offset + " length=" + length);
064
065 // start position in this node
066 if (offset <= this.getLength()) {
067
068 position = totalOffset + offset;
069 insert = biTree.getText().substring(position, position + length);
070
071 if (insert.contains("<") || insert.contains(">")) {
072 // reparsing
073 throw new ReparseException();
074 }
075
076 this.changeLengthRec(length);
077
078 } else {
079 // start position outside this node
080 this.forwardToSibling(true, biTree, offset - this.getLength(),
081 length, totalOffset + this.getLength());
082 }
083 }
084
085 /**
086 * remove characters from EmptyNode, reparse if length gets 0. {@inheritDoc}
087 */
088 public void remove(final BiTree biTree, final int offset, final int length,
089 final int totalOffset) throws ReparseException,
090 NonIncrementalElementException {
091 // System.out.println("remove " + toString() + " offset=" +
092 // offset + " length=" + length);
093
094 // start position in this node
095 if (offset <= this.getLength()) {
096
097 if (offset == 0 && length >= this.getLength()) {
098 // remove this node
099 throw new ReparseException();
100
101 } else {
102 // change length
103 // end position in this node
104 if (offset + length <= this.getLength()) {
105 this.changeLengthRec(-length);
106
107 } else {
108 // end position outside this node
109 this.changeLengthRec(offset - this.getLength());
110
111 // forward remainder to sibling
112 this.forwardToSibling(false, biTree, 0, offset + length
113 - this.getLength(), totalOffset + this.getLength());
114 }
115 }
116 } else {
117 // start position outside this node
118 this.forwardToSibling(false, biTree, offset - this.getLength(),
119 length, totalOffset + this.getLength());
120 }
121 }
122
123 /**
124 * don't create a DOM-tree from EmptyNode (EmptyNode has no DOM node).
125 *
126 * @param doc
127 * Document to create DOM-tree
128 * @return null
129 */
130 public Node createDOMSubtree(final Document doc) {
131 return null;
132 }
133
134 /** {@inheritDoc} */
135 @Override
136 public TextPosition searchNode(final Node node, final int totalOffset) {
137 // forward to sibling
138 if (this.getSibling() != null) {
139 return this.getSibling().searchNode(node,
140 totalOffset + this.getLength());
141 }
142
143 return null;
144 }
145
146 @Override
147 public String toString() {
148 final StringBuffer sb = new StringBuffer(32);
149
150 sb.append("[EMTPY length: ");
151 sb.append(this.getLength());
152 sb.append(']');
153
154 return sb.toString();
155 }
156
157 /** {@inheritDoc} */
158 public String toString(final int level) {
159 final StringBuffer sb = new StringBuffer(32);
160 final String nl = System.getProperty("line.separator");
161
162 sb.append(this.formatLength());
163 sb.append(':');
164 for (int i = 0; i <= level; i++) {
165 sb.append(' ');
166 }
167
168 sb.append("EMTPY");
169
170 if (this.getSibling() != null) {
171 sb.append(nl);
172 sb.append(this.getSibling().toString(level));
173 }
174
175 return sb.toString();
176 }
177 }