KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > jmiimpl > javamodel > MetadataElement


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.javacore.jmiimpl.javamodel;
20
21 import org.netbeans.jmi.javamodel.*;
22 import org.netbeans.lib.java.parser.ASTree;
23 import org.netbeans.lib.java.parser.ASTreeTypes;
24 import org.netbeans.lib.java.parser.ParserTokens;
25 import org.netbeans.lib.java.parser.Token;
26 import org.netbeans.mdr.handlers.AttrListWrapper;
27 import org.netbeans.mdr.handlers.BaseObjectHandler;
28 import org.netbeans.mdr.handlers.InstanceHandler;
29 import org.netbeans.mdr.persistence.StorageException;
30 import org.netbeans.mdr.storagemodel.StorableFeatured;
31 import org.netbeans.mdr.storagemodel.StorableObject;
32 import org.netbeans.modules.javacore.ClassIndex;
33 import org.netbeans.modules.javacore.internalapi.JavaMetamodel;
34 import org.netbeans.modules.javacore.internalapi.JavaModelUtil;
35 import org.netbeans.modules.javacore.parser.*;
36 import org.netbeans.modules.javacore.JMManager;
37 import org.openide.ErrorManager;
38 import org.openide.text.PositionBounds;
39 import javax.jmi.reflect.InvalidObjectException;
40 import javax.jmi.reflect.RefClass;
41 import javax.jmi.reflect.RefFeatured;
42 import javax.jmi.reflect.RefObject;
43 import java.lang.ref.Reference JavaDoc;
44 import java.util.*;
45
46 /** Defines method for children initialization and changes management.
47  *
48  * @author Martin Matula
49  */

50 public abstract class MetadataElement extends InstanceHandler implements Element {
51     public static final int CHANGED_CHILDREN = 1;
52     public static final int CHANGED_NAME = 1 << 1;
53     public static final int CHANGED_MODIFIERS = 1 << 2;
54     public static final int CHANGED_IS_STATIC = CHANGED_MODIFIERS;
55     public static final int CHANGED_IS_FINAL = CHANGED_MODIFIERS;
56     public static final int CHANGED_IS_ON_DEMAND = 1 << 3;
57     public static final int CHANGED_THROWS = CHANGED_IS_ON_DEMAND;
58     public static final int CHANGED_JAVADOC = 1 << 4;
59     public static final int CHANGED_BODY = 1 << 5;
60     public static final int CHANGED_TYPE = 1 << 6;
61     public static final int CHANGED_EXTENDS = CHANGED_THROWS;
62     public static final int CHANGED_IMPLEMENTS = 1 << 7;
63     public static final int CHANGED_INITIAL_VALUE = CHANGED_BODY;
64     public static final int CHANGED_PARAMETERS = 1 << 8;
65     public static final int CHANGED_PACKAGE_NAME = 1 << 9;
66     public static final int CHANGED_FEATURES = CHANGED_PARAMETERS;
67     public static final int CHANGED_CLASSIFIERS = CHANGED_FEATURES;
68     public static final int CHANGED_IMPORTS = CHANGED_BODY;
69     public static final int CHANGED_STATEMENTS = CHANGED_FEATURES;
70     public static final int CHANGED_LABEL = CHANGED_NAME;
71     public static final int CHANGED_THEN_PART = CHANGED_BODY;
72     public static final int CHANGED_ELSE_PART = 1 << 10;
73     public static final int CHANGED_EXPRESSION = 1 << 11;
74     public static final int CHANGED_STEPS = CHANGED_FEATURES;
75     public static final int CHANGED_INIT = CHANGED_THROWS;
76     public static final int CHANGED_CASES = CHANGED_STEPS;
77     public static final int CHANGED_VALUE = CHANGED_EXPRESSION;
78     public static final int CHANGED_LOCK = CHANGED_EXPRESSION;
79     public static final int CHANGED_DETAIL = CHANGED_BODY;
80     public static final int CHANGED_FINALIZER = CHANGED_EXPRESSION;
81     public static final int CHANGED_CATCHES = CHANGED_FEATURES;
82     public static final int CHANGED_PARAMETER = CHANGED_EXPRESSION;
83     public static final int CHANGED_RIGHT_SIDE = CHANGED_ELSE_PART;
84     public static final int CHANGED_LEFT_SIDE = CHANGED_THEN_PART;
85     public static final int CHANGED_CONDITION = CHANGED_EXPRESSION;
86     public static final int CHANGED_TRUE_PART = CHANGED_THEN_PART;
87     public static final int CHANGED_FALSE_PART = CHANGED_ELSE_PART;
88     public static final int CHANGED_ARRAY = CHANGED_LEFT_SIDE;
89     public static final int CHANGED_INDEX = CHANGED_RIGHT_SIDE;
90     public static final int CHANGED_PARENT_CLASS = CHANGED_EXPRESSION;
91     public static final int CHANGED_ENCLOSING_CLASS = CHANGED_PARENT_CLASS;
92     public static final int CHANGED_CLASS_DEFINITION = CHANGED_ELSE_PART;
93     public static final int CHANGED_HAS_SUPER = CHANGED_MODIFIERS;
94     public static final int CHANGED_ELEMENT_VALUES = CHANGED_FEATURES;
95     public static final int CHANGED_DIMENSIONS = CHANGED_FEATURES;
96     public static final int CHANGED_VARIABLES = CHANGED_FEATURES;
97     public static final int CHANGED_TEXT = CHANGED_NAME;
98     public static final int CHANGED_INITIALIZER = CHANGED_EXPRESSION;
99     public static final int CHANGED_PARENT = CHANGED_EXPRESSION;
100     public static final int CHANGED_CLASS_NAME = 1 << 12;
101     public static final int CHANGED_DIM_COUNT = 1 << 13;
102     public static final int CHANGED_ITERABLE = CHANGED_EXPRESSION;
103     public static final int CHANGED_CONSTANTS = CHANGED_DIM_COUNT;
104     public static final int CHANGED_IS_VARARG = CHANGED_BODY;
105     public static final int CHANGED_TYPE_ARGUMENTS = 1 << 14;
106     public static final int CHANGED_ANNOTATION = 1 << 15;
107     public static final int CHANGED_BOUNDS = CHANGED_MODIFIERS;
108     public static final int CHANGED_TYPE_PARAMETERS = 1 << 16;
109     public static final int CHANGED_BOUND = CHANGED_BOUNDS;
110     public static final int CHANGED_IS_LOWER = CHANGED_EXPRESSION;
111     public static final int CHANGED_ARGUMENTS = CHANGED_STATEMENTS;
112     public static final int CHANGED_ENUM_CONST_BODY = CHANGED_CLASS_DEFINITION;
113     public static final int CHANGED_OPERATOR = 1 << 17;
114     public static final int CHANGED_EXTERNAL = 1 << 18;
115     
116     // value of this field will be lazily initialized from editor setting
117
protected static String JavaDoc INDENTATION = " "; // NOI18N
118
/**
119      * Contains information about spaces per tab character. In addition to,
120      * it holds also information if the INDENTATION field is initialized from
121      * editor setting. -1 means it is not initialized yet.
122      */

123     protected static int spacesPerTab = -1;
124     
125     private int changes = 0;
126     private boolean isValid = true;
127     protected boolean childrenInited = false;
128     public boolean disableChanges = false;
129
130     public MetadataElement(StorableObject o) {
131         super(o);
132     }
133
134     protected final void initCheck() {
135         if (!isValid) {
136             throwInvalidObject();
137         }
138         if (!isInitialized()) {
139             if (this instanceof ResourceImpl) {
140                 ((ResourceImpl) this).initResource();
141             } else {
142                 MetadataElement parent = (MetadataElement) refImmediateComposite();
143                 // the element must have a parent
144
// with an exception of Resource
145
if (parent != null)
146                     parent.initChildren();
147             }
148         }
149     }
150     
151     private void throwInvalidObject() {
152         throw new InvalidObjectException(null, "Object was deleted."); // NOI18N
153
}
154
155     protected void _delete() {
156         // --- delete from composite --------------------------------------
157
MetadataElement parent = (MetadataElement) refImmediateComposite();
158         if (parent != null) {
159             parent.removeChild(this);
160         }
161         // --- delete children --------------------------------------------
162
// for (Iterator it = getInitedChildren().iterator(); it.hasNext();) {
163
// ((RefObject) it.next()).refDelete();
164
// }
165
// --- delete this instance ---------------------------------------
166
// ((ExclusiveMutex) _getMdrStorage().getRepositoryMutex()).removeNew(this);
167

168         isValid = false;
169     }
170
171     /** Part ot the rollback mechanism.
172      *
173      * In the case of any rollback, all classes should be rebuilt from ASTrees.
174      * The layout for method is the next one:
175      * protected void reset() {
176      * .. do your own job...
177      * super.reset()
178      * }
179      */

180     protected void rollback() {
181         if (isNew()) {
182             isValid = false;
183         } else {
184             isValid = true;
185             resetChange();
186             boolean changes = disableChanges;
187             disableChanges = true;
188             try {
189                 //resetValues();
190
for (Iterator it = getInitedChildren().iterator(); it.hasNext();) {
191                     ((MetadataElement) it.next()).rollback();
192                 }
193                 resetChildren();
194             } finally {
195                 disableChanges = changes;
196             }
197         }
198     }
199
200     protected final void commit() {
201         //if (isNew()) {
202
// the element is new => remove it from the registry
203
//((ExclusiveMutex) _getMdrStorage().getRepositoryMutex()).removeNew(this);
204
//}
205
for (Iterator it = getInitedChildren().iterator(); it.hasNext();) {
206             ((MetadataElement) it.next()).commit();
207         }
208         uninitialize();
209     }
210
211     protected abstract boolean isInitialized();
212     protected abstract void uninitialize();
213
214 // protected void resetValues() {
215
// }
216

217     public boolean isValid() {
218         return isValid;
219     }
220
221     protected abstract Object JavaDoc getInternalForm();
222
223     protected void initChildren() {
224     }
225
226     protected void resetChildren() {
227     }
228
229     protected List getInitedChildren() {
230         if (childrenInited) {
231             return getChildren();
232         } else {
233             return Collections.EMPTY_LIST;
234         }
235     }
236
237     public List getChildren() {
238         return Collections.EMPTY_LIST;
239     }
240
241     static void addIfNotNull(Collection collection, Object JavaDoc value) {
242         if (value != null) {
243             collection.add(value);
244         }
245     }
246
247     protected void parentChanged() {
248     }
249
250     protected int getParentChangedMask(int mask) {
251         return CHANGED_CHILDREN;
252     }
253
254     protected void objectChanged(int mask) {
255         if (!isValid()) throwInvalidObject(); // NOI18N
256
if (disableChanges) return;
257         if (!isChanged()) {
258             if (!childrenInited) {
259                 // todo: this is only necessary for elements that have persistent children
260
initChildren();
261             }
262             Object JavaDoc parent = refImmediateComposite();
263             if (parent != null && parent instanceof MetadataElement) {
264                 ((MetadataElement) parent).objectChanged(getParentChangedMask(mask));
265             }
266         }
267         changes |= mask;
268     }
269
270     /**
271      * Returns source code representation of this element in case of the element
272      * does not contain any change and is not newly added. In such cases
273      * (when element is new or changed) it returns null.
274      *
275      * @return null in case of newly added or changed element, otherwise
276      * source-code representation.
277      */

278     protected final String JavaDoc checkChange() {
279         // there is not any change, return original element in case of element
280
// is not new element
281
if (!isNew()) {
282             if (!isChanged()) {
283                 ASTProvider p = getParser();
284                 MetadataElement indentElement = this;
285                 int b = IndentUtil.getElementStart(this);
286                 int e = IndentUtil.getElementEnd(this);
287                 if (this instanceof StatementBlock) {
288                     // !!!! TODO: fix the following - this seems like it specially handles
289
// moving statement block in the finally clause
290
Object JavaDoc composite = refImmediateComposite();
291                     if (composite instanceof TryStatement) {
292                         TryStatement tryStmt = (TryStatement) composite;
293                         if (this.equals(tryStmt.getFinalizer())) {
294                             if (tryStmt.getCatches().isEmpty()) {
295                                 b = IndentUtil.getElementEnd(tryStmt.getBody());
296                             } else {
297                                 CatchImpl catchBlock = null;
298                                 Iterator it = tryStmt.getCatches().iterator();
299                                 while (it.hasNext()) catchBlock = (CatchImpl) it.next();
300                                 b = IndentUtil.getElementEnd(catchBlock);
301                                 indentElement = (MetadataElement) refImmediateComposite();
302                             }
303                         }
304                     }
305                     // !!!!
306
} else if (this instanceof Statement) {
307                     Token startToken = p.getToken(getASTree().getFirstToken());
308                     b = startToken.getStartOffset();
309                     Token[] pad = startToken.getPadding();
310                     if (pad.length > 0) {
311                         startToken = pad[0];
312                         for (int i = 0; i < pad.length; i++) {
313                             if (pad[i].getType() == ParserTokens.EOL) {
314                                 b = pad[i].getStartOffset();
315                                 break;
316                             }
317                         }
318                     }
319                     int lastTokenIndex = getASTree().getLastToken();
320                     Token endToken = p.getToken(lastTokenIndex+1);
321                     if (endToken == null) {
322                         endToken = p.getToken(lastTokenIndex);
323                         e = endToken.getEndOffset();
324                     } else {
325                         pad = endToken.getPadding();
326                         if (pad.length > 0) {
327                             endToken = pad[0];
328                             for (int i = 0; i < pad.length; i++) {
329                                 if (pad[i].getType() == ParserTokens.EOL) {
330                                     e = pad[i].getStartOffset();
331                                     break;
332                                 }
333                             }
334                         }
335                     }
336                 } else if (this instanceof Catch) {
337                     int tokenBefore = getASTree().getFirstToken();
338                     b = IndentUtil.getElementEnd(((TryStatement) refImmediateComposite()).getBody());
339                 }
340                 String JavaDoc text = p.getSourceText().substring(b, e);
341                 int tokenId = getASTree().getFirstToken();
342                 // for the statement block, use closing curly as a base element
343
// indentation will be computed from spaces before this curly
344
if (this instanceof StatementBlock) {
345                     tokenId = getASTree().getLastToken();
346                 }
347                 return IndentUtil.indentExistingElement(this, text, tokenId);
348             } else {
349                 if (!childrenInited) {
350                     initChildren();
351                 }
352             }
353         }
354         return null;
355     }
356
357     protected final void resetChange() {
358         if (disableChanges) return;
359         changes = 0;
360     }
361
362     protected final void setChanged() {
363         if (disableChanges) return;
364         changes = ~0;
365     }
366
367     protected final void resetChange(int mask) {
368         if (disableChanges) return;
369         changes &= ~mask;
370     }
371
372     protected final boolean isChanged() {
373         return changes != 0;
374     }
375
376     protected final boolean isChanged(int mask) {
377         return (changes & mask) != 0;
378     }
379
380     /** Method used to create children list from the AST
381      * @param currentList Current list of children that the method should update with new ASTs or rebuild (in not applicable, pass null)
382      * @param attrName Name of MOF attribute that holds the list returned by this method.
383      * @param tree AS tree that represents a child or children to be put into the returned list.
384      * @param groupNodeType In case there can be one child or a group node of several children
385      * represented by tree parameter, this attribute contains type of node that corresponds
386      * to the group node (to determine whether there is a single child or a group of children under a group node.
387      * @param changeMask Bit that should be set in change flags of owner of the returned list if the list changes.
388      * @param rebuild Indicates whether this method should completely rebuild the existing list (if passed in the first
389      * parameter) or whether it is expected that the list contains the same element, only their AS trees should be updated (in case of false value).
390      * @return List of children.
391      */

392     protected final LightAttrList createChildrenList(LightAttrList currentList, String JavaDoc attrName, ASTree tree, int groupNodeType, int changeMask, boolean rebuild) {
393         return createChildrenList(currentList, attrName, getChildNodes(tree, groupNodeType), changeMask, rebuild);
394     }
395
396     /** Method used to create children list from the AST */
397     protected final LightAttrList createChildrenList(LightAttrList currentList, String JavaDoc attrName, ASTree[] trees, int changeMask, boolean rebuild) {
398         return createChildrenList(currentList, attrName, trees, 0, changeMask, rebuild);
399     }
400
401     protected final LightAttrList createChildrenList(LightAttrList currentList, String JavaDoc attrName, ASTree[] trees, int index, int changeMask, boolean rebuild) {
402         DeferredAttrList deferredList;
403         try {
404             if (currentList != null && trees != null) {
405                 deferredList = (DeferredAttrList) ((AttrListWrapper) currentList.getInnerList()).getInnerList();
406                 if (rebuild) {
407                     for (Iterator it = deferredList.iterator(); it.hasNext();) {
408                         MetadataElement temp = (MetadataElement) it.next();
409                         it.remove();
410                         temp.refDelete();
411                     }
412                 } else {
413                     int i = index;
414                     for (ListIterator it = deferredList.listIterator(); it.hasNext(); i++) {
415                         MetadataElement im = (MetadataElement) it.next();
416                         if (isNew()) {
417                             im.setNew();
418                         } else {
419                             if (i >= trees.length) {
420                                 it.remove();
421                             } else {
422                                 Element newElement = initOrCreate(im, trees[i]);
423                                 if (newElement != im) {
424                                     it.set(newElement);
425                                 }
426                             }
427                         }
428                     }
429                     for (; i < trees.length; i++) {
430                         deferredList.add(createElement(trees[i]));
431                     }
432                     deferredList = null;
433                 }
434             } else {
435                 StorableFeatured storable = (StorableFeatured) _getDelegate();
436                 deferredList = new DeferredAttrList(storable, storable.getClassProxy().getAttrDesc(attrName), new ArrayList());
437                 currentList = createWrapper(attrName, deferredList, changeMask);
438             }
439             if (deferredList != null && trees != null) {
440                 for (int i = index; i < trees.length; i++) {
441                     MetadataElement s = createElement(trees[i]);
442                     if (s != null) {
443                         deferredList.add(s);
444                     }
445                 }
446             }
447         } catch (StorageException e) {
448             throw (GeneralException) ErrorManager.getDefault().annotate(new GeneralException(e.getMessage()), e);
449         }
450         return currentList;
451     }
452
453     /** Method used to create children list from a list provided into the statement constructor */
454     protected final LightAttrList createChildrenList(String JavaDoc attrName, List elements, int changeMask) {
455         DeferredAttrList deferredList;
456         try {
457             ArrayList innerList;
458             if (elements != null) {
459                 innerList = new ArrayList(elements.size());
460                 for (Iterator it = elements.iterator(); it.hasNext();) {
461                     MetadataElement element = (MetadataElement) it.next();
462                     ((StorableObject) element._getDelegate()).setComposite(_getDelegate(), null, null);
463                     innerList.add(element);
464                 }
465             } else {
466                 innerList = new ArrayList();
467             }
468             StorableFeatured storable = (StorableFeatured) _getDelegate();
469             deferredList = new DeferredAttrList(storable, storable.getClassProxy().getAttrDesc(attrName), innerList);
470         } catch (StorageException e) {
471             throw (GeneralException) ErrorManager.getDefault().annotate(new GeneralException(e.getMessage()), e);
472         }
473         return createWrapper(attrName, deferredList, changeMask);
474     }
475
476     protected final LightAttrList createWrapper(String JavaDoc attrName, List innerList, int changeMask) {
477         AttrListWrapper list = new AttrListWrapper(this, innerList);
478         list.setAttrName(attrName);
479         return new LightAttrList(list, this, changeMask);
480     }
481
482     protected final void deleteChild(Element child) {
483         if (child != null) {
484             changeChild(child, null);
485             child.refDelete();
486         }
487     }
488
489     protected static void deleteChildren(Collection children) {
490         for (Iterator it = children.iterator(); it.hasNext();) {
491             RefObject element = (RefObject) it.next();
492             it.remove();
493             element.refDelete();
494         }
495     }
496
497     protected final void changeChild(Element oldChild, Element newChild) {
498         try {
499             if (oldChild != null) {
500                 ((StorableObject) ((BaseObjectHandler) oldChild)._getDelegate()).clearComposite();
501             }
502             if (newChild != null) {
503                 ((StorableObject) ((BaseObjectHandler) newChild)._getDelegate()).setComposite(_getDelegate(), null, null);
504             }
505         } catch (StorageException e) {
506             throw (GeneralException) ErrorManager.getDefault().annotate(new GeneralException(e.getMessage()), e);
507         }
508     }
509
510     protected final TransientElement createElement(ASTree tree, RefClass proxy) {
511         if (tree == null || proxy == null) return null;
512         Object JavaDoc o = ((MEFactory) proxy).create(this);
513         TransientElement result = (TransientElement) o;
514         result.init(tree);
515         return result;
516     }
517
518     public abstract MDRParser getParser();
519
520     public ASTree getASTree() {
521         return getASTree(getInternalForm());
522     }
523
524     public PositionBounds getPosition(boolean inclDoc) {
525         testResourceChange();
526         PositionBounds result = null;
527         ASTree tree = getASTree();
528         if (tree != null) {
529             result = ((MDRParser) tree.getASTContext()).createBounds(tree, tree, inclDoc);
530         }
531         return result;
532     }
533
534     public final PositionBounds getPartPosition(ElementPartKind part, int position) {
535         testResourceChange();
536         return getParser().createBounds(getPartStartTree(part), getPartEndTree(part), false);
537     }
538
539     public Resource getResource() {
540         RefObject parent = this;
541
542         while (!(parent == null || parent instanceof Resource)) {
543             parent = (RefObject) parent.refImmediateComposite();
544         }
545         return (Resource) parent;
546     }
547
548     protected MetadataElement createElement(ASTree tree) {
549         if (tree == null) return null;
550         switch (tree.getType()) {
551             case ASTreeTypes.ENUM_DECLARATION:
552             case ASTreeTypes.ANNOTATION_TYPE_DECLARATION:
553             case ASTreeTypes.INTERFACE_DECLARATION:
554             case ASTreeTypes.CLASS_DECLARATION: {
555                 JavaClassImpl jcls=(JavaClassImpl)getParser().getSemanticInfo(tree, this);
556
557                 return jcls;
558             }
559             default:
560                 return createElement(tree, getElementProxy(tree));
561         }
562     }
563
564     private RefClass getElementProxy(ASTree tree) {
565         JavaModelPackage pkg = (JavaModelPackage) refImmediatePackage();
566         int type = tree.getType();
567         switch (type) {
568             case ASTreeTypes.EXPLICIT_CONSTRUCTOR_INVOCATION:
569                 return pkg.getConstructorInvocation();
570             case ASTreeTypes.ARRAY_INITIALIZER:
571                 return pkg.getArrayInitialization();
572             case ASTreeTypes.ARRAY_CREATION_EXPRESSION:
573                 return pkg.getNewArrayExpression();
574             case ASTreeTypes.LOCAL_VARIABLE_DECLARATION:
575                 return pkg.getLocalVarDeclaration();
576             case ASTreeTypes.VARIABLE_DECLARATOR:
577                 return pkg.getLocalVariable();
578             case ASTreeTypes.LABELED_STATEMENT:
579                 return pkg.getLabeledStatement();
580             case ASTreeTypes.IF_STATEMENT:
581                 return pkg.getIfStatement();
582             case ASTreeTypes.WHILE_STATEMENT:
583                 return pkg.getWhileStatement();
584             case ASTreeTypes.FOR_STATEMENT:
585                 return pkg.getForStatement();
586             case ASTreeTypes.FOR_EACH_STATEMENT:
587                 return pkg.getForEachStatement();
588             case ASTreeTypes.BLOCK_STATEMENTS:
589                 return pkg.getStatementBlock();
590             case ASTreeTypes.EXPRESSION_STATEMENT:
591                 return pkg.getExpressionStatement();
592             case ASTreeTypes.EMPTY_STATEMENT:
593                 return pkg.getEmptyStatement();
594             case ASTreeTypes.ASSIGNMENT:
595                 return pkg.getAssignment();
596             case ASTreeTypes.INFIX_EXPRESSION:
597                 return pkg.getInfixExpression();
598             case ASTreeTypes.PREFIX_EXPRESSION:
599                 return pkg.getPrefixExpression();
600             case ASTreeTypes.POSTFIX_EXPRESSION:
601                 return pkg.getPostfixExpression();
602             case ASTreeTypes.METHOD_INVOCATION:
603                 return pkg.getMethodInvocation();
604             case ASTreeTypes.CLASS_INSTANCE_CREATION_EXPRESSION:
605                 return pkg.getNewClassExpression();
606             case ASTreeTypes.COMPLEX_EXPRESSION:
607                 return pkg.getComplexExpression();
608             case ASTreeTypes.CONDITIONAL_EXPRESSION:
609                 return pkg.getConditionalExpression();
610             case ASTreeTypes.CAST_EXPRESSION:
611                 return pkg.getTypeCast();
612             case ASTreeTypes.SWITCH_STATEMENT:
613                 return pkg.getSwitchStatement();
614             case ASTreeTypes.SWITCH_LABEL:
615             case ASTreeTypes.SWITCH_BLOCK_STATEMENT_GROUP:
616                 return pkg.getCase();
617             case ASTreeTypes.DO_STATEMENT:
618                 return pkg.getDoStatement();
619             case ASTreeTypes.BREAK_STATEMENT:
620                 return pkg.getBreakStatement();
621             case ASTreeTypes.CONTINUE_STATEMENT:
622                 return pkg.getContinueStatement();
623             case ASTreeTypes.RETURN_STATEMENT:
624                 return pkg.getReturnStatement();
625             case ASTreeTypes.SYNCHRONIZE_STATEMENT:
626                 return pkg.getSynchronizedStatement();
627             case ASTreeTypes.THROW_STATEMENT:
628                 return pkg.getThrowStatement();
629             case ASTreeTypes.TRY_STATEMENT:
630                 return pkg.getTryStatement();
631             case ASTreeTypes.CATCH_CLAUSE:
632                 return pkg.getCatch();
633             case ASTreeTypes.ASSERT_STATEMENT:
634                 return pkg.getAssertStatement();
635             case ASTreeTypes.REFERENCE_TYPE:
636                 return pkg.getArrayReference();
637             case ASTreeTypes.MULTI_PART_ID:
638             case ParserTokens.IDENTIFIER:
639                 if (getParser().isVariableAccess(tree)) {
640                     return pkg.getVariableAccess();
641                 }
642             case ASTreeTypes.PRIMITIVE_TYPE:
643                 return pkg.getMultipartId();
644             case ASTreeTypes.FIELD_DECLARATION:
645             case ASTreeTypes.METHOD_DECLARATION:
646             case ASTreeTypes.CLASS_DECLARATION:
647             case ASTreeTypes.INTERFACE_DECLARATION:
648             case ASTreeTypes.INSTANCE_INITIALIZER:
649             case ASTreeTypes.STATIC_INITIALIZER:
650             case ASTreeTypes.CONSTRUCTOR_DECLARATION:
651             case ASTreeTypes.CLASS_BODY_DECLARATIONS:
652                 //return pkg.getClassDefinition();
653
// temporary -- ignore local classes
654
return null;
655             case ASTreeTypes.PRIMARY_CLASS:
656                 return pkg.getClassExpression();
657             case ASTreeTypes.PRIMARY_THIS:
658                 return pkg.getThisExpression();
659             case ASTreeTypes.FIELD_ACCESS:
660                 return pkg.getVariableAccess();
661             case ASTreeTypes.ARRAY_ACCESS:
662                 return pkg.getArrayAccess();
663             case ParserTokens.INT_LIT:
664                 if (((Token) tree).getValue() instanceof Long JavaDoc) {
665                     return pkg.getLongLiteral();
666                 } else {
667                     return pkg.getIntLiteral();
668                 }
669             case ParserTokens.FLOAT_LIT:
670                 if (((Token) tree).getValue() instanceof Float JavaDoc) {
671                     return pkg.getFloatLiteral();
672                 } else {
673                     return pkg.getDoubleLiteral();
674                 }
675             case ParserTokens.BOOL_LIT:
676                 return pkg.getBooleanLiteral();
677             case ParserTokens.CHAR_LIT:
678                 return pkg.getCharLiteral();
679             case ParserTokens.STRING_LIT:
680                 return pkg.getStringLiteral();
681             case ParserTokens.NULL_LIT:
682                 return pkg.getNullLiteral();
683             case ASTreeTypes.SUPER_:
684                 return pkg.getMultipartId();
685             case ASTreeTypes.WILDCARD:
686                 return pkg.getWildCard();
687             case ASTreeTypes.ARGUMENT_LIST:
688                 return pkg.getArgumentList();
689             case ASTreeTypes.ELEMENT_VALUE_PAIR:
690                 return pkg.getAttributeValue();
691             case ASTreeTypes.ERRONEOUS:
692                 return null;
693             default:
694                 throw new RuntimeException JavaDoc("Unexpected type of ASTree: " + type); // NOI18N
695
}
696     }
697
698     /**
699      * Used for obtaining source-code representation of the element. This
700      * method is called by parent when the element is newly added or we need
701      * to regenerate whole element.
702      *
703      * @return source-code representation of element
704      */

705     public String JavaDoc getSourceText() {
706         String JavaDoc origElem;
707         if ((origElem = checkChange()) != null)
708             return origElem;
709         else {
710             if (isNew()) {
711                 return IndentUtil.indentNewElement(this);
712             } else {
713                 // for all statements (except statement block) todo
714
if (this instanceof Statement && !(this instanceof StatementBlock) &&
715                                                  !(this instanceof JavaClass) &&
716                                                  !(this instanceof LocalVarDeclaration && refImmediateComposite() instanceof ForStatement))
717                 {
718                     StringBuffer JavaDoc buf = new StringBuffer JavaDoc(256);
719                     IndentUtil.reformatHeadGarbage(this, buf);
720                     buf.append(getRawText());
721                     
722                     // do not print tail for cycles as it was printed by
723
// their body
724
if (!(this instanceof WhileStatement ||
725                          this instanceof ForStatement ||
726                          this instanceof ForEachStatement ||
727                          this instanceof IfStatement)
728                        )
729                     {
730                         IndentUtil.printTailGarbage(this, buf);
731                     }
732                     return buf.toString();
733                 } else {
734                     return getRawText();
735                 }
736             }
737         }
738     }
739
740     abstract String JavaDoc getRawText();
741     
742     /**
743      * Used for obtaining changes and put them to the list.
744      *
745      * @param diffList list, where the changes are put by method. Contains
746      * DiffElement instances.
747      */

748     public void getDiff(List diffList) {
749     }
750
751     protected abstract void setNew();
752     protected abstract boolean isNew();
753
754     public final void replaceNode(List diff, ASTProvider parser, ASTree node, String JavaDoc text, int start, String JavaDoc prefix) {
755         int startOffset;
756         int endOffset;
757         if ((text == null && prefix != null) || node == null) {
758             startOffset = start;
759         } else {
760             startOffset = getStartOffset(parser, node, false);
761         }
762         if (node == null) {
763             endOffset = startOffset;
764             if (text != null && prefix != null) {
765                 text = prefix + text;
766             }
767         } else {
768             endOffset = parser.getToken(node.getLastToken()).getEndOffset();
769         }
770         if (text == null) {
771             text = "";
772         }
773         diff.add(new DiffElement(startOffset, endOffset, text));
774     }
775
776     protected final void getChildDiff(List diff, ASTProvider parser, ASTree node, MetadataElement child, int changeMask) {
777         getChildDiff(diff, parser, node, child, changeMask, 0, null);
778     }
779
780     protected final void getChildDiff(List diff, ASTProvider parser, ASTree node, MetadataElement child, int changeMask, int startOffset, String JavaDoc prefix) {
781         if (isChanged(changeMask)) {
782             replaceNode(diff, parser, node, child == null ? null : child.getSourceText(), startOffset, prefix);
783         } else if (child != null && child.isChanged()) {
784             child.getDiff(diff);
785         }
786     }
787
788     public final void getElementsDiff(List diff, Collection newElements) {
789         Object JavaDoc[] elements=newElements.toArray();
790         for (int i=0;i<elements.length;i++) {
791             MetadataElement me = (MetadataElement)elements[i];
792             if (me.isChanged())
793                 me.getDiff(diff);
794         }
795     }
796     public final void getCollectionDiff(List diff, ASTProvider parser, int changeMask, Object JavaDoc[] oldElements, Collection newElements, int endOffset, String JavaDoc separator) {
797         getCollectionDiff(diff, parser, changeMask, oldElements, newElements, endOffset, separator, true);
798     }
799
800     public final void getCollectionDiff(List diff, ASTProvider parser, int changeMask, Object JavaDoc[] oldElements, Collection newElements, int endOffset, String JavaDoc separator, boolean includePadds) {
801         if (isChanged(changeMask)) {
802             getCollectionDiff(diff, parser, oldElements, newElements, endOffset, separator, null, 0, includePadds);
803         } else if (isChanged(CHANGED_CHILDREN)) {
804             getElementsDiff(diff, newElements);
805         }
806     }
807
808     public final void getCollectionDiff(List diff, ASTProvider parser, int changeMask, ASTree oldParentNode, Collection newElements, int startOffset, String JavaDoc separator, String JavaDoc prefixIfNew) {
809         getCollectionDiff(diff, parser, changeMask, oldParentNode, oldParentNode == null ? 0 : oldParentNode.getType(), newElements, startOffset, separator, prefixIfNew);
810     }
811
812     public final void getCollectionDiff(List diff, ASTProvider parser, int changeMask, ASTree oldParentNode, int groupNodeType, Collection newElements, int startOffset, String JavaDoc separator, String JavaDoc prefixIfNew) {
813         if (isChanged(changeMask)) {
814             ASTree[] oldASTs;
815             int endOffset;
816             if (oldParentNode == null) {
817                 endOffset = startOffset;
818                 oldASTs = new ASTree[0];
819             } else {
820                 if (oldParentNode.getType() == groupNodeType) {
821                     oldASTs = oldParentNode.getSubTrees();
822                 } else {
823                     oldASTs = new ASTree[] {oldParentNode};
824                 }
825                 if (oldASTs.length == 0) {
826                     endOffset = startOffset;
827                 } else {
828                     endOffset = parser.getToken(oldASTs[oldASTs.length - 1].getLastToken()).getEndOffset();
829                 }
830             }
831             getCollectionDiff(diff, parser, oldASTs, newElements, endOffset, separator, prefixIfNew, startOffset, true);
832         } else if (isChanged(CHANGED_CHILDREN)) {
833             getElementsDiff(diff, newElements);
834         }
835     }
836
837     private void getCollectionDiff(List diff, ASTProvider parser, Object JavaDoc[] oldElements, Collection newElements, int endOffset, String JavaDoc separator, String JavaDoc prefixIfNew, int startOffset, boolean includePadds) {
838         //MethodInfo astInfo = (MethodInfo) getElementInfo();
839
if (newElements.isEmpty()) {
840             if (oldElements.length > 0 && prefixIfNew != null) {
841                 diff.add(new DiffElement(startOffset, endOffset, ""));
842                 return;
843             }
844         }
845         Object JavaDoc[] newElementArr=newElements.toArray();
846         CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr);
847         boolean isFirst = true;
848         StringBuffer JavaDoc diffText = null;
849         int positions[] = matcher.getPositions();
850         Set deleted = matcher.getDeleted();
851         int lastOffset = getOffset(0, parser, oldElements, endOffset, includePadds, false);
852         ASTree lastElement = null;
853         int newPos = 0;
854         int oldPos = 0;
855         for (;newPos<newElementArr.length; newPos++) {
856             boolean shouldDelete = false;
857             int newLastOffset = 0;
858             while (oldPos < oldElements.length && deleted.remove(oldElements[oldPos])) {
859                 if (!shouldDelete) {
860                     shouldDelete = true;
861                     lastOffset = getOffset(oldPos, parser, oldElements, endOffset, oldPos == 0 ? includePadds : true, true);
862                 }
863                 oldPos++;
864                 newLastOffset = getOffset(oldPos, parser, oldElements, endOffset, true, false);
865                 // if we are going to delete all elements from a given element to the last old element,
866
// we need to adjust the start offset of the deletion, since it should no longer
867
// be the start offset of the first element to be deleted, but rather the start offset
868
// of the token immediately following the last element that will not be deleted
869
// (e.g. to eliminate tokens like colons in the list of parameters)
870
if (lastElement != null && oldPos == oldElements.length &&
871                    (separator.trim().length() != 0)) {
872                     Token took = parser.getToken(lastElement.getLastToken() + 1);
873                     lastOffset = took.getStartOffset();
874                     Token[] pads = took.getPadding();
875                     if (pads != null && pads.length > 0) {
876                         for (int i = pads.length-1; i >= 0; i--) {
877                             if (pads[i].getType() == ParserTokens.EOL) {
878                                 lastOffset = pads[i].getStartOffset();
879                                 break;
880                             }
881                         }
882                     }
883                 }
884             }
885             if (shouldDelete) {
886                 diff.add(new DiffElement(lastOffset, newLastOffset, ""));
887                 lastOffset = newLastOffset;
888             }
889             MetadataElement e = (MetadataElement)newElementArr[newPos];
890             if (positions[newPos] != oldPos) {
891                 if (diffText == null) {
892                     if (prefixIfNew == null || oldElements.length > 0) {
893                         if (oldPos >= oldElements.length && !isFirst) {
894                             diffText = new StringBuffer JavaDoc(separator);
895                         } else {
896                             diffText = new StringBuffer JavaDoc();
897                         }
898                     } else {
899                         diffText = new StringBuffer JavaDoc(prefixIfNew);
900                     }
901                 } else {
902                     diffText.append(separator);
903                 }
904                 diffText.append(e.getSourceText());
905                 if (positions[newPos] != -1) {
906                     deleted.add(oldElements[positions[newPos]]);
907                 }
908             } else {
909                 if (diffText != null) {
910                     diffText.append(separator);
911                     diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
912                     diffText = null;
913                 }
914                 if (e.isChanged()) {
915                     e.getDiff(diff);
916                 }
917                 lastElement = getLastElement(oldPos, oldElements);
918                 oldPos++;
919                 lastOffset = getOffset(oldPos, parser, oldElements, endOffset, true, false);
920                 isFirst = false;
921             }
922         }
923         if (oldPos < oldElements.length) {
924             int newLastOffset = getOffset(oldElements.length, parser, oldElements, endOffset, true, false);
925             if (lastElement != null) {
926                 lastOffset = getStartOffset2(parser, parser.getToken(lastElement.getLastToken() + 1));
927             }
928             diff.add(new DiffElement(lastOffset, newLastOffset, diffText == null ? "" : diffText.toString()));
929         } else if (diffText != null) {
930             diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
931         }
932     }
933     
934     private int getImportsOffset(int index, ASTProvider parser, Object JavaDoc[] oldElements, int endOffset, boolean includePadds, boolean excludeComments) {
935         if (oldElements.length <= index) {
936             return endOffset;
937         } else {
938             ASTree tree = getChildASTree(oldElements[index]);
939             if (index != 0) {
940                 return excludeComments ? getStartOffset2(parser, tree) : getStartOffset(parser, tree, includePadds);
941             } else {
942                 Token startToken = parser.getToken(tree.getFirstToken());
943                 Token[] pad = startToken.getPadding();
944                 if (pad.length > 0) {
945                     startToken = pad[0];
946                     for (int i = 0; i < pad.length; i++) {
947                         if (pad[i].getType() == ParserTokens.EOL) {
948                             String JavaDoc value = parser.getText(pad[i]);
949                             return pad[i].getEndOffset();
950                         }
951                     }
952                 }
953                 return startToken.getStartOffset();
954             }
955         }
956     }
957     
958     void getImportsDiff(List diff, ASTProvider parser, Object JavaDoc[] oldElements, Collection newElements, int endOffset, int endOffset2, String JavaDoc separator, boolean includePadds, int changeMask) {
959         if (!isChanged(changeMask) && isChanged(CHANGED_CHILDREN)) {
960             getElementsDiff(diff, newElements);
961             return;
962         }
963         Object JavaDoc[] newElementArr=newElements.toArray();
964         CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr);
965         boolean isFirst = true;
966         StringBuffer JavaDoc diffText = null;
967         int positions[] = matcher.getPositions();
968         Set deleted = matcher.getDeleted();
969         int lastOffset = getOffset(0, parser, oldElements, endOffset, includePadds, false);
970         ASTree lastElement = null;
971         int newPos = 0;
972         int oldPos = 0;
973         for (;newPos<newElementArr.length; newPos++) {
974             boolean shouldDelete = false;
975             int newLastOffset = 0;
976             while (oldPos < oldElements.length && deleted.remove(oldElements[oldPos])) {
977                 if (!shouldDelete) {
978                     shouldDelete = true;
979                     lastOffset = getImportsOffset(oldPos, parser, oldElements, endOffset, oldPos == 0 ? includePadds : true, true);
980                 }
981                 oldPos++;
982                 newLastOffset = getImportsOffset(oldPos, parser, oldElements, endOffset, true, false);
983                 // if we are going to delete all elements from a given element to the last old element,
984
// we need to adjust the start offset of the deletion, since it should no longer
985
// be the start offset of the first element to be deleted, but rather the start offset
986
// of the token immediately following the last element that will not be deleted
987
// (e.g. to eliminate tokens like colons in the list of parameters)
988
if (lastElement != null && oldPos == oldElements.length) {
989                     Token took = parser.getToken(lastElement.getLastToken() + 1);
990                     lastOffset = took.getStartOffset();
991                     Token[] pads = took.getPadding();
992                     if (pads != null && pads.length > 0) {
993                         for (int i = pads.length-1; i >= 0; i--) {
994                             if (pads[i].getType() == ParserTokens.EOL) {
995                                 lastOffset = pads[i].getStartOffset();
996                                 break;
997                             }
998                         }
999                     }
1000                }
1001            }
1002            if (shouldDelete) {
1003// String s = oldPos == oldElements.length-1 ? "\n" : "";
1004
diff.add(new DiffElement(lastOffset, newLastOffset, ""));
1005                lastOffset = newLastOffset;
1006            }
1007            MetadataElement e = (MetadataElement)newElementArr[newPos];
1008            if (positions[newPos] != oldPos) {
1009                if (diffText == null) {
1010                    if ((oldElements.length > 0) && (oldPos >= oldElements.length && !isFirst)) {
1011                        diffText = new StringBuffer JavaDoc(separator);
1012                    } else {
1013                        diffText = new StringBuffer JavaDoc();
1014                    }
1015                } else {
1016                    diffText.append(separator);
1017                }
1018                diffText.append(e.getSourceText());
1019                if (positions[newPos] != -1) {
1020                    deleted.add(oldElements[positions[newPos]]);
1021                }
1022            } else {
1023                if (diffText != null) {
1024                    diffText.append(separator);
1025                    diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
1026                    diffText = null;
1027                }
1028                if (e.isChanged()) {
1029                    e.getDiff(diff);
1030                }
1031                lastElement = getLastElement(oldPos, oldElements);
1032                oldPos++;
1033                lastOffset = getImportsOffset(oldPos, parser, oldElements, endOffset, true, false);
1034                isFirst = false;
1035            }
1036        }
1037        if (oldPos < oldElements.length) {
1038            int newLastOffset = endOffset2 == -1 ? getImportsOffset(oldElements.length, parser, oldElements, endOffset, true, false) : endOffset2;
1039            if (lastElement != null) {
1040                lastOffset = getStartOffset2(parser, parser.getToken(lastElement.getLastToken() + 1));
1041            }
1042            diff.add(new DiffElement(lastOffset, newLastOffset, diffText == null ? "" : diffText.toString()));
1043        } else if (diffText != null) {
1044            diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
1045        }
1046    }
1047
1048    private int getOffset(int index, ASTProvider parser, Object JavaDoc[] oldElements, int endOffset, boolean includePadds, boolean excludeComments) {
1049        if (oldElements.length <= index) {
1050            return endOffset;
1051        } else {
1052            ASTree tree = getChildASTree(oldElements[index]);
1053            return excludeComments ? getStartOffset2(parser, tree) : getStartOffset(parser, tree, includePadds);
1054        }
1055    }
1056
1057    protected int getStartOffset(ASTProvider parser, ASTree tree, boolean includePaddings) {
1058        Token startToken = parser.getToken(tree.getFirstToken());
1059        if (includePaddings) {
1060            Token[] pad = startToken.getPadding();
1061            if (pad.length > 0) {
1062                startToken = pad[0];
1063                for (int i = 0; i < pad.length; i++) {
1064                    if (pad[i].getType() == ParserTokens.EOL) {
1065                        String JavaDoc value = parser.getText(pad[i]);
1066                        return pad[i].getStartOffset() + value.indexOf('\n') + 1;
1067                    }
1068                }
1069            }
1070        }
1071        return startToken.getStartOffset();
1072    }
1073    
1074    protected int getStartOffset2(ASTProvider parser, ASTree tree) {
1075        return getStartOffset(parser, tree, true);
1076    }
1077    
1078    public void getStatementsDiff(List diff, ASTProvider parser, Object JavaDoc[] oldElements, Collection newElements, int endOffset, String JavaDoc separator, String JavaDoc prefixIfNew, int startOffset, boolean includePadds) {
1079        //MethodInfo astInfo = (MethodInfo) getElementInfo();
1080
if (newElements.isEmpty()) {
1081            if (oldElements.length > 0 && prefixIfNew != null) {
1082                diff.add(new DiffElement(startOffset, endOffset, ""));
1083                return;
1084            }
1085        }
1086        Object JavaDoc[] newElementArr=newElements.toArray();
1087        CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr);
1088        boolean isFirst = true;
1089        StringBuffer JavaDoc diffText = null;
1090        int positions[] = matcher.getPositions();
1091        Set deleted = matcher.getDeleted();
1092        int lastOffset = getOffset(0, parser, oldElements, endOffset, includePadds, false);
1093        if (oldElements.length > 0) {
1094            ASTree tree = getChildASTree(oldElements[0]);
1095            Token[] pad = getParser().getToken(tree.getFirstToken()).getPadding();
1096            if (pad.length > 0) {
1097                for (int i = 0; i < pad.length; i++) {
1098                    if (pad[i].getType() == ParserTokens.EOL) {
1099                        lastOffset = pad[i].getStartOffset();
1100                        break;
1101                    }
1102                }
1103            }
1104        }
1105        ASTree lastElement = null;
1106        int newPos = 0;
1107        int oldPos = 0;
1108        for (;newPos<newElementArr.length; newPos++) {
1109            boolean shouldDelete = false;
1110            int newLastOffset = 0;
1111            while (oldPos < oldElements.length && deleted.remove(oldElements[oldPos])) {
1112                if (!shouldDelete) {
1113                    shouldDelete = true;
1114                    if (oldPos != 0) {
1115                        lastOffset = getOffset(oldPos, parser, oldElements, endOffset, true, true);
1116                    }
1117                }
1118                oldPos++;
1119                newLastOffset = getOffset(oldPos, parser, oldElements, endOffset, true, false);
1120                // if we are going to delete all elements from a given element to the last old element,
1121
// we need to adjust the start offset of the deletion, since it should no longer
1122
// be the start offset of the first element to be deleted, but rather the start offset
1123
// of the token immediately following the last element that will not be deleted
1124
// (e.g. to eliminate tokens like colons in the list of parameters)
1125
if (lastElement != null && oldPos == oldElements.length &&
1126                   (separator.trim().length() != 0)) {
1127                    Token took = parser.getToken(lastElement.getLastToken() + 1);
1128                    lastOffset = took.getStartOffset();
1129                    Token[] pads = took.getPadding();
1130                    if (pads != null && pads.length > 0) {
1131                        for (int i = pads.length-1; i >= 0; i--) {
1132                            if (pads[i].getType() == ParserTokens.EOL) {
1133                                lastOffset = pads[i].getStartOffset();
1134                                break;
1135                            }
1136                        }
1137                    }
1138                }
1139            }
1140            if (shouldDelete) {
1141                diff.add(new DiffElement(lastOffset, newLastOffset, ""));
1142                lastOffset = newLastOffset;
1143            }
1144            MetadataElement e = (MetadataElement)newElementArr[newPos];
1145            if (positions[newPos] != oldPos) {
1146                if (diffText == null) {
1147                    if (prefixIfNew == null || oldElements.length > 0) {
1148                        if (oldPos >= oldElements.length && !isFirst) {
1149                            diffText = new StringBuffer JavaDoc(separator);
1150                        } else {
1151                            diffText = new StringBuffer JavaDoc();
1152                        }
1153                    } else {
1154                        diffText = new StringBuffer JavaDoc(prefixIfNew);
1155                    }
1156                } else {
1157                    diffText.append(separator);
1158                }
1159                diffText.append(e.getSourceText());
1160                if (positions[newPos] != -1) {
1161                    deleted.add(oldElements[positions[newPos]]);
1162                }
1163            } else {
1164                if (diffText != null) {
1165                    diffText.append(separator);
1166                    diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
1167                    diffText = null;
1168                }
1169                if (e.isChanged()) {
1170                    e.getDiff(diff);
1171                }
1172                lastElement = getLastElement(oldPos, oldElements);
1173                oldPos++;
1174                lastOffset = getOffset(oldPos, parser, oldElements, endOffset, true, false);
1175                isFirst = false;
1176            }
1177        }
1178        if (oldPos < oldElements.length) {
1179            int newLastOffset = getOffset(oldElements.length, parser, oldElements, endOffset, true, false);
1180            if (lastElement != null) {
1181                lastOffset = getStartOffset2(parser, parser.getToken(lastElement.getLastToken() + 1));
1182            }
1183            diff.add(new DiffElement(lastOffset, newLastOffset, diffText == null ? "" : diffText.toString()));
1184        } else if (diffText != null) {
1185            diff.add(new DiffElement(lastOffset, lastOffset, diffText.toString()));
1186        }
1187    }
1188
1189    void testResourceChange() {
1190        if (((ResourceImpl) getResource()).isChanged()) {
1191            throw new IllegalStateException JavaDoc("The model was modified. Unable to return start offset."); // NOI18N
1192
}
1193    }
1194
1195    /**
1196     * Returns the start offset of the element in the original source text.
1197     *
1198     * @throws IllegalStateException when element was changed
1199     * @return start offset of the element
1200     */

1201    public int getStartOffset() {
1202        _lock();
1203        try {
1204        testResourceChange();
1205        return getStartOffset(getParser(), getASTree(), false);
1206        } finally {
1207            _unlock();
1208    }
1209    }
1210
1211    /**
1212     * Start offset of part of the element.
1213     *
1214     * @param part identifies part of the element, see constants
1215     * @return start offset of given part and position
1216     */

1217    public int getPartStartOffset(ElementPartKind part) {
1218        _lock();
1219        try {
1220        testResourceChange();
1221        return getParser().getToken(getPartStartTree(part).getFirstToken()).getStartOffset();
1222        } finally {
1223            _unlock();
1224    }
1225    }
1226
1227    /**
1228     * Returns the end offset of the element in the original source text.
1229     *
1230     * @return end offset of the element
1231     */

1232    public int getEndOffset() {
1233        _lock();
1234        try {
1235        testResourceChange();
1236        return IndentUtil.getElementEnd(this);
1237        } finally {
1238            _unlock();
1239    }
1240    }
1241
1242    /**
1243     * End offset of part of the element.
1244     *
1245     * @param part identifier part of the element, see constants
1246     * @return end offset of given part and position
1247     */

1248    public int getPartEndOffset(ElementPartKind part) {
1249        _lock();
1250        try {
1251        testResourceChange();
1252        return getParser().getToken(getPartEndTree(part).getLastToken()).getEndOffset();
1253        } finally {
1254            _unlock();
1255    }
1256    }
1257
1258    protected ASTree getPartStartTree(ElementPartKind part) {
1259        return getPartTree(part);
1260    }
1261
1262    protected ASTree getPartEndTree(ElementPartKind part) {
1263        return getPartTree(part);
1264    }
1265
1266    protected ASTree getPartTree(ElementPartKind part) {
1267        throw new IllegalArgumentException JavaDoc("Invalid part for this element: " + part.toString()); // NOI18N
1268
}
1269
1270    protected static int getEndOffset(ASTProvider parser, ASTree tree) {
1271        Token endIndex = parser.getToken(tree.getLastToken());
1272        return endIndex.getEndOffset();
1273    }
1274
1275    private ASTree getASTree(Object JavaDoc o) {
1276        if (o instanceof ElementInfo) {
1277            ElementInfo info = (ElementInfo) o;
1278            Reference JavaDoc sr = info.getASTree();
1279            if (sr == null) return null;
1280
1281            ASTree result = (ASTree) sr.get();
1282            if (result == null) {
1283                try {
1284                    result = info.refreshASTree();
1285                } catch (IllegalArgumentException JavaDoc ex) {
1286                    StringBuffer JavaDoc report=new StringBuffer JavaDoc(100);
1287                    MetadataElement el=this;
1288                    
1289                    do {
1290                        report.append(el.getClass()).append(" ");
1291                        if (el instanceof NamedElement && el.isValid()) {
1292                            report.append(((NamedElement)el).getName()).append(" ");
1293                        }
1294                        report.append("valid:").append(el.isValid()).append(" | ");
1295                        Object JavaDoc obj = el.refImmediateComposite();
1296                        el = obj instanceof MetadataElement ? (MetadataElement)obj : null;
1297                    } while(el!=null);
1298                    throw new IllegalArgumentException JavaDoc(ex.getMessage()+" "+report.toString());
1299                }
1300            }
1301            return result;
1302        } else if (o instanceof ASTree) {
1303            return (ASTree) o;
1304        } else {
1305            return null;
1306        }
1307    }
1308
1309    private ASTree getChildASTree(Object JavaDoc o) {
1310        return getASTree(o);
1311    }
1312
1313    private ASTree getLastElement(int index, Object JavaDoc[] oldElements) {
1314        if (oldElements.length <= index) {
1315            return null;
1316        }
1317        return getChildASTree(oldElements[index]);
1318    }
1319
1320    protected final Element initOrCreate(Element element, ASTree tree) {
1321        boolean changes = disableChanges;
1322        disableChanges = true;
1323        try {
1324            if (element != null) {
1325                if (element instanceof TransientElement) {
1326                    if (tree != null) {
1327                        RefClass proxy = getElementProxy(tree);
1328                        if (element.refClass().equals(proxy)) {
1329                            ((TransientElement) element).init(tree);
1330                            return element;
1331                        }
1332                    }
1333                    ((TransientElement) element).invalidate();
1334                } else { // local class
1335
element.refDelete();
1336                }
1337            }
1338            return createElement(tree);
1339        } finally {
1340            disableChanges = changes;
1341        }
1342    }
1343
1344    public final boolean isTransient() {
1345        return _getDelegate() instanceof DeferredObject;
1346    }
1347    
1348    public final boolean checkElementType(ElementInfo astInfo, Element element) {
1349        switch (astInfo.infoType) {
1350            case FieldInfo.FIELD_TYPE:
1351                return (element instanceof Field) && !(element instanceof EnumConstant);
1352            case FieldGroupInfo.FIELDGROUP_TYPE:
1353                return element instanceof FieldGroup;
1354            case EnumInfo.ENUM_TYPE:
1355                return element instanceof JavaEnum;
1356            case ClassInfo.INTERFACE_TYPE:
1357            case ClassInfo.CLASS_TYPE:
1358                return (element instanceof JavaClass) && !(element instanceof AnnotationType) && !(element instanceof JavaEnum);
1359            case AnnotationTypeInfo.ANNOTATIONTYPE_TYPE:
1360                return element instanceof AnnotationType;
1361            case ClassInfo.ANON_CLASS_TYPE:
1362                return (element instanceof ClassDefinition) && !(element instanceof JavaClass);
1363            case MethodInfo.METHOD_TYPE:
1364                return element instanceof Method;
1365            case FeatureInfo.INSTANCE_INITIALIZER_TYPE:
1366            case FeatureInfo.STATIC_INITIALIZER_TYPE:
1367                return element instanceof Initializer;
1368            case MethodInfo.CONSTRUCTOR_TYPE:
1369                return element instanceof Constructor;
1370            case ElementInfo.IMPORT_ON_DEMAND_TYPE:
1371            case ElementInfo.SINGLE_IMPORT_TYPE:
1372                return element instanceof Import;
1373            case ParameterInfo.PARAMETER_TYPE:
1374                return element instanceof Parameter;
1375            case TypeParamInfo.TYPEPARAM_TYPE:
1376                return element instanceof TypeParameter;
1377            case FeatureInfo.ENUM_CONSTANT_TYPE:
1378                return element instanceof EnumConstant;
1379            case AttributeInfo.ATTRIBUTE_TYPE:
1380                return element instanceof Attribute;
1381            case AnnotationInfo.ANNOTATION_TYPE:
1382                return element instanceof Annotation;
1383            default:
1384                throw new IllegalArgumentException JavaDoc("Illegal type "+astInfo.infoType); // NOI18N
1385
}
1386    }
1387    
1388    public final SemiPersistentElement createElement(ElementInfo astInfo) {
1389        return createElement(astInfo, true);
1390    }
1391
1392    protected final SemiPersistentElement createElement(ElementInfo astInfo, boolean initialize) {
1393        if (astInfo == null) return null;
1394        JavaModelPackage extent = (JavaModelPackage) refImmediatePackage();
1395        SemiPersistentElement element=null;
1396        boolean isTransient = isTransient();
1397        
1398        switch (astInfo.infoType) {
1399            case FieldInfo.FIELD_TYPE: {
1400                FieldInfo info = (FieldInfo) astInfo;
1401                element = ((FieldClassImpl) extent.getField()).create(info.name, info.modifiers, info.type, isTransient);
1402                break;
1403            } case FieldGroupInfo.FIELDGROUP_TYPE: {
1404                FieldGroupInfo info = (FieldGroupInfo) astInfo;
1405                element = ((FieldGroupClassImpl) extent.getFieldGroup()).create(info.modifiers, info.type, isTransient);
1406                break;
1407            } case EnumInfo.ENUM_TYPE:
1408                if (isTransient) {
1409                    ASTree tree=getASTree(astInfo);
1410                    MDRParser parser=(MDRParser) tree.getASTContext();
1411                    element = (JavaClassImpl)parser.getSemanticInfo(tree,this);
1412                } else {
1413                    ClassIndex index=ClassIndex.getIndex(extent);
1414
1415                    Set classes = index.getClassesByFqn(astInfo.name);
1416                    for (Iterator it = classes.iterator(); it.hasNext();) {
1417                        JavaClassImpl temp = (JavaClassImpl) it.next();
1418                        if (temp.isValid()) {
1419                            Object JavaDoc composite = temp.refImmediateComposite();
1420                            if (composite == null || this.equals(composite)) {
1421                                element = temp;
1422                                break;
1423                            }
1424                        }
1425                    }
1426                    if (element == null) {
1427                        element = recoverFromCNFII(astInfo, extent.getJavaEnum());
1428                    }
1429                }
1430                break;
1431            case ClassInfo.INTERFACE_TYPE:
1432            case ClassInfo.CLASS_TYPE:
1433                if (isTransient) {
1434                    ASTree tree=getASTree(astInfo);
1435                    MDRParser parser=(MDRParser) tree.getASTContext();
1436                    element = (JavaClassImpl)parser.getSemanticInfo(tree,this);
1437                } else {
1438                    ClassIndex index=ClassIndex.getIndex(extent);
1439
1440                    Set classes = index.getClassesByFqn(astInfo.name);
1441                    for (Iterator it = classes.iterator(); it.hasNext();) {
1442                        JavaClassImpl temp = (JavaClassImpl) it.next();
1443                        if (temp.isValid()) {
1444                            Object JavaDoc composite = temp.refImmediateComposite();
1445                            if (composite == null || this.equals(composite)) {
1446                                element = temp;
1447                                break;
1448                            }
1449                        }
1450                    }
1451                    if (element == null) {
1452                        element = recoverFromCNFII(astInfo, extent.getJavaClass());
1453                    }
1454                }
1455                break;
1456            case AnnotationTypeInfo.ANNOTATIONTYPE_TYPE:
1457                if (isTransient) {
1458                    ASTree tree=getASTree(astInfo);
1459                    MDRParser parser=(MDRParser) tree.getASTContext();
1460                    element = (JavaClassImpl)parser.getSemanticInfo(tree,this);
1461                } else {
1462                    ClassIndex index=ClassIndex.getIndex(extent);
1463
1464                    Set classes = index.getClassesByFqn(astInfo.name);
1465                    for (Iterator it = classes.iterator(); it.hasNext();) {
1466                        JavaClassImpl temp = (JavaClassImpl) it.next();
1467                        if (temp.isValid()) {
1468                            Object JavaDoc composite = temp.refImmediateComposite();
1469                            if (composite == null || this.equals(composite)) {
1470                                element = temp;
1471                                break;
1472                            }
1473                        }
1474                    }
1475                    if (element == null) {
1476                        element = recoverFromCNFII(astInfo, extent.getAnnotationType());
1477                    }
1478                }
1479                break;
1480            case ClassInfo.ANON_CLASS_TYPE:
1481                element = ((ClassDefinitionClassImpl) extent.getClassDefinition()).create();
1482                break;
1483            case MethodInfo.METHOD_TYPE: {
1484                MethodInfo info = (MethodInfo) astInfo;
1485                element = ((MethodClassImpl) extent.getMethod()).create(info.name, info.modifiers, info.type, info.exceptions, isTransient);
1486                break;
1487            } case FeatureInfo.INSTANCE_INITIALIZER_TYPE:
1488            case FeatureInfo.STATIC_INITIALIZER_TYPE:
1489                element = ((InitializerClassImpl) extent.getInitializer()).create(((FeatureInfo) astInfo).modifiers, isTransient);
1490                break;
1491            case MethodInfo.CONSTRUCTOR_TYPE: {
1492                MethodInfo info = (MethodInfo) astInfo;
1493                element = ((ConstructorClassImpl) extent.getConstructor()).create(info.modifiers, info.exceptions, isTransient);
1494                break;
1495            } case ElementInfo.IMPORT_ON_DEMAND_TYPE:
1496            case ElementInfo.SINGLE_IMPORT_TYPE:
1497                element = ((ImportClassImpl)extent.getImport()).create(astInfo.name, null, false, astInfo.infoType == ElementInfo.IMPORT_ON_DEMAND_TYPE, (ResourceImpl)this);
1498                break;
1499            case ParameterInfo.PARAMETER_TYPE: {
1500                ParameterInfo info = (ParameterInfo) astInfo;
1501                element = ((ParameterClassImpl) extent.getParameter()).create(info.name, info.isFinal, info.isVarArg, info.type, isTransient);
1502                break;
1503            } case TypeParamInfo.TYPEPARAM_TYPE: {
1504                TypeParamInfo info = (TypeParamInfo) astInfo;
1505                element = ((TypeParameterClassImpl) extent.getTypeParameter()).create(info.name, info.bounds, isTransient);
1506                break;
1507            } case FeatureInfo.ENUM_CONSTANT_TYPE:
1508                element = ((EnumConstantClassImpl) extent.getEnumConstant()).create(astInfo.name, isTransient);
1509                break;
1510            case AttributeInfo.ATTRIBUTE_TYPE:
1511                element = ((AttributeClassImpl) extent.getAttribute()).create(astInfo.name, ((AttributeInfo) astInfo).modifiers, ((AttributeInfo) astInfo).type, isTransient);
1512                break;
1513            case AnnotationInfo.ANNOTATION_TYPE:
1514                element = ((AnnotationClassImpl) extent.getAnnotation()).create(isTransient);
1515                break;
1516            case AnnotationValueInfo.ANNOTATIONVALUE_ANNOTATION:
1517            case AnnotationValueInfo.ANNOTATIONVALUE_ARRAY:
1518            case AnnotationValueInfo.ANNOTATIONVALUE_STRING:
1519                element = ((AttributeValueClassImpl) extent.getAttributeValue()).create(astInfo.name,isTransient);
1520                break;
1521            default:
1522                throw new IllegalArgumentException JavaDoc("Illegal type "+astInfo.infoType); // NOI18N
1523
}
1524        element.updatePersistent(astInfo);
1525        if (initialize) {
1526            element.setElementInfo(astInfo);
1527        }
1528        return element;
1529    }
1530    
1531    private static SemiPersistentElement recoverFromCNFII(ElementInfo info, RefClass classProxy) {
1532        JMManager.getLog().notify(ErrorManager.INFORMATIONAL, new Exception JavaDoc("Class not found in index: " + info.name + ". Recovering...")); // NOI18N
1533
if (classProxy instanceof JavaEnumClassImpl) {
1534            return ((JavaEnumClassImpl) classProxy).create(info.name, ((EnumInfo) info).modifiers, false);
1535        } else if (classProxy instanceof AnnotationTypeClassImpl) {
1536            return ((AnnotationTypeClassImpl) classProxy).create(info.name, ((ClassInfo) info).modifiers, false);
1537        } else {
1538            return ((JavaClassClassImpl) classProxy).create(info.name, ((ClassInfo) info).modifiers, ((ClassInfo) info).superclass, ((ClassInfo) info).interfaces, false);
1539        }
1540    }
1541
1542    public static ASTree[] getChildNodes(ASTree parent, int groupNodeType) {
1543        if (parent == null) {
1544            return new ASTree[0];
1545        } else if (parent.getType() == groupNodeType) {
1546            return parent.getSubTrees();
1547        } else {
1548            return new ASTree[] {parent};
1549        }
1550    }
1551    
1552    public Type resolveType(TypeRef typeRef) {
1553        if (typeRef == null) return null;
1554        
1555        JavaModelPackage extent = (JavaModelPackage) refImmediatePackage();
1556        if (typeRef instanceof LocalClassNameRef) {
1557            LocalClassNameRef locRef=(LocalClassNameRef)typeRef;
1558            
1559            return (Type)JavaMetamodel.getDefaultRepository().getByMofId(locRef.mofId);
1560        } else if (typeRef instanceof NameRef) {
1561            NameRef nRef = (NameRef) typeRef;
1562            JavaClass parent = (JavaClass) resolveType(nRef.parent);
1563            ArrayList args = new ArrayList(nRef.args.length);
1564            boolean hasWildCard = false;
1565            for (int i = 0; i < nRef.args.length; i++) {
1566                args.add(resolveType(nRef.args[i]));
1567                if (nRef.args[i] instanceof WildCardRef) {
1568                    hasWildCard = true;
1569                }
1570            }
1571            JavaClass definition;
1572            if (parent != null) {
1573                definition = parent.getInnerClass(nRef.name, true);
1574                if (definition == null) {
1575                    definition = ((UnresolvedClassClassImpl) extent.getUnresolvedClass()).resolveUnresolved(nRef.name);
1576                }
1577            } else {
1578                definition = ((JavaClassClassImpl) extent.getJavaClass()).resolveClass(nRef.name, false);
1579            }
1580            if ((definition instanceof AnnotationType) && (parent == null) && (args.size() == 0)) {
1581                return definition;
1582            }
1583            if (!(parent instanceof ParameterizedType)) {
1584                parent = null;
1585            }
1586            ParameterizedTypeClass parTypeClass = ((JavaModelPackage)definition.refImmediatePackage()).getParameterizedType();
1587            ParameterizedTypeImpl result = (ParameterizedTypeImpl) parTypeClass.resolveParameterizedType(definition, args, (ParameterizedType)parent);
1588            if (hasWildCard) {
1589                for (int i = 0; i < nRef.args.length; i++) {
1590                    if (nRef.args[i] instanceof WildCardRef) {
1591                        WildCardRef wcRef = (WildCardRef) nRef.args[i];
1592                        result.setWildCardStatus(i, wcRef.bound == null ? 3 : (wcRef.isLower ? 1 : 2));
1593                    }
1594                }
1595            }
1596            return result;
1597        } else if (typeRef instanceof ArrayRef) {
1598            ArrayRef aRef = (ArrayRef) typeRef;
1599            Type result = resolveType(aRef.parent);
1600            ArrayClass arrClass = ((JavaModelPackage)result.refImmediatePackage()).getArray();
1601            for (int i = 0; i < aRef.dimCount; i++) {
1602                result = arrClass.resolveArray(result);
1603            }
1604            return result;
1605        } else if (typeRef instanceof TypeParamRef) {
1606            TypeParamRef tpRef = (TypeParamRef) typeRef;
1607            Element element=this;
1608            while (!((element instanceof Resource) || element == null)) {
1609                if (element instanceof GenericElement) {
1610                    GenericElement gel=(GenericElement)element;
1611                    Iterator typeParsIt=gel.getTypeParameters().iterator();
1612                    
1613                    while(typeParsIt.hasNext()) {
1614                        TypeParameter typePar=(TypeParameter)typeParsIt.next();
1615                        
1616                        if (typePar.getName().equals(tpRef.name))
1617                            return typePar;
1618
1619                    }
1620                }
1621                element=(Element)element.refImmediateComposite();
1622            }
1623            // type parameter not found, create unresolved class - this is OK - this case happens when parsing the file and parser
1624
// is resolving the identifiers
1625
return ((JavaClassClassImpl) extent.getJavaClass()).resolveClass(tpRef.name, false);
1626        } else if (typeRef instanceof PrimitiveTypeRef) {
1627            PrimitiveTypeRef ptRef = (PrimitiveTypeRef) typeRef;
1628            return ((PrimitiveTypeClassImpl) extent.getPrimitiveType()).resolveType(ptRef.name);
1629        } else if (typeRef instanceof WildCardRef) {
1630            WildCardRef wcRef = (WildCardRef) typeRef;
1631            if (wcRef.bound != null) {
1632                return resolveType(wcRef.bound);
1633            }
1634            return resolveType(NameRef.java_lang_Object);
1635        }
1636        throw new IllegalStateException JavaDoc();
1637    }
1638
1639    /**
1640     * Returns indentation of the element. Every element, which should be
1641     * indented has to override this method.
1642     *
1643     * @return indentation for element.
1644     */

1645    protected String JavaDoc getIndentation() {
1646        return "";
1647    }
1648
1649    // temporary part - should be read from options
1650
static String JavaDoc[][] data = null;
1651    static String JavaDoc[] EMPTY = { null, null, null };
1652    static {
1653        //
1654
data = new String JavaDoc[][] {
1655            EMPTY, // 0 EMPTY
1656
{ "s", "{", "n" }, // 1 BODY_OPEN_CURLY // NOI18N
1657
{ "i", "}", "" }, // 2 BODY_CLOSE_CURLY // NOI18N
1658
{ "", "(", "" }, // 3 PAR_OPEN_BRACKET // NOI18N
1659
{ "", ")", "" }, // 4 PAR_CLOSE_BRACKET // NOI18N
1660
{ "", ",", "s" }, // 5 COMMA // NOI18N
1661
{ null, null, null }, // 6 CALLABLE_IDENTIFIER
1662
{ "s" , "throws", "s" }, // 7 THROWS_KEYWORD // NOI18N
1663
{ "s", "=", "s" }, // 8 FIELD_EQUALS // NOI18N
1664
{ "s", "extends", "s" }, // 9 EXTENDS_KEYWORD // NOI18N
1665
{ "s", "implements", "s" },// 10 IMPLEMENTS_KEYWORD // NOI18N
1666
{ "s", "{", "n" }, // 11 CLASS_OPEN_CURLY // NOI18N
1667
{ "i", "}", "n" }, // 12 CLASS_CLOSE_CURLY // NOI18N
1668
{ "", "[", "" }, // 13 ARRAY_OPEN_BRACKET // NOI18N
1669
{ "", "]", "" }, // 14 ARRAY_CLOSE_BRACKET // NOI18N
1670
{ "", "{", "" }, // 15 ARRAY_OPEN_CURLY // NOI18N
1671
{ "", "}", "" }, // 16 ARRAY_CLOSE_CURLY // NOI18N
1672
{ "i", "assert", "s" }, // 17 ASSERT_KEYWORD // NOI18N
1673
{ "s", "catch", "s" }, // 18 CATCH_KEYWORD // NOI18N
1674
{ "", "(", "" }, // 19 STMT_OPEN_BRACKET // NOI18N
1675
{ "", ")", "" }, // 20 STMT_CLOSE_BRACKET // NOI18N
1676
{ "i", "case", "s" }, // 21 CASE_KEYWORD // NOI18N
1677
{ "i", "default", ":" }, // 22 DEFAULT_KEYWORD // NOI18N
1678
{ "s", "?", "s" }, // 23 COND_EXPR_QUESTION // NOI18N
1679
{ "s", ":", "s" }, // 24 COND_EXPR_COLON // NOI18N
1680
{ "i", "do", "s" }, // 25 DO_KEYWORD // NOI18N
1681
{ "s", "while", "s" }, // 26 DO_WHILE_KEYWORD // NOI18N
1682
{ "", "for", "s" }, // 27 FOR_KEYWORD // NOI18N
1683
{ "", ";", "s" }, // 28 FOR_SEMICOLON // NOI18N
1684
{ "", "if", "s" }, // 29 IF_KEYWORD // NOI18N
1685
{ "s", "else", "" }, // 30 ELSE_KEYWORD // NOI18N
1686
{ "", "", "" }, // 31 --- not used ---
1687
{ "s", "{", "" }, // 32 BLOCK_OPEN_CURLY // NOI18N
1688
{ "ni", "}", "" }, // 33 BLOCK_CLOSE_CURLY // NOI18N
1689
{ "i", "switch", "s" }, // 34 SWITCH_KEYWORD // NOI18N
1690
{ "i", "synchronized", "s" },// 35 SYNCHRONIZED_KEYWORD // NOI18N
1691
{ "", "throw", "s" }, // 36 THROW_KEYWORD // NOI18N
1692
{ "", "try", "" }, // 37 TRY_KEYWORD // NOI18N
1693
{ "s", "finally", "" }, // 38 FINALLY_KEYWORD // NOI18N
1694
{ "", "while", "s" }, // 39 WHILE_KEYWORD // NOI18N
1695
{ "i", "}", "" } // 40 ANON_CLASS_CLOSE_CURLY // NOI18N
1696
};
1697    }
1698    // end temporary
1699

1700    // formatting constants
1701
public static final int BODY_OPEN_CURLY = 1;
1702    public static final int BODY_CLOSE_CURLY = 2;
1703    public static final int PAR_OPEN_BRACKET = 3;
1704    public static final int PAR_CLOSE_BRACKET = 4;
1705    public static final int COMMA = 5;
1706    public static final int CALLABLE_IDENTIFIER = 6;
1707    public static final int THROWS_KEYWORD = 7;
1708    public static final int FIELD_EQUALS = 8;
1709    public static final int EXTENDS_KEYWORD = 9;
1710    public static final int IMPLEMENTS_KEYWORD = 10;
1711    public static final int CLASS_OPEN_CURLY = 11;
1712    public static final int CLASS_CLOSE_CURLY = 12;
1713    public static final int ARRAY_OPEN_BRACKET = 13;
1714    public static final int ARRAY_CLOSE_BRACKET = 14;
1715    public static final int ARRAY_OPEN_CURLY = 15;
1716    public static final int ARRAY_CLOSE_CURLY = 16;
1717    public static final int ASSERT_KEYWORD = 17;
1718    public static final int CATCH_KEYWORD = 18;
1719    public static final int STMT_OPEN_BRACKET = 19;
1720    public static final int STMT_CLOSE_BRACKET = 20;
1721    public static final int CASE_KEYWORD = 21;
1722    public static final int DEFAULT_KEYWORD = 22;
1723    public static final int COND_EXPR_QUESTION = 23;
1724    public static final int COND_EXPR_COLON = 24;
1725    public static final int DO_KEYWORD = 25;
1726    public static final int DO_WHILE_KEYWORD = 26;
1727    public static final int FOR_KEYWORD = 27;
1728    public static final int FOR_SEMICOLON = 28;
1729    public static final int IF_KEYWORD = 29;
1730    public static final int ELSE_KEYWORD = 30;
1731    public static final int BLOCK_OPEN_CURLY = 32;
1732    public static final int BLOCK_CLOSE_CURLY = 33;
1733    public static final int SWITCH_KEYWORD = 34;
1734    public static final int SYNCHRONIZED_KEYWORD = 35;
1735    public static final int THROW_KEYWORD = 36;
1736    public static final int TRY_KEYWORD = 37;
1737    public static final int FINALLY_KEYWORD = 38;
1738    public static final int WHILE_KEYWORD = 39;
1739    public static final int ANON_CLASS_CLOSE_CURLY = 40;
1740    
1741    /**
1742     * Looks for the formatting used for defined element (type). Puts
1743     * source representation to the parameter buffer. If the data are not
1744     * available for the specified formatting type, it throws exception.
1745     *
1746     * @param type represents type of element which should be formatted
1747     * @throws IllegalArgumentException if the formatting for the type
1748     * is not available or the formatting data are not accessible
1749     */

1750    protected final void formatElementPart(int type, StringBuffer JavaDoc buf) throws IllegalArgumentException JavaDoc {
1751        if (data == null || type >= data.length) {
1752            throw new IllegalArgumentException JavaDoc("Format data for the argument " + // NOI18N
1753
"type #" + type + " not available or formatting data are not " + // NOI18N
1754
"accessible."); // NOI18N
1755
}
1756        // prints leading formatting
1757
format(data[type][0], buf);
1758        // prints token representation
1759
if (data[type][1] != null)
1760            buf.append(data[type][1]);
1761        // prints trailing formatting
1762
format(data[type][2], buf);
1763    }
1764
1765    /**
1766     * @see ...
1767     * @return formatted element part
1768     */

1769    protected final String JavaDoc formatElementPart(int type) {
1770        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1771        formatElementPart(type, buf);
1772        return buf.toString();
1773    }
1774    
1775    protected void formatElementPart(int type, StringBuffer JavaDoc buf, boolean isNew) {
1776        if (isNew)
1777            formatElementPart(type, buf);
1778        else
1779            buf.append(data[type][1]);
1780    }
1781    
1782    /**
1783     *
1784     * @return
1785     */

1786    String JavaDoc getElementPrefix(int type) {
1787        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(64);
1788        format(data[type][0], buf);
1789        return buf.toString();
1790    }
1791
1792    /**
1793     * Sets the text used before the element and after the
1794     * element. See ... how strings are interpreted.
1795     */

1796    public static final void setFormattingFor(int type, String JavaDoc pre, String JavaDoc post) {
1797        data[type][0] = pre;
1798        data[type][2] = post;
1799    }
1800
1801    /**
1802     * Returns the array of the three strings:
1803     * Characters before the text,
1804     * formatted text,
1805     * characters after the text.
1806     *
1807     * @return array of strings
1808     */

1809    public static final String JavaDoc[] getFormattingFor(int type) {
1810        return data[type];
1811    }
1812
1813    /**
1814     * Creates whitespaces from the formatting mask.
1815     * Format characters representation:
1816     * n ... new line ('\n') character
1817     * i ... indentation
1818     * s ... space
1819     *
1820     * @param mask represents formatting mask
1821     * @param buf buffer to append whitespaces to
1822     *
1823     * @return if anything was added to the buffer
1824     */

1825    private boolean format(String JavaDoc mask, StringBuffer JavaDoc buf) {
1826        if (mask == null || mask.length() == 0)
1827            return false;
1828
1829        char[] c = mask.toCharArray();
1830        for (int i = 0; i < c.length; i++) {
1831            switch (c[i]) {
1832                case 'n':
1833                    buf.append('\n');
1834                    break;
1835                case 's':
1836                    buf.append(' ');
1837                    break;
1838                case 'i':
1839                    buf.append(getIndentation());
1840                    break;
1841            }
1842        }
1843        return true;
1844    }
1845
1846    protected StringBuffer JavaDoc appendDims(StringBuffer JavaDoc buf, int dimCount) {
1847        for (int i = 0; i < dimCount; i++) {
1848            formatElementPart(ARRAY_OPEN_BRACKET, buf);
1849            formatElementPart(ARRAY_CLOSE_BRACKET, buf);
1850        }
1851        return buf;
1852    }
1853
1854    /**
1855     * Sets the default indentation of the element.
1856     *
1857     * @param spaces number of spaces used for indentation
1858     * @param expandTabs if this parameter is true, tab character is used
1859     * instead of spaces
1860     */

1861    public static void setIndentSpace(int spaces, boolean expandTabs) {
1862        if (!expandTabs) {
1863            // user want to use \t character instead of spaces
1864
INDENTATION = "\t"; // NOI18N
1865
} else {
1866            if (spaces >= 0) {
1867                spacesPerTab = spaces;
1868                char[] buf = new char[spaces];
1869                Arrays.fill(buf, ' ');
1870                INDENTATION = new String JavaDoc(buf);
1871            }
1872        }
1873    }
1874    
1875    public static boolean isExpandTab() {
1876        return !INDENTATION.equals("\t"); // NOI18N
1877
}
1878    
1879    public static int getIndentSpace() {
1880        return spacesPerTab;
1881    }
1882    
1883    protected RefFeatured _immediateComposite() {
1884        return getRealComposite(super._immediateComposite());
1885    }
1886    
1887    protected RefFeatured _realImmediateComposite() {
1888        return super._immediateComposite();
1889    }
1890
1891    protected RefFeatured _outermostComposite() {
1892        return getRealComposite(super._outermostComposite());
1893    }
1894
1895    private RefFeatured getRealComposite(RefFeatured refFeatured) {
1896        if (refFeatured instanceof JavaPackage) {
1897            JavaPackage pkg = (JavaPackage) refFeatured;
1898            return ((JavaPackageClass) pkg.refClass()).resolvePackage(pkg.getName());
1899        } else {
1900            return refFeatured;
1901        }
1902    }
1903
1904    void childChanged(MetadataElement element) {
1905    }
1906
1907    protected final void removeChild(MetadataElement element) {
1908        replaceChild(element, null);
1909    }
1910
1911    public void replaceChild(Element oldElement, Element newElement) {
1912    }
1913
1914    protected final boolean replaceObject(List list, Element oldElement, Element newElement) {
1915        int index=list.indexOf(oldElement);
1916
1917        if (index!=-1) {
1918            if (newElement==null)
1919                list.remove(index);
1920            else
1921                list.set(index,newElement);
1922            return true;
1923        }
1924        return false;
1925    }
1926    
1927    static void fixImportsInClassList(Element scope,List newEl,List origEls) {
1928        Iterator fIt=origEls.iterator();
1929
1930        if (fIt.hasNext()) {
1931            newEl.clear();
1932            while(fIt.hasNext()) {
1933                newEl.add(JavaModelUtil.resolveImportsForClass(scope,(JavaClass)fIt.next()));
1934            }
1935        }
1936    }
1937    
1938    static void fixImports(Element scope, List newEl, List origEls) {
1939        List nels=new ArrayList(newEl);
1940        List oels=new ArrayList(origEls);
1941        int size = nels.size();
1942        
1943        for (int i=0;i<size;i++) {
1944            Element oe=(Element)oels.get(i);
1945            MetadataElement ne=(MetadataElement)nels.get(i);
1946            
1947            ne.fixImports(scope,oe);
1948        }
1949    }
1950    
1951    public void fixImports(Element scope,Element original) {
1952        fixImports(scope, getChildren(), original.getChildren());
1953    }
1954    
1955    /**
1956     * Duplicates elements in list provided in parameter and returns
1957     * ArrayList with the elements' duplicates.
1958     *
1959     * @param list original list with elements, which should be duplicated
1960     * @return new list with duplicated elements.
1961     */

1962    static List duplicateList(List list, JavaModelPackage targetExtent) {
1963        if (list == null) {
1964            return Collections.EMPTY_LIST;
1965        }
1966        Object JavaDoc[] elements=list.toArray();
1967        int size = elements.length;
1968        if (size == 0) {
1969            return Collections.EMPTY_LIST;
1970        }
1971        List result = new ArrayList(size);
1972        for (int i=0;i<elements.length;i++) {
1973            Object JavaDoc o = elements[i];
1974            result.add(((MetadataElement) o).duplicate(targetExtent));
1975        }
1976        return result;
1977    }
1978    
1979    /**
1980     * Duplicates provided element by calling duplicate() method on them.
1981     * Method is provided only for null value handling.
1982     *
1983     * @param element which has to be duplicated
1984     * @return duplicated element or null
1985     */

1986    static Element duplicateElement(Element e, JavaModelPackage targetExtent) {
1987        return e == null ? null : ((MetadataElement) e).duplicate(targetExtent);
1988    }
1989    
1990    public Element duplicate() {
1991        return duplicate((JavaModelPackage) refImmediatePackage());
1992    }
1993
1994    public abstract Element duplicate(JavaModelPackage targetExtent);
1995}
1996
Popular Tags