blob: bea5c7a711194f35c8d3e797ee11b494f6806e8c [file] [log] [blame]
david_williamscfdb2cd2004-11-11 08:37:49 +00001/*******************************************************************************
amywuecebb042007-04-10 20:07:35 +00002 * Copyright (c) 2001, 2005 IBM Corporation and others.
david_williamscfdb2cd2004-11-11 08:37:49 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
amywuecebb042007-04-10 20:07:35 +00007 *
david_williamscfdb2cd2004-11-11 08:37:49 +00008 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Jens Lukowski/Innoopract - initial renaming/restructuring
11 *
12 *******************************************************************************/
nitindd6e591d2005-03-14 22:21:57 +000013package org.eclipse.wst.dtd.core.internal;
david_williamscfdb2cd2004-11-11 08:37:49 +000014
15import java.util.ArrayList;
16import java.util.Collections;
17import java.util.List;
18
19import org.eclipse.swt.graphics.Image;
nitindd6e591d2005-03-14 22:21:57 +000020import org.eclipse.wst.dtd.core.internal.document.DTDModelImpl;
21import org.eclipse.wst.dtd.core.internal.parser.DTDRegionTypes;
david_williamscfdb2cd2004-11-11 08:37:49 +000022import org.eclipse.wst.dtd.core.internal.text.RegionIterator;
david_williamsc9113882005-04-09 03:19:38 +000023import org.eclipse.wst.sse.core.internal.model.FactoryRegistry;
david_williams4ad020f2005-04-18 08:00:30 +000024import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
25import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
26import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
david_williamscfdb2cd2004-11-11 08:37:49 +000027import org.eclipse.wst.sse.core.internal.text.TextRegionListImpl;
david_williamsc16014c2004-11-11 17:11:35 +000028import org.eclipse.wst.xml.core.internal.document.NodeContainer;
nitindd6e591d2005-03-14 22:21:57 +000029import org.w3c.dom.Node;
david_williamscfdb2cd2004-11-11 08:37:49 +000030
31
32public abstract class DTDNode extends NodeContainer implements IndexedRegion {
33
34 // these are characteroffsets
35 protected DTDFile dtdFile;
36
37 // flat node that contains this node
38 protected IStructuredDocumentRegion flatNode;
39
40 protected TextRegionListImpl regions = new TextRegionListImpl();
41
42 protected TextRegionListImpl whitespace = new TextRegionListImpl();
43
44 public DTDNode(DTDFile dtdFile, IStructuredDocumentRegion flatNode) {
45 this.dtdFile = dtdFile;
46 this.flatNode = flatNode;
47 }
48
49 public void addRegion(ITextRegion region) {
50 /*
51 * if (startRegion == null) { startRegion = region; } endRegion =
52 * region;
53 */
54 regions.add(region);
55 }
56
57 public void addWhitespaceRegion(ITextRegion region) {
58 whitespace.add(region);
59 }
60
david_williamscfdb2cd2004-11-11 08:37:49 +000061 public void beginRecording(Object requestor, String label) {
62 getDTDFile().getDTDModel().beginRecording(requestor, label);
63 }
64
nitindd6e591d2005-03-14 22:21:57 +000065 public Node cloneNode(boolean deepest) {
david_williamscfdb2cd2004-11-11 08:37:49 +000066 return null;
67 }
68
69 public boolean contains(int testPosition) {
70 return containsRange(testPosition, testPosition);
71 }
72
73 public boolean containsRange(int start, int end) {
74 return getStartOffset() <= start && end <= getEndOffset();
75 }
76
77 public void delete(DTDNode child) {
david_williams38046012005-04-08 19:04:29 +000078 beginRecording(this, DTDCoreMessages._UI_LABEL_DTD_NODE_DELETE); //$NON-NLS-1$
david_williamscfdb2cd2004-11-11 08:37:49 +000079 delete(this, child);
80 endRecording(this);
81 }
82
83 public void delete(Object requestor, DTDNode child) {
84 replaceText(requestor, child.getStartOffset(), child.getFullNodeLength(), ""); //$NON-NLS-1$
85 }
86
87 public void endRecording(Object requestor) {
88 getDTDFile().getDTDModel().endRecording(requestor);
89 }
90
91 public Object[] getChildren() {
92 return getChildrenList().toArray();
93 }
94
95 public List getChildrenList() {
nitindd6e591d2005-03-14 22:21:57 +000096 Node child = getFirstChild();
david_williamscfdb2cd2004-11-11 08:37:49 +000097 if (child != null) {
98 List children = new ArrayList();
99 for (; child != null; child = child.getNextSibling()) {
100 children.add(child);
101 }
102 return children;
nitindd6e591d2005-03-14 22:21:57 +0000103 }
104 else {
david_williamscfdb2cd2004-11-11 08:37:49 +0000105 return Collections.EMPTY_LIST;
106 }
107 }
108
109 public DTDNode getDeepestNode(int offset) {
110 if (contains(offset)) {
111 // now see if a child contains this offset
112 Object[] children = getChildren();
113 for (int i = 0; i < children.length; i++) {
114 DTDNode child = (DTDNode) children[i];
115 DTDNode deepest = child.getDeepestNode(offset);
116 if (deepest != null) {
117 return deepest;
118 }
119 } // end of for ()
120 return this;
121 }
122 return null;
123 }
124
125 public DTDNode getDeepestNode(int start, int end) {
126 if (containsRange(start, end)) {
127 // now see if a child contains this offset
128 Object[] children = getChildren();
129 for (int i = 0; i < children.length; i++) {
130 DTDNode child = (DTDNode) children[i];
131 DTDNode deepest = child.getDeepestNode(start, end);
132 if (deepest != null) {
133 return deepest;
134 }
135 } // end of for ()
136 return this;
137 }
138 return null;
139 }
140
141 public DTDFile getDTDFile() {
142 return dtdFile;
143 }
144
145 public int getEndOffset() {
david_williams29d69682004-11-20 17:49:29 +0000146 return getStructuredDTDDocumentRegion().getEndOffset(getEndRegion());
david_williamscfdb2cd2004-11-11 08:37:49 +0000147 }
148
149 public ITextRegion getEndRegion() {
david_williams29d69682004-11-20 17:49:29 +0000150 return regions.get(regions.size() - 1);// endRegion;
david_williamscfdb2cd2004-11-11 08:37:49 +0000151 }
152
153 /**
154 */
david_williams68bf9b32005-03-26 04:29:10 +0000155 public FactoryRegistry getFactoryRegistry() {
david_williamscfdb2cd2004-11-11 08:37:49 +0000156 DTDModelImpl model = dtdFile.getDTDModel();
157 if (model != null) {
david_williams68bf9b32005-03-26 04:29:10 +0000158 FactoryRegistry reg = model.getFactoryRegistry();
david_williamscfdb2cd2004-11-11 08:37:49 +0000159 if (reg != null)
160 return reg;
161 }
162 return null;
163 }
164
165 public int getFullNodeLength() {
166 return getWhitespaceEndOffset() - getStartOffset();
167 }
168
169 public String getFullNodeText() {
170 String text = getNodeText();
171 if (whitespace.size() > 0) {
172 RegionIterator iter = new RegionIterator(whitespace);
173 while (iter.hasNext()) {
174 ITextRegion region = iter.next();
david_williams29d69682004-11-20 17:49:29 +0000175 text += getStructuredDTDDocumentRegion().getText(region);
david_williamscfdb2cd2004-11-11 08:37:49 +0000176 }
177 }
178 return text;
179 }
180
181 abstract public Image getImage();
182
183 public String getName() {
184 ITextRegion region = getNameRegion();
185 if (region != null) {
david_williams29d69682004-11-20 17:49:29 +0000186 return getStructuredDTDDocumentRegion().getText(region);
david_williamscfdb2cd2004-11-11 08:37:49 +0000187 }
188 return ""; //$NON-NLS-1$
189 }
190
191 public ITextRegion getNameRegion() {
192 RegionIterator iter = iterator();
193 while (iter.hasNext()) {
194 ITextRegion region = iter.next();
195 if (region.getType() == DTDRegionTypes.NAME) {
196 return region;
197 }
198 }
199 return null;
200 }
201
202 // return the first token containing the specified token type
203 public ITextRegion getNextRegion(RegionIterator iter, String type) {
204 while (iter.hasNext()) {
205 ITextRegion region = iter.next();
206 if (region.getType().equals(type)) {
207 return region;
208 }
209 }
210 return null;
211 }
212
213 public int getNodeLength() {
214 return getEndOffset() - getStartOffset();
215 }
216
217 public String getNodeName() {
218 return getName();
219 }
220
221 public String getNodeText() {
222 StringBuffer sb = new StringBuffer();
223
224 RegionIterator iter = iterator();
225 while (iter.hasNext()) {
226 ITextRegion region = iter.next();
david_williams29d69682004-11-20 17:49:29 +0000227 sb.append(getStructuredDTDDocumentRegion().getText(region));
david_williamscfdb2cd2004-11-11 08:37:49 +0000228 }
229 return sb.toString();
230 }
231
232 public short getNodeType() {
233 return -1;
234 }
235
236 public int getStartOffset() {
david_williams29d69682004-11-20 17:49:29 +0000237 return getStructuredDTDDocumentRegion().getStartOffset(getStartRegion());
david_williamscfdb2cd2004-11-11 08:37:49 +0000238 }
239
david_williams29d69682004-11-20 17:49:29 +0000240 // private Region startRegion,endRegion;
david_williamscfdb2cd2004-11-11 08:37:49 +0000241 public ITextRegion getStartRegion() {
242 return regions.get(0);
david_williams29d69682004-11-20 17:49:29 +0000243 // return startRegion;
david_williamscfdb2cd2004-11-11 08:37:49 +0000244 }
245
246 /**
247 * Get the value of flatNode.
248 *
249 * @return value of flatNode.
david_williams29d69682004-11-20 17:49:29 +0000250 *
251 * ISSUE:named changed not to be confused with default access protected
252 * super class method, but should re-think if this is correct technique.
253 * Perhaps getFirstRegion?
david_williamscfdb2cd2004-11-11 08:37:49 +0000254 */
david_williams29d69682004-11-20 17:49:29 +0000255 public IStructuredDocumentRegion getStructuredDTDDocumentRegion() {
david_williamscfdb2cd2004-11-11 08:37:49 +0000256 return flatNode;
257 }
258
259 // return end offset including whitespace
260 // or just the end offset if there is no whitespace
261 public int getWhitespaceEndOffset() {
262 if (whitespace.size() > 0) {
263 ITextRegion region = whitespace.get(whitespace.size() - 1);
david_williams29d69682004-11-20 17:49:29 +0000264 return getStructuredDTDDocumentRegion().getEndOffset(region);
david_williamscfdb2cd2004-11-11 08:37:49 +0000265 }
266
267 return getEndOffset();
268 }
269
270 public boolean hasTrailingWhitespace() {
271 return whitespace.size() > 0;
272 }
273
274 public RegionIterator iterator() {
david_williams29d69682004-11-20 17:49:29 +0000275 // System.out.println("create region iter " + this.getClass() + " with
david_williamscfdb2cd2004-11-11 08:37:49 +0000276 // start , end = " + getStartOffset() + ", " +getEndOffset());
277 return new RegionIterator(regions);
278 }
279
280 public void replaceText(Object requestor, int start, int length, String newText) {
281 getDTDFile().getStructuredDocument().replaceText(requestor, start, length, newText);
282 }
283
284 public void resolveRegions() {
285 }
286
287 public void setName(Object requestor, String name) {
288 if (!getName().equals(name)) {
289 ITextRegion nameRegion = getNameRegion();
290 if (nameRegion != null) {
david_williams29d69682004-11-20 17:49:29 +0000291 // nameToken.updateText(name);
david_williamscfdb2cd2004-11-11 08:37:49 +0000292 getDTDFile().getDTDModel().getReferenceUpdater().nameAboutToChange(requestor, this, name);
david_williams29d69682004-11-20 17:49:29 +0000293 replaceText(requestor, getStructuredDTDDocumentRegion().getStartOffset(nameRegion), nameRegion.getLength(), name);
david_williamscfdb2cd2004-11-11 08:37:49 +0000294 }
295 }
296 }
297
298 public void setName(String name) {
david_williams38046012005-04-08 19:04:29 +0000299 beginRecording(this, DTDCoreMessages._UI_LABEL_DTD_NODE_NAME_CHG); //$NON-NLS-1$
david_williamscfdb2cd2004-11-11 08:37:49 +0000300 setName(this, name);
301 endRecording(this);
302 }
303
304 /**
305 * Set the value of flatNode.
306 *
307 * @param v
david_williams29d69682004-11-20 17:49:29 +0000308 * Value to assign to flatNode. ISSUE:named changed not to be
309 * confused with default access protected super class method,
310 * but should re-think if this is correct technique
david_williamscfdb2cd2004-11-11 08:37:49 +0000311 */
david_williams29d69682004-11-20 17:49:29 +0000312 void setStructuredDTDDocumentRegion(IStructuredDocumentRegion v) {
david_williamscfdb2cd2004-11-11 08:37:49 +0000313 this.flatNode = v;
314 }
315
316 // skips past next name token in the iterator
317 protected void skipPastName(RegionIterator iter) {
318 while (iter.hasNext()) {
319 ITextRegion currentRegion = iter.next();
320 if (currentRegion.getType() == DTDRegionTypes.NAME) {
321 break;
322 }
323 }
324 }
325
326 public boolean supports(java.lang.String feature, java.lang.String version) {
327 return false;
328 }
329
330}