KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > jdom > DOMField


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * 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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.core.jdom;
12
13 import java.util.Enumeration JavaDoc;
14
15 import org.eclipse.jdt.core.IJavaElement;
16 import org.eclipse.jdt.core.IType;
17 import org.eclipse.jdt.core.compiler.CharOperation;
18 import org.eclipse.jdt.core.jdom.*;
19 import org.eclipse.jdt.internal.core.util.Messages;
20 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
21 import org.eclipse.jdt.internal.core.util.Util;
22 /**
23  * DOMField provides an implementation of IDOMField.
24  *
25  * @see IDOMField
26  * @see DOMNode
27  * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
28  * powerful, fine-grained DOM/AST API found in the
29  * org.eclipse.jdt.core.dom package.
30  */

31 class DOMField extends DOMMember implements IDOMField {
32     
33     /**
34      * Contains the type of the field when the type
35      * has been altered from the contents in the
36      * document, otherwise <code>null</code>.
37      */

38     protected String JavaDoc fType;
39
40     /**
41      * The original inclusive source range of the
42      * field's type in the document.
43      */

44     protected int[] fTypeRange;
45         
46     /**
47      * The contents of the initializer when the
48      * initializer has been altered from the
49      * original state in the document, otherwise
50      * <code>null</code>.
51      */

52     protected String JavaDoc fInitializer;
53
54     /**
55      * The original inclusive source range of the
56      * initializer in the document.
57      */

58     protected int[] fInitializerRange;
59
60 /**
61  * Constructs an empty field node.
62  */

63 DOMField() {
64     // Constructs an empty field node
65
}
66 /**
67  * Creates a new detailed FIELD document fragment on the given range of the document.
68  *
69  * @param document - the document containing this node's original contents
70  * @param sourceRange - a two element array of integers describing the
71  * entire inclusive source range of this node within its document.
72  * Contents start on and include the character at the first position.
73  * Contents end on and include the character at the last position.
74  * An array of -1's indicates this node's contents do not exist
75  * in the document.
76  * @param name - the identifier portion of the name of this field,
77  * corresponding to VariableDeclaratorId (JLS 8.3).
78  * @param nameRange - a two element array of integers describing the
79  * entire inclusive source range of this node's name within its document,
80  * including any array qualifiers that might follow the name.
81  * @param commentRange - a two element array describing the comments that precede
82  * the member declaration. The first matches the start of this node's
83  * sourceRange, and the second is the new-line or first non-whitespace
84  * character following the last comment. If no comments are present,
85  * this array contains two -1's.
86  * @param flags - an integer representing the modifiers for this member. The
87  * integer can be analyzed with org.eclipse.jdt.core.Flags
88  * @param modifierRange - a two element array describing the location of
89  * modifiers for this member within its source range. The first integer
90  * is the first character of the first modifier for this member, and
91  * the second integer is the last whitespace character preceeding the
92  * next part of this member declaration. If there are no modifiers present
93  * in this node's source code (that is, package default visibility), this array
94  * contains two -1's.
95  * @param typeRange - a two element array describing the location of the
96  * typeName in the document - the positions of the first and last characters
97  * of the typeName.
98  * @param type - the type of the field, in normalized form, as defined in
99  * Type in Field Declaration (JLS 8.3)
100  * @param hasInitializer - true if this field declaration includes an initializer,
101  * otherwise false
102  * @param initRange - a two element array describing the location of the initializer
103  * in the declaration. The first integer is the position of the character
104  * following the equals sign, and the position of the last character is the last
105  * in the initializer. If this field has no initializer, this array contains
106  * two -1's.
107  * @param isVariableDeclarator - true if the field is a seconday variable declarator
108  * for a previous field declaration.
109  */

110 DOMField(char[] document, int[] sourceRange, String JavaDoc name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, String JavaDoc type, boolean hasInitializer, int[] initRange, boolean isVariableDeclarator) {
111     super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange);
112
113     fType= type;
114     fTypeRange= typeRange;
115     setHasInitializer(hasInitializer);
116     fInitializerRange= initRange;
117     setIsVariableDeclarator(isVariableDeclarator);
118     setMask(MASK_DETAILED_SOURCE_INDEXES, true);
119
120 }
121 /**
122  * Creates a new simple FIELD document fragment on the given range of the document.
123  *
124  * @param document - the document containing this node's original contents
125  * @param sourceRange - a two element array of integers describing the
126  * entire inclusive source range of this node within its document.
127  * Contents start on and include the character at the first position.
128  * Contents end on and include the character at the last position.
129  * An array of -1's indicates this node's contents do not exist
130  * in the document.
131  * @param name - the identifier portion of the name of this field,
132  * corresponding to VariableDeclaratorId (JLS 8.3).
133  * @param nameRange - a two element array of integers describing the
134  * entire inclusive source range of this node's name within its document,
135  * including any array qualifiers that might follow the name.
136  * @param flags - an integer representing the modifiers for this member. The
137  * integer can be analyzed with org.eclipse.jdt.core.Flags
138  * @param type - the type of the field, in normalized form, as defined in
139  * Type in Field Declaration (JLS 8.3)
140  * @param isVariableDeclarator - true if the field is a seconday variable declarator
141  * for a previous field declaration.
142  */

143 DOMField(char[] document, int[] sourceRange, String JavaDoc name, int[] nameRange, int flags, String JavaDoc type, boolean isVariableDeclarator) {
144     this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, new int[] {-1, -1}, type, false, new int[] {-1, -1}, isVariableDeclarator);
145     setMask(MASK_DETAILED_SOURCE_INDEXES, false);
146 }
147 /**
148  * Appends this member's body contents to the given CharArrayBuffer.
149  * Body contents include the member body and any trailing whitespace.
150  *
151  * <p>A field does not have a body.
152  *
153  * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
154  */

155 protected void appendMemberBodyContents(CharArrayBuffer buffer) {
156     // nothing to do
157
}
158 /**
159  * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer)
160  */

161 protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {
162
163     if (isVariableDeclarator()) {
164         buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]);
165     } else {
166         buffer
167             .append(getTypeContents())
168             .append(fDocument, fTypeRange[1] + 1, fNameRange[0] - fTypeRange[1] - 1);
169     }
170     
171     buffer.append(getNameContents());
172     if (hasInitializer()) {
173         if (fInitializerRange[0] < 0) {
174             buffer
175                 .append('=')
176                 .append(fInitializer)
177                 .append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]);
178         } else {
179             buffer
180                 .append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1)
181                 .append(getInitializer())
182                 .append(fDocument, fInitializerRange[1] + 1, fSourceRange[1] - fInitializerRange[1]);
183         }
184     } else {
185         if (fInitializerRange[0] < 0) {
186             buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]);
187         } else {
188             buffer.append(fDocument, fInitializerRange[1] + 1, fSourceRange[1] - fInitializerRange[1]);
189         }
190     }
191
192 }
193 /**
194  * Appends this member's header contents to the given CharArrayBuffer.
195  * Header contents include any preceding comments and modifiers.
196  *
197  * <p>If this field is a secondary variable declarator, there is no header.
198  *
199  * @see DOMMember#appendMemberHeaderFragment(CharArrayBuffer)
200  */

201 protected void appendMemberHeaderFragment(CharArrayBuffer buffer) {
202
203     if (isVariableDeclarator()) {
204         return;
205     } else {
206         super.appendMemberHeaderFragment(buffer);
207     }
208
209 }
210 /**
211  * @see DOMMember#appendSimpleContents(CharArrayBuffer)
212  */

213 protected void appendSimpleContents(CharArrayBuffer buffer) {
214     // append eveything before my name
215
buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]);
216     // append my name
217
buffer.append(fName);
218     // append everything after my name
219
buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1] - fNameRange[1]);
220 }
221 /**
222  * Generates detailed source indexes for this node if possible.
223  *
224  * @exception DOMException if unable to generate detailed source indexes
225  * for this node
226  */

227 protected void becomeDetailed() throws DOMException {
228     if (!isDetailed()) {
229         if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
230             DOMNode first = getFirstFieldDeclaration();
231             DOMNode last = getLastFieldDeclaration();
232             DOMNode node= first;
233             String JavaDoc source= first.getContents();
234             while (node != last) {
235                 node= node.fNextNode;
236                 source+=node.getContents();
237             }
238             DOMBuilder builder = new DOMBuilder();
239             IDOMField[] details= builder.createFields(source.toCharArray());
240             if (details.length == 0) {
241                 throw new DOMException(Messages.dom_cannotDetail);
242             } else {
243                 node= this;
244                 for (int i= 0; i < details.length; i++) {
245                     node.shareContents((DOMNode)details[i]);
246                     node= node.fNextNode;
247                 }
248             }
249         } else {
250             super.becomeDetailed();
251         }
252
253     }
254 }
255 /**
256  * @see IDOMNode#clone()
257  */

258 public Object JavaDoc clone() {
259     if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
260         return getFactory().createField(new String JavaDoc(getSingleVariableDeclaratorContents()));
261     } else {
262         return super.clone();
263     }
264 }
265 /**
266  * Expands all variable declarators in this field declaration into
267  * stand-alone field declarations.
268  */

269 protected void expand() {
270     if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
271         Enumeration JavaDoc siblings= new SiblingEnumeration(getFirstFieldDeclaration());
272         DOMField field= (DOMField)siblings.nextElement();
273         DOMNode next= field.fNextNode;
274         while (siblings.hasMoreElements() && (next instanceof DOMField) && (((DOMField)next).isVariableDeclarator())) {
275             field.localizeContents();
276             if (field.fParent != null) {
277                 field.fParent.fragment();
278             }
279             field= (DOMField)siblings.nextElement();
280             next= field.fNextNode;
281         }
282         field.localizeContents();
283     }
284 }
285 /**
286  * @see DOMNode#getDetailedNode()
287  */

288 protected DOMNode getDetailedNode() {
289     if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
290         return (DOMNode)getFactory().createField(new String JavaDoc(getSingleVariableDeclaratorContents()));
291     } else {
292         return (DOMNode)getFactory().createField(getContents());
293     }
294 }
295 /**
296  * Returns the first field document fragment that defines
297  * the type for this variable declarator.
298  */

299 protected DOMField getFirstFieldDeclaration() {
300     if (isVariableDeclarator()) {
301         return ((DOMField)fPreviousNode).getFirstFieldDeclaration();
302     } else {
303         return this;
304     }
305 }
306 /**
307  * @see IDOMField#getInitializer()
308  */

309 public String JavaDoc getInitializer() {
310     becomeDetailed();
311     if (hasInitializer()) {
312         if (fInitializer != null) {
313             return fInitializer;
314         } else {
315             return new String JavaDoc(fDocument, fInitializerRange[0], fInitializerRange[1] + 1 - fInitializerRange[0]);
316         }
317     } else {
318         return null;
319     }
320 }
321 /**
322  * @see IDOMNode#getJavaElement
323  */

324 public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException JavaDoc {
325     if (parent.getElementType() == IJavaElement.TYPE) {
326         return ((IType)parent).getField(getName());
327     } else {
328         throw new IllegalArgumentException JavaDoc(Messages.element_illegalParent);
329     }
330 }
331 /**
332  * Returns the last field document fragment in this muli-declarator statement.
333  */

334 protected DOMField getLastFieldDeclaration() {
335     DOMField field = this;
336     while (field.isVariableDeclarator() || field.hasMultipleVariableDeclarators()) {
337         if (field.fNextNode instanceof DOMField && ((DOMField)field.fNextNode).isVariableDeclarator()) {
338             field= (DOMField)field.fNextNode;
339         } else {
340             break;
341         }
342     }
343     return field;
344 }
345 /**
346  * @see DOMMember#getMemberDeclarationStartPosition()
347  */

348 protected int getMemberDeclarationStartPosition() {
349     return fTypeRange[0];
350 }
351 /**
352  * @see IDOMNode#getNodeType()
353  */

354 public int getNodeType() {
355     return IDOMNode.FIELD;
356 }
357 /**
358  * Returns a String representing this field declaration as a field
359  * declaration with one variable declarator.
360  */

361 protected char[] getSingleVariableDeclaratorContents() {
362
363
364     CharArrayBuffer buffer= new CharArrayBuffer();
365     DOMField first= getFirstFieldDeclaration();
366     if (first.isDetailed()) {
367         first.appendMemberHeaderFragment(buffer);
368         buffer.append(getType());
369         if (isVariableDeclarator()) {
370             buffer.append(' ');
371         } else {
372             buffer.append(fDocument, fTypeRange[1] + 1, fNameRange[0] - fTypeRange[1] - 1);
373         }
374     } else {
375         buffer.append(first.fDocument, first.fSourceRange[0], first.fNameRange[0] - first.fSourceRange[0]);
376     }
377     
378     buffer.append(getName());
379     if (hasInitializer()) {
380         if (fInitializerRange[0] < 0) {
381             buffer
382                 .append('=')
383                 .append(fInitializer)
384                 .append(';')
385                 .append(Util.getLineSeparator(buffer.toString(), null));
386         } else {
387             buffer
388                 .append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1)
389                 .append(getInitializer())
390                 .append(';')
391                 .append(Util.getLineSeparator(buffer.toString(), null));
392         }
393     } else {
394         buffer.append(';').append(Util.getLineSeparator(buffer.toString(), null));
395     }
396     return buffer.getContents();
397 }
398 /**
399  * @see IDOMField#getType()
400  */

401 public String JavaDoc getType() {
402     return fType;
403 }
404 /**
405  * Returns the souce code to be used for this
406  * field's type.
407  */

408 protected char[] getTypeContents() {
409     if (isTypeAltered()) {
410         return fType.toCharArray();
411     } else {
412         return CharOperation.subarray(fDocument, fTypeRange[0], fTypeRange[1] + 1);
413     }
414 }
415 /**
416  * Returns true if this field has an initializer expression,
417  * otherwise false.
418  */

419 protected boolean hasInitializer() {
420     return getMask(MASK_FIELD_HAS_INITIALIZER);
421 }
422 /**
423  * Returns true is this field declarations has more than one
424  * variable declarator, otherwise false;
425  */

426 protected boolean hasMultipleVariableDeclarators() {
427     return fNextNode != null && (fNextNode instanceof DOMField) &&
428         ((DOMField)fNextNode).isVariableDeclarator();
429 }
430 /**
431  * Inserts the given un-parented node as a sibling of this node, immediately before
432  * this node. Once inserted, the sibling is only dependent on this document fragment.
433  *
434  * <p>When a sibling is inserted before a variable declarator, it must first
435  * be expanded.
436  *
437  * @see IDOMNode#insertSibling(IDOMNode)
438  */

439 public void insertSibling(IDOMNode sibling) throws IllegalArgumentException JavaDoc, DOMException {
440     if (isVariableDeclarator()) {
441         expand();
442     }
443     super.insertSibling(sibling);
444 }
445 /**
446  * Returns true if this field's type has been altered
447  * from the original document contents.
448  */

449 protected boolean isTypeAltered() {
450     return getMask(MASK_FIELD_TYPE_ALTERED);
451 }
452 /**
453  * Returns true if this field is declared as a secondary variable
454  * declarator for a previous field declaration.
455  */

456 protected boolean isVariableDeclarator() {
457     return getMask(MASK_FIELD_IS_VARIABLE_DECLARATOR);
458 }
459 /**
460  * @see DOMNode
461  */

462 protected DOMNode newDOMNode() {
463     return new DOMField();
464 }
465 /**
466  * Normalizes this <code>DOMNode</code>'s end position.
467  */

468 void normalizeEndPosition(ILineStartFinder finder, DOMNode next) {
469     if (next == null) {
470         // this node's end position includes all of the characters up
471
// to the end of the enclosing node
472
DOMNode parent = (DOMNode) getParent();
473         if (parent == null || parent instanceof DOMCompilationUnit) {
474             setSourceRangeEnd(fDocument.length - 1);
475         } else {
476             // parent is a type
477
int temp = ((DOMType)parent).getCloseBodyPosition() - 1;
478             setSourceRangeEnd(temp);
479             fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
480         }
481     } else {
482         // this node's end position is just before the start of the next node
483
// unless the next node is a field that is declared along with this one
484
int temp = next.getStartPosition() - 1;
485         fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
486         
487         next.normalizeStartPosition(getEndPosition(), finder);
488         if (next instanceof DOMField) {
489             DOMField field = (DOMField) next;
490             if (field.isVariableDeclarator() && fTypeRange[0] == field.fTypeRange[0])
491                 return;
492         }
493         setSourceRangeEnd(next.getStartPosition() - 1);
494     }
495 }
496 /**
497  * Normalizes this <code>DOMNode</code>'s start position.
498  */

499 void normalizeStartPosition(int endPosition, ILineStartFinder finder) {
500     if (isVariableDeclarator()) {
501         // start position is end of last element
502
setStartPosition(fPreviousNode.getEndPosition() + 1);
503     } else {
504         super.normalizeStartPosition(endPosition, finder);
505     }
506 }
507 /**
508  * Offsets all the source indexes in this node by the given amount.
509  */

510 protected void offset(int offset) {
511     super.offset(offset);
512     offsetRange(fInitializerRange, offset);
513     offsetRange(fTypeRange, offset);
514 }
515 /**
516  * Separates this node from its parent and siblings, maintaining any ties that
517  * this node has to the underlying document fragment.
518  *
519  * <p>When a field with multiple declarators is removed, its declaration
520  * must first be expanded.
521  *
522  * @see IDOMNode#remove()
523  */

524 public void remove() {
525     expand();
526     super.remove();
527 }
528 /**
529  * @see IDOMMember#setComment(String)
530  */

531 public void setComment(String JavaDoc comment) {
532     expand();
533     super.setComment(comment);
534 }
535 /**
536  * @see IDOMMember#setFlags(int)
537  */

538 public void setFlags(int flags) {
539     expand();
540     super.setFlags(flags);
541 }
542 /**
543  * Sets the state of this field declaration as having
544  * an initializer expression.
545  */

546 protected void setHasInitializer(boolean hasInitializer) {
547     setMask(MASK_FIELD_HAS_INITIALIZER, hasInitializer);
548 }
549 /**
550  * @see IDOMField#setInitializer(String)
551  */

552 public void setInitializer(String JavaDoc initializer) {
553     becomeDetailed();
554     fragment();
555     setHasInitializer(initializer != null);
556     fInitializer= initializer;
557 }
558 /**
559  * Sets the initializer range.
560  */

561 void setInitializerRange(int start, int end) {
562     fInitializerRange[0] = start;
563     fInitializerRange[1] = end;
564 }
565 /**
566  * Sets the state of this field declaration as being a
567  * secondary variable declarator for a previous field
568  * declaration.
569  */

570 protected void setIsVariableDeclarator(boolean isVariableDeclarator) {
571     setMask(MASK_FIELD_IS_VARIABLE_DECLARATOR, isVariableDeclarator);
572 }
573 /**
574  * @see IDOMField#setName(String)
575  */

576 public void setName(String JavaDoc name) throws IllegalArgumentException JavaDoc {
577     if (name == null) {
578         throw new IllegalArgumentException JavaDoc(Messages.element_nullName);
579     } else {
580         super.setName(name);
581         setTypeAltered(true);
582     }
583 }
584 /**
585  * @see IDOMField#setType(String)
586  */

587 public void setType(String JavaDoc typeName) throws IllegalArgumentException JavaDoc {
588     if (typeName == null) {
589         throw new IllegalArgumentException JavaDoc(Messages.element_nullType);
590     }
591     becomeDetailed();
592     expand();
593     fragment();
594     setTypeAltered(true);
595     setNameAltered(true);
596     fType= typeName;
597 }
598 /**
599  * Sets the state of this field declaration as having
600  * the field type altered from the original document.
601  */

602 protected void setTypeAltered(boolean typeAltered) {
603     setMask(MASK_FIELD_TYPE_ALTERED, typeAltered);
604 }
605 /**
606  * @see DOMNode#shareContents(DOMNode)
607  */

608 protected void shareContents(DOMNode node) {
609     super.shareContents(node);
610     DOMField field= (DOMField)node;
611     fInitializer= field.fInitializer;
612     fInitializerRange= rangeCopy(field.fInitializerRange);
613     fType= field.fType;
614     fTypeRange= rangeCopy(field.fTypeRange);
615 }
616 /**
617  * @see IDOMNode#toString()
618  */

619 public String JavaDoc toString() {
620     return "FIELD: " + getName(); //$NON-NLS-1$
621
}
622 }
623
Popular Tags