1 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 ; 44 import java.util.*; 45 46 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 protected static String INDENTATION = " "; 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 if (parent != null) 146 parent.initChildren(); 147 } 148 } 149 } 150 151 private void throwInvalidObject() { 152 throw new InvalidObjectException(null, "Object was deleted."); } 154 155 protected void _delete() { 156 MetadataElement parent = (MetadataElement) refImmediateComposite(); 158 if (parent != null) { 159 parent.removeChild(this); 160 } 161 168 isValid = false; 169 } 170 171 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 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 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 217 public boolean isValid() { 218 return isValid; 219 } 220 221 protected abstract Object 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 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(); if (disableChanges) return; 257 if (!isChanged()) { 258 if (!childrenInited) { 259 initChildren(); 261 } 262 Object parent = refImmediateComposite(); 263 if (parent != null && parent instanceof MetadataElement) { 264 ((MetadataElement) parent).objectChanged(getParentChangedMask(mask)); 265 } 266 } 267 changes |= mask; 268 } 269 270 278 protected final String checkChange() { 279 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 Object 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 } 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 text = p.getSourceText().substring(b, e); 341 int tokenId = getASTree().getFirstToken(); 342 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 392 protected final LightAttrList createChildrenList(LightAttrList currentList, String attrName, ASTree tree, int groupNodeType, int changeMask, boolean rebuild) { 393 return createChildrenList(currentList, attrName, getChildNodes(tree, groupNodeType), changeMask, rebuild); 394 } 395 396 397 protected final LightAttrList createChildrenList(LightAttrList currentList, String 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 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 454 protected final LightAttrList createChildrenList(String 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 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 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 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 ) { 665 return pkg.getLongLiteral(); 666 } else { 667 return pkg.getIntLiteral(); 668 } 669 case ParserTokens.FLOAT_LIT: 670 if (((Token) tree).getValue() instanceof Float ) { 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 ("Unexpected type of ASTree: " + type); } 696 } 697 698 705 public String getSourceText() { 706 String origElem; 707 if ((origElem = checkChange()) != null) 708 return origElem; 709 else { 710 if (isNew()) { 711 return IndentUtil.indentNewElement(this); 712 } else { 713 if (this instanceof Statement && !(this instanceof StatementBlock) && 715 !(this instanceof JavaClass) && 716 !(this instanceof LocalVarDeclaration && refImmediateComposite() instanceof ForStatement)) 717 { 718 StringBuffer buf = new StringBuffer (256); 719 IndentUtil.reformatHeadGarbage(this, buf); 720 buf.append(getRawText()); 721 722 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 getRawText(); 741 742 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 text, int start, String 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 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 [] 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 [] oldElements, Collection newElements, int endOffset, String 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 [] oldElements, Collection newElements, int endOffset, String 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 separator, String 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 separator, String 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 [] oldElements, Collection newElements, int endOffset, String separator, String prefixIfNew, int startOffset, boolean includePadds) { 838 if (newElements.isEmpty()) { 840 if (oldElements.length > 0 && prefixIfNew != null) { 841 diff.add(new DiffElement(startOffset, endOffset, "")); 842 return; 843 } 844 } 845 Object [] newElementArr=newElements.toArray(); 846 CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr); 847 boolean isFirst = true; 848 StringBuffer 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 (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 (separator); 895 } else { 896 diffText = new StringBuffer (); 897 } 898 } else { 899 diffText = new StringBuffer (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 [] 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 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 [] oldElements, Collection newElements, int endOffset, int endOffset2, String separator, boolean includePadds, int changeMask) { 959 if (!isChanged(changeMask) && isChanged(CHANGED_CHILDREN)) { 960 getElementsDiff(diff, newElements); 961 return; 962 } 963 Object [] newElementArr=newElements.toArray(); 964 CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr); 965 boolean isFirst = true; 966 StringBuffer 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 (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 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 (separator); 1012 } else { 1013 diffText = new StringBuffer (); 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 [] 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 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 [] oldElements, Collection newElements, int endOffset, String separator, String prefixIfNew, int startOffset, boolean includePadds) { 1079 if (newElements.isEmpty()) { 1081 if (oldElements.length > 0 && prefixIfNew != null) { 1082 diff.add(new DiffElement(startOffset, endOffset, "")); 1083 return; 1084 } 1085 } 1086 Object [] newElementArr=newElements.toArray(); 1087 CollectionMatcher matcher = new CollectionMatcher(oldElements, newElementArr); 1088 boolean isFirst = true; 1089 StringBuffer 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 (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 (separator); 1150 } else { 1151 diffText = new StringBuffer (); 1152 } 1153 } else { 1154 diffText = new StringBuffer (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 ("The model was modified. Unable to return start offset."); } 1193 } 1194 1195 1201 public int getStartOffset() { 1202 _lock(); 1203 try { 1204 testResourceChange(); 1205 return getStartOffset(getParser(), getASTree(), false); 1206 } finally { 1207 _unlock(); 1208 } 1209 } 1210 1211 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 1232 public int getEndOffset() { 1233 _lock(); 1234 try { 1235 testResourceChange(); 1236 return IndentUtil.getElementEnd(this); 1237 } finally { 1238 _unlock(); 1239 } 1240 } 1241 1242 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 ("Invalid part for this element: " + part.toString()); } 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 o) { 1276 if (o instanceof ElementInfo) { 1277 ElementInfo info = (ElementInfo) o; 1278 Reference 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 ex) { 1286 StringBuffer report=new StringBuffer (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 obj = el.refImmediateComposite(); 1296 el = obj instanceof MetadataElement ? (MetadataElement)obj : null; 1297 } while(el!=null); 1298 throw new IllegalArgumentException (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 o) { 1310 return getASTree(o); 1311 } 1312 1313 private ASTree getLastElement(int index, Object [] 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 { 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 ("Illegal type "+astInfo.infoType); } 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 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 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 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 ("Illegal type "+astInfo.infoType); } 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 ("Class not found in index: " + info.name + ". Recovering...")); 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 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 (); 1637 } 1638 1639 1645 protected String getIndentation() { 1646 return ""; 1647 } 1648 1649 static String [][] data = null; 1651 static String [] EMPTY = { null, null, null }; 1652 static { 1653 data = new String [][] { 1655 EMPTY, { "s", "{", "n" }, { "i", "}", "" }, { "", "(", "" }, { "", ")", "" }, { "", ",", "s" }, { null, null, null }, { "s" , "throws", "s" }, { "s", "=", "s" }, { "s", "extends", "s" }, { "s", "implements", "s" }, { "s", "{", "n" }, { "i", "}", "n" }, { "", "[", "" }, { "", "]", "" }, { "", "{", "" }, { "", "}", "" }, { "i", "assert", "s" }, { "s", "catch", "s" }, { "", "(", "" }, { "", ")", "" }, { "i", "case", "s" }, { "i", "default", ":" }, { "s", "?", "s" }, { "s", ":", "s" }, { "i", "do", "s" }, { "s", "while", "s" }, { "", "for", "s" }, { "", ";", "s" }, { "", "if", "s" }, { "s", "else", "" }, { "", "", "" }, { "s", "{", "" }, { "ni", "}", "" }, { "i", "switch", "s" }, { "i", "synchronized", "s" }, { "", "throw", "s" }, { "", "try", "" }, { "s", "finally", "" }, { "", "while", "s" }, { "i", "}", "" } }; 1697 } 1698 1700 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 1750 protected final void formatElementPart(int type, StringBuffer buf) throws IllegalArgumentException { 1751 if (data == null || type >= data.length) { 1752 throw new IllegalArgumentException ("Format data for the argument " + "type #" + type + " not available or formatting data are not " + "accessible."); } 1756 format(data[type][0], buf); 1758 if (data[type][1] != null) 1760 buf.append(data[type][1]); 1761 format(data[type][2], buf); 1763 } 1764 1765 1769 protected final String formatElementPart(int type) { 1770 StringBuffer buf = new StringBuffer (); 1771 formatElementPart(type, buf); 1772 return buf.toString(); 1773 } 1774 1775 protected void formatElementPart(int type, StringBuffer buf, boolean isNew) { 1776 if (isNew) 1777 formatElementPart(type, buf); 1778 else 1779 buf.append(data[type][1]); 1780 } 1781 1782 1786 String getElementPrefix(int type) { 1787 StringBuffer buf = new StringBuffer (64); 1788 format(data[type][0], buf); 1789 return buf.toString(); 1790 } 1791 1792 1796 public static final void setFormattingFor(int type, String pre, String post) { 1797 data[type][0] = pre; 1798 data[type][2] = post; 1799 } 1800 1801 1809 public static final String [] getFormattingFor(int type) { 1810 return data[type]; 1811 } 1812 1813 1825 private boolean format(String mask, StringBuffer 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 appendDims(StringBuffer 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 1861 public static void setIndentSpace(int spaces, boolean expandTabs) { 1862 if (!expandTabs) { 1863 INDENTATION = "\t"; } else { 1866 if (spaces >= 0) { 1867 spacesPerTab = spaces; 1868 char[] buf = new char[spaces]; 1869 Arrays.fill(buf, ' '); 1870 INDENTATION = new String (buf); 1871 } 1872 } 1873 } 1874 1875 public static boolean isExpandTab() { 1876 return !INDENTATION.equals("\t"); } 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 1962 static List duplicateList(List list, JavaModelPackage targetExtent) { 1963 if (list == null) { 1964 return Collections.EMPTY_LIST; 1965 } 1966 Object [] 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 o = elements[i]; 1974 result.add(((MetadataElement) o).duplicate(targetExtent)); 1975 } 1976 return result; 1977 } 1978 1979 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 |