KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > rewrite > ListRewrite


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 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.core.dom.rewrite;
12
13 import java.util.Collections JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.jdt.core.dom.ASTNode;
17 import org.eclipse.jdt.core.dom.Block;
18 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
19 import org.eclipse.jdt.core.dom.FieldDeclaration;
20 import org.eclipse.jdt.core.dom.Statement;
21 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
22 import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
23 import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
24 import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
25 import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
26 import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
27 import org.eclipse.text.edits.TextEditGroup;
28
29 /**
30  * For describing manipulations to a child list property of an AST node.
31  * <p>
32  * This class is not intended to be subclassed.
33  * </p>
34  * @see ASTRewrite#getListRewrite(ASTNode, ChildListPropertyDescriptor)
35  * @since 3.0
36  */

37 public final class ListRewrite {
38     
39     private ASTNode parent;
40     private StructuralPropertyDescriptor childProperty;
41     private ASTRewrite rewriter;
42
43
44     /* package*/ ListRewrite(ASTRewrite rewriter, ASTNode parent, StructuralPropertyDescriptor childProperty) {
45         this.rewriter= rewriter;
46         this.parent= parent;
47         this.childProperty= childProperty;
48     }
49     
50     private RewriteEventStore getRewriteStore() {
51         return this.rewriter.getRewriteEventStore();
52     }
53     
54     private ListRewriteEvent getEvent() {
55         return getRewriteStore().getListEvent(this.parent, this.childProperty, true);
56     }
57     
58     /**
59      * Returns the parent of the list for which this list rewriter was created.
60
61      * @return the node that contains the list for which this list rewriter was created
62      * @see #getLocationInParent()
63      * @since 3.1
64      */

65     public ASTNode getParent() {
66         return this.parent;
67     }
68     
69     /**
70      * Returns the property of the parent node for which this list rewriter was created.
71      *
72      * @return the property of the parent node for which this list rewriter was created
73      * @see #getParent()
74      * @since 3.1
75      */

76     public StructuralPropertyDescriptor getLocationInParent() {
77         return this.childProperty;
78     }
79     
80     /**
81      * Removes the given node from its parent's list property in the rewriter.
82      * The node must be contained in the list.
83      * The AST itself is not actually modified in any way; rather, the rewriter
84      * just records a note that this node has been removed from this list.
85      *
86      * @param node the node being removed
87      * @param editGroup the edit group in which to collect the corresponding
88      * text edits, or <code>null</code> if ungrouped
89      * @throws IllegalArgumentException if the node is null, or if the node is not
90      * part of this rewriter's AST, or if the described modification is invalid
91      * (not a member of this node's original list)
92      */

93     public void remove(ASTNode node, TextEditGroup editGroup) {
94         if (node == null) {
95             throw new IllegalArgumentException JavaDoc();
96         }
97         RewriteEvent event= getEvent().removeEntry(node);
98         if (editGroup != null) {
99             getRewriteStore().setEventEditGroup(event, editGroup);
100         }
101     }
102     
103     /**
104      * Returns the ASTRewrite instance from which this ListRewriter has been created from.
105      * @return the parent AST Rewriter instance.
106      * @since 3.1
107      */

108     public ASTRewrite getASTRewrite() {
109         return this.rewriter;
110     }
111     
112
113     /**
114      * Replaces the given node from its parent's list property in the rewriter.
115      * The node must be contained in the list.
116      * The replacement node must either be brand new (not part of the original AST)
117      * or a placeholder node (for example, one created by
118      * {@link ASTRewrite#createCopyTarget(ASTNode)},
119      * {@link ASTRewrite#createMoveTarget(ASTNode)},
120      * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
121      * is not actually modified in any way; rather, the rewriter just records
122      * a note that this node has been replaced in this list.
123      *
124      * @param node the node being replaced
125      * @param replacement the replacement node, or <code>null</code> if no
126      * replacement
127      * @param editGroup the edit group in which to collect the corresponding
128      * text edits, or <code>null</code> if ungrouped
129      * @throws IllegalArgumentException if the node is null, or if the node is not part
130      * of this rewriter's AST, or if the replacement node is not a new node (or
131      * placeholder), or if the described modification is otherwise invalid
132      * (not a member of this node's original list)
133      */

134     public void replace(ASTNode node, ASTNode replacement, TextEditGroup editGroup) {
135         if (node == null) {
136             throw new IllegalArgumentException JavaDoc();
137         }
138         RewriteEvent event= getEvent().replaceEntry(node, replacement);
139         if (editGroup != null) {
140             getRewriteStore().setEventEditGroup(event, editGroup);
141         }
142     }
143
144     /**
145      * Inserts the given node into the list after the given element.
146      * The existing node must be in the list, either as an original or as a new
147      * node that has been inserted.
148      * The inserted node must either be brand new (not part of the original AST)
149      * or a placeholder node (for example, one created by
150      * {@link ASTRewrite#createCopyTarget(ASTNode)},
151      * {@link ASTRewrite#createMoveTarget(ASTNode)},
152      * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
153      * is not actually modified in any way; rather, the rewriter just records
154      * a note that this node has been inserted into the list.
155      *
156      * @param node the node to insert
157      * @param element the element after which the given node is to be inserted
158      * @param editGroup the edit group in which to collect the corresponding
159      * text edits, or <code>null</code> if ungrouped
160      * @throws IllegalArgumentException if the node or element is null,
161      * or if the node is not part of this rewriter's AST, or if the inserted node
162      * is not a new node (or placeholder), or if <code>element</code> is not a member
163      * of the list (original or new), or if the described modification is
164      * otherwise invalid
165      */

166     public void insertAfter(ASTNode node, ASTNode element, TextEditGroup editGroup) {
167         if (node == null || element == null) {
168             throw new IllegalArgumentException JavaDoc();
169         }
170         int index= getEvent().getIndex(element, ListRewriteEvent.BOTH);
171         if (index == -1) {
172             throw new IllegalArgumentException JavaDoc("Node does not exist"); //$NON-NLS-1$
173
}
174         internalInsertAt(node, index + 1, true, editGroup);
175     }
176     
177     /**
178      * Inserts the given node into the list before the given element.
179      * The existing node must be in the list, either as an original or as a new
180      * node that has been inserted.
181      * The inserted node must either be brand new (not part of the original AST)
182      * or a placeholder node (for example, one created by
183      * {@link ASTRewrite#createCopyTarget(ASTNode)},
184      * {@link ASTRewrite#createMoveTarget(ASTNode)},
185      * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
186      * is not actually modified in any way; rather, the rewriter just records
187      * a note that this node has been inserted into the list.
188      *
189      * @param node the node to insert
190      * @param element the element before which the given node is to be inserted
191      * @param editGroup the edit group in which to collect the corresponding
192      * text edits, or <code>null</code> if ungrouped
193      * @throws IllegalArgumentException if the node or element is null,
194      * or if the node is not part of this rewriter's AST, or if the inserted node
195      * is not a new node (or placeholder), or if <code>element</code> is not a member
196      * of the list (original or new), or if the described modification is
197      * otherwise invalid
198      */

199     public void insertBefore(ASTNode node, ASTNode element, TextEditGroup editGroup) {
200         if (node == null || element == null) {
201             throw new IllegalArgumentException JavaDoc();
202         }
203         int index= getEvent().getIndex(element, ListRewriteEvent.BOTH);
204         if (index == -1) {
205             throw new IllegalArgumentException JavaDoc("Node does not exist"); //$NON-NLS-1$
206
}
207         internalInsertAt(node, index, false, editGroup);
208     }
209     
210     /**
211      * Inserts the given node into the list at the start of the list.
212      * Equivalent to <code>insertAt(node, 0, editGroup)</code>.
213      *
214      * @param node the node to insert
215      * @param editGroup the edit group in which to collect the corresponding
216      * text edits, or <code>null</code> if ungrouped
217      * @throws IllegalArgumentException if the node is null, or if the node is not part
218      * of this rewriter's AST, or if the inserted node is not a new node (or
219      * placeholder), or if the described modification is otherwise invalid
220      * (not a member of this node's original list)
221      * @see #insertAt(ASTNode, int, TextEditGroup)
222      */

223     public void insertFirst(ASTNode node, TextEditGroup editGroup) {
224         if (node == null) {
225             throw new IllegalArgumentException JavaDoc();
226         }
227         internalInsertAt(node, 0, false, editGroup);
228     }
229     
230     /**
231      * Inserts the given node into the list at the end of the list.
232      * Equivalent to <code>insertAt(node, -1, editGroup)</code>.
233      *
234      * @param node the node to insert
235      * @param editGroup the edit group in which to collect the corresponding
236      * text edits, or <code>null</code> if ungrouped
237      * @throws IllegalArgumentException if the node is null, or if the node is not part
238      * of this rewriter's AST, or if the inserted node is not a new node (or
239      * placeholder), or if the described modification is otherwise invalid
240      * (not a member of this node's original list)
241      * @see #insertAt(ASTNode, int, TextEditGroup)
242      */

243     public void insertLast(ASTNode node, TextEditGroup editGroup) {
244         if (node == null) {
245             throw new IllegalArgumentException JavaDoc();
246         }
247         internalInsertAt(node, -1, true, editGroup);
248     }
249
250     /**
251      * Inserts the given node into the list at the given index.
252      * The index corresponds to a combined list of original and new nodes;
253      * removed or replaced nodes are still in the combined list.
254      * The inserted node must either be brand new (not part of the original AST)
255      * or a placeholder node (for example, one created by
256      * {@link ASTRewrite#createCopyTarget(ASTNode)},
257      * {@link ASTRewrite#createMoveTarget(ASTNode)},
258      * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
259      * is not actually modified in any way; rather, the rewriter just records
260      * a note that this node has been inserted into the list.
261      *
262      * @param node the node to insert
263      * @param index insertion index in the combined list of original and
264      * inserted nodes; <code>-1</code> indicates insertion as the last element
265      * @param editGroup the edit group in which to collect the corresponding
266      * text edits, or <code>null</code> if ungrouped
267      * @throws IllegalArgumentException if the node is null, or if the node is not part
268      * of this rewriter's AST, or if the inserted node is not a new node (or
269      * placeholder), or if the described modification is otherwise invalid
270      * (not a member of this node's original list)
271      * @throws IndexOutOfBoundsException if the index is negative and not -1,
272      * or if it is larger than the size of the combined list
273      */

274     public void insertAt(ASTNode node, int index, TextEditGroup editGroup) {
275         if (node == null) {
276             throw new IllegalArgumentException JavaDoc();
277         }
278         internalInsertAt(node, index, isInsertBoundToPreviousByDefault(node), editGroup);
279     }
280     
281     private void internalInsertAt(ASTNode node, int index, boolean boundToPrevious, TextEditGroup editGroup) {
282         RewriteEvent event= getEvent().insert(node, index);
283         if (boundToPrevious) {
284             getRewriteStore().setInsertBoundToPrevious(node);
285         }
286         if (editGroup != null) {
287             getRewriteStore().setEventEditGroup(event, editGroup);
288         }
289     }
290     
291     
292     private ASTNode createTargetNode(ASTNode first, ASTNode last, boolean isMove, ASTNode replacingNode, TextEditGroup editGroup) {
293         if (first == null || last == null) {
294             throw new IllegalArgumentException JavaDoc();
295         }
296
297         NodeInfoStore nodeStore= this.rewriter.getNodeStore();
298         ASTNode placeholder= nodeStore.newPlaceholderNode(first.getNodeType()); // revisit: could use list type
299
if (placeholder == null) {
300             throw new IllegalArgumentException JavaDoc("Creating a target node is not supported for nodes of type" + first.getClass().getName()); //$NON-NLS-1$
301
}
302         
303         Block internalPlaceHolder= nodeStore.createCollapsePlaceholder();
304         CopySourceInfo info= getRewriteStore().createRangeCopy(this.parent, this.childProperty, first, last, isMove, internalPlaceHolder, replacingNode, editGroup);
305         nodeStore.markAsCopyTarget(placeholder, info);
306         
307         return placeholder;
308     }
309     
310     /**
311      * Creates and returns a placeholder node for a true copy of a range of nodes of the
312      * current list.
313      * The placeholder node can either be inserted as new or used to replace an
314      * existing node. When the document is rewritten, a copy of the source code
315      * for the given node range is inserted into the output document at the position
316      * corresponding to the placeholder (indentation is adjusted).
317      *
318      * @param first the node that starts the range
319      * @param last the node that ends the range
320      * @return the new placeholder node
321      * @throws IllegalArgumentException An exception is thrown if the first or last node
322      * are <code>null</code>, if a node is not a child of the current list or if the first node
323      * is not before the last node. An <code>IllegalArgumentException</code> is
324      * also thrown if the copied range is overlapping with an other moved or copied range.
325      */

326     public final ASTNode createCopyTarget(ASTNode first, ASTNode last) {
327         if (first == last) {
328             return this.rewriter.createCopyTarget(first);
329         } else {
330             return createTargetNode(first, last, false, null, null);
331         }
332     }
333     
334     /**
335      * Creates and returns a placeholder node for a move of a range of nodes of the
336      * current list.
337      * The placeholder node can either be inserted as new or used to replace an
338      * existing node. When the document is rewritten, a copy of the source code
339      * for the given node range is inserted into the output document at the position
340      * corresponding to the placeholder (indentation is adjusted).
341      *
342      * @param first the node that starts the range
343      * @param last the node that ends the range
344      * @return the new placeholder node
345      * @throws IllegalArgumentException An exception is thrown if the first or last node
346      * are <code>null</code>, if a node is not a child of the current list or if the first node
347      * is not before the last node. An <code>IllegalArgumentException</code> is
348      * also thrown if the moved range is overlapping with an other moved or copied range.
349      *
350      * @since 3.1
351      */

352     public final ASTNode createMoveTarget(ASTNode first, ASTNode last) {
353         return createMoveTarget(first, last, null, null);
354     }
355     
356     /**
357      * Creates and returns a placeholder node for a move of a range of nodes of the
358      * current list. The moved nodes can optionally be replaced by a specified node.
359      *
360      * The placeholder node can either be inserted as new or used to replace an
361      * existing node. When the document is rewritten, a copy of the source code
362      * for the given node range is inserted into the output document at the position
363      * corresponding to the placeholder (indentation is adjusted).
364      *
365      * @param first the node that starts the range
366      * @param last the node that ends the range
367      * @param replacingNode a node that is set at the location of the moved nodes
368      * or <code>null</code> to remove all nodes
369      * @param editGroup the edit group in which to collect the corresponding
370      * text edits fro a replace, or <code>null</code> if ungrouped
371      * @return the new placeholder node
372      * @throws IllegalArgumentException An exception is thrown if the first or
373      * last node are <code>null</code>, if a node is not a child of the current list or
374      * if the first node is not before the last node. An <code>IllegalArgumentException
375      * </code> is also thrown if the moved range is overlapping with an other moved
376      * or copied range.
377      *
378      * @since 3.1
379      */

380     public final ASTNode createMoveTarget(ASTNode first, ASTNode last, ASTNode replacingNode, TextEditGroup editGroup) {
381         if (first == last) {
382             replace(first, replacingNode, editGroup);
383             return this.rewriter.createMoveTarget(first);
384         } else {
385             return createTargetNode(first, last, true, replacingNode, editGroup);
386         }
387     }
388     
389     /*
390      * Heuristic to decide if a inserted node is bound to previous or the next sibling.
391      */

392     private boolean isInsertBoundToPreviousByDefault(ASTNode node) {
393         return (node instanceof Statement || node instanceof FieldDeclaration);
394     }
395     
396     /**
397      * Returns the original nodes in the list property managed by this
398      * rewriter. The returned list is unmodifiable.
399      *
400      * @return a list of all original nodes in the list
401      */

402     public List JavaDoc getOriginalList() {
403         List JavaDoc list= (List JavaDoc) getEvent().getOriginalValue();
404         return Collections.unmodifiableList(list);
405     }
406     
407     /**
408      * Returns the nodes in the revised list property managed by this
409      * rewriter. The returned list is unmodifiable.
410      *
411      * @return a list of all nodes in the list taking into account
412      * all the described changes
413      */

414     public List JavaDoc getRewrittenList() {
415         List JavaDoc list= (List JavaDoc) getEvent().getNewValue();
416         return Collections.unmodifiableList(list);
417     }
418
419 }
420
Popular Tags