1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.lang.ref.WeakReference ; 22 import java.lang.reflect.Modifier ; 23 import java.util.*; 24 import javax.jmi.reflect.ConstraintViolationException; 25 import javax.jmi.reflect.RefFeatured; 26 import javax.jmi.reflect.RefObject; 27 import org.netbeans.api.mdr.events.AssociationEvent; 28 import org.netbeans.jmi.javamodel.*; 29 import org.netbeans.lib.java.parser.ASTree; 30 import org.netbeans.lib.java.parser.ParserTokens; 31 import org.netbeans.lib.java.parser.Token; 32 import org.netbeans.mdr.handlers.AttrListWrapper; 33 import org.netbeans.mdr.handlers.BaseObjectHandler; 34 import org.netbeans.mdr.persistence.MOFID; 35 import org.netbeans.mdr.persistence.StorageException; 36 import org.netbeans.mdr.storagemodel.StorableBaseObject; 37 import org.netbeans.mdr.storagemodel.StorableObject; 38 import org.netbeans.modules.javacore.ClassIndex; 39 import org.netbeans.modules.javacore.JMManager; 40 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 41 import org.netbeans.modules.javacore.internalapi.JavaModelUtil; 42 import org.netbeans.modules.javacore.parser.*; 43 import org.openide.ErrorManager; 44 import org.openide.util.Utilities; 45 46 53 public abstract class JavaClassImpl extends FeatureImpl implements JavaClass { 54 static final ElementInfo DEFAULT_INFO = new ClassInfo(null, ClassInfo.CLASS_TYPE, null, 0, null, null, null, null, null); 55 56 public static boolean DEBUG = false; 57 58 public static final String CONTENTS_ATTR = "contents"; 60 private LightAttrList contents = null; 61 62 63 private ReferenceListWrapper interfaces = null; 64 65 private WeakReference subClasses = null; 66 private WeakReference implementors = null; 67 68 private boolean internalSetName = false; 69 70 private boolean elementsInited = false; 71 private MultipartId superClassName; 72 private LightAttrList interfaceNames; 73 private final List featuresList; 74 private LightAttrList typeParameters; 75 76 77 public JavaClassImpl(StorableObject s) { 78 super(s); 79 featuresList = new FeaturesList(this); 80 } 81 82 public int getModifiers() { 84 int mods = super_getModifiers(); 85 if (isInner()) { 86 ClassDefinition cd = getDeclaringClass(); 87 if (cd instanceof JavaClass && ((JavaClass)cd).isInterface()) { 88 mods |= Modifier.STATIC | Modifier.PUBLIC; 89 } 90 } 91 return ~DEPRECATED & mods; 92 } 93 94 protected abstract void super_setName(String name); 95 96 101 void internalSetName(String name) { 102 internalSetName = true; 103 try { 104 if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaClassImpl: Changing name of a class using internalSetName."); 105 if (!name.equals(getName())) { 106 setName(name); 107 } 108 } finally { 109 internalSetName = false; 110 } 111 } 112 113 public void setName(String name) { 114 if (name.equals(getName())) return; 115 if (JMManager.INCONSISTENCY_DEBUG) System.err.println("JavaClassImpl: Renaming class " + getName() + " to " + name); 116 boolean isTransient = isTransient(); 117 if (!internalSetName) { 118 if (!isTransient && getResource()!=null && getResource().getPackageName() != null && !name.startsWith(getResource().getPackageName())) { 119 throw new ConstraintViolationException(null, null, "Unable to change the package of the class by setting its name (old name: " + getName() + " new name: " + name + " resource package name: " + getResource().getPackageName() + ")."); 120 } 121 } 122 123 objectChanged(CHANGED_NAME); 124 125 if (isInitialized() && !isNew()) { 126 getElementInfo().hardRefAST(); 127 } 128 129 if (!isTransient) { 130 JavaModelPackage srcExtent=(JavaModelPackage)refOutermostPackage(); 131 ClassIndex index=ClassIndex.getIndex(srcExtent); 132 if (getName() != null) { 133 index.renameClass(this, name); 137 } else { 138 index.addClass(this, name, this.getSimpleName(name)); 141 } 142 } 143 super_setName(name); 144 if (isPersisted()) { 145 Object [] features=getContents().toArray(); 146 for (int i=0;i<features.length;i++) { 147 Object temp = features[i]; 148 if (temp instanceof JavaClassImpl && !isTransient) { 149 JavaClassImpl cls = (JavaClassImpl) temp; 150 boolean changes = cls.disableChanges; 151 cls.disableChanges |= this.disableChanges; 152 try { 153 cls.internalSetName(name.concat('.' + cls.getSimpleName())); 154 } finally { 155 cls.disableChanges = changes; 156 } 157 } else if ((temp instanceof ConstructorImpl) && !disableChanges) { 158 ((ConstructorImpl) temp).objectChanged(CHANGED_NAME); 159 } 160 } 161 } else { 162 List list = (List) _getDelegate().getSlot3(); 164 if (list != null) { 165 HashSet inner = new HashSet(list); 166 for (Iterator it = inner.iterator(); it.hasNext();) { 167 JavaClassImpl cls = (JavaClassImpl) it.next(); 168 boolean changes = cls.disableChanges; 169 cls.disableChanges |= this.disableChanges; 170 try { 171 cls.internalSetName(name.concat('.' + cls.getSimpleName())); 172 } finally { 173 cls.disableChanges = changes; 174 } 175 } 176 } 177 } 178 } 179 180 public boolean isInner() { 181 if (isTransient()) return true; 182 String name=getName(); 183 int lastDot=name.lastIndexOf('.'); 184 185 if (lastDot!=-1) { 186 String outerName=name.substring(0, lastDot); 187 ClassIndex index=ClassIndex.getIndex((JavaModelPackage)refImmediatePackage()); 188 189 return !index.doesnotExist(outerName); 190 } 191 return false; 192 } 193 194 198 public boolean isInterface() { 199 return Modifier.isInterface(getSourceModifiers()); 200 } 201 202 207 public void setInterface(boolean newValue) { 208 if (newValue) { 209 setModifiers(getSourceModifiers() | Modifier.INTERFACE); 210 } else { 211 setModifiers(getSourceModifiers() & ~Modifier.INTERFACE); 212 } 213 } 214 215 219 public List getInterfaces() { 220 checkUpToDate(); 221 if (interfaces == null) { 222 initInterfaces(); 223 } 224 return interfaces; 225 } 226 227 private void initInterfaces() { 228 List interfaceNames = getInterfaceRefs(); 229 if (interfaceNames == null) { 230 interfaceNames = new ArrayList(); 231 } else if (!(interfaceNames instanceof ArrayList)) { 232 interfaceNames = new ArrayList(interfaceNames); 233 } 234 TypeList _interfaces = new TypeList(this, (ArrayList) interfaceNames) { 236 protected void updateParent() { 237 setInterfaceRefs(innerList); 238 } 239 240 protected void fireChange(int attrType, TypeRef newTR, int position) { 241 Object newValue, oldValue; 242 if (elementsInited) { 243 newValue = typeRefToTypeReference(newTR, 0); 244 oldValue = null; 246 } else { 247 newValue = oldValue = null; 248 } 249 fireAttrChange("interfaceNames", oldValue, newValue, position); } 251 }; 252 if (interfaces == null) { 253 ImplementsImpl implementsImpl = (ImplementsImpl)(((JavaModelPackage) refImmediatePackage()).getImplements()); 254 interfaces = new ReferenceListWrapper(_getDelegate().getMdrStorage(), implementsImpl, this, "interfaces", this, CHANGED_IMPLEMENTS, _interfaces); } else { 256 interfaces.setInnerList(_interfaces); 257 } 258 } 259 260 private void fireSCNameChange(MultipartId typeReference) { 261 Object oldValue = null; 262 Object newValue = null; 263 if (elementsInited) { 264 oldValue = getSuperClassName(); 265 newValue = typeReference; 266 } 267 fireAttrChange("superClassName", oldValue, newValue); } 269 270 275 public void setSuperClass(JavaClass newValue) { 276 Extends source = ((JavaModelPackage) refImmediatePackage()).getExtends(); 277 if (_getMdrStorage().eventsEnabled()) { 278 AssociationEvent event = new AssociationEvent( 279 source, 280 AssociationEvent.EVENT_ASSOCIATION_SET, 281 this, 282 "subClasses", getSuperClass(), 284 newValue, 285 AssociationEvent.POSITION_NONE); 286 _getMdrStorage().getEventNotifier().ASSOCIATION.firePlannedChange(source, event); 287 } 288 NameRef sc; 289 if (newValue == null) { 290 sc = NameRef.java_lang_Object; 291 newValue = (JavaClass) resolveType(sc); 292 } else { 293 sc = (NameRef) typeToTypeRef(newValue); 294 } 295 MultipartId mpi = (MultipartId) typeRefToTypeReference(sc, 0); 296 fireSCNameChange(mpi); 297 _setSuperClass(sc, mpi); 298 } 299 300 private void _setSuperClass(NameRef superClass, MultipartId superClassName) { 301 if (!disableChanges) { 302 objectChanged(CHANGED_EXTENDS); 303 changeChild(getSuperClassName(), superClassName); 304 this.superClassName = superClassName; 305 } 306 setSuperclassRef(superClass); 307 } 308 309 public org.netbeans.jmi.javamodel.MultipartId getSuperClassName() { 310 checkUpToDate(); 311 if (!elementsInited) { 312 initASTElements(); 313 } 314 return superClassName; 315 } 316 317 public void setSuperClassName(org.netbeans.jmi.javamodel.MultipartId newValue) { 318 NameRef sc = (NameRef) typeReferenceToTypeRef(newValue, 0); 319 if (sc == null) { 320 sc = NameRef.java_lang_Object; 321 } 322 _setSuperClass(sc, newValue); 323 } 324 325 329 public JavaClass getSuperClass() { 330 JavaClass result; 331 checkUpToDate(); 332 333 if ("java.lang.Object".equals(getName())) { result = null; 336 } else if (isInterface()) { 337 result = (JavaClass) resolveType(NameRef.java_lang_Object); 338 339 } else { 342 NameRef superClass = getSuperclassRef(); 343 if (superClass == null) { 344 superClass = NameRef.java_lang_Object; 345 setSuperclassRef(superClass); 346 } 347 result = (JavaClass) resolveType(superClass); 348 } 349 350 if (DEBUG) { 351 System.out.println("getSuperClass: "+result); if (result != null) 353 System.out.println("getSuperClass: "+result.getName()); } 355 return result; 356 } 357 358 private Collection getSubClasses(boolean deterministicProgress) { 359 if (isInterface()) return Collections.EMPTY_LIST; 360 ReferenceColWrapper subClasses; 363 if (this.subClasses == null || (subClasses = (ReferenceColWrapper) this.subClasses.get()) == null) { 364 SubClassesCollection coll = new SubClassesCollection(this, deterministicProgress); 365 subClasses = new ReferenceColWrapper(_getMdrStorage(), null, this, null, null, 0, coll); 366 this.subClasses = new WeakReference (subClasses); 367 } 368 return subClasses; 369 } 370 371 private Collection getImplementors(boolean deterministicProgress) { 372 if (!isInterface()) return Collections.EMPTY_LIST; 373 ReferenceColWrapper implementors; 374 if (this.implementors == null || (implementors = (ReferenceColWrapper) this.implementors.get()) == null) { 375 ImplementorsCollection coll = new ImplementorsCollection(this, deterministicProgress); 376 implementors = new ReferenceColWrapper(_getMdrStorage(), null, this, null, null, 0, coll); 377 this.implementors = new WeakReference (implementors); 378 } 379 return implementors; 380 } 381 382 public Collection getSubClasses() { 383 return getSubClasses(true); 384 } 385 386 public Collection getImplementors() { 387 return getImplementors(true); 388 } 389 390 public Collection findSubTypes(boolean transitively) { 391 if (!transitively) { 392 return isInterface() ? getImplementors() : getSubClasses(); 393 } else { 394 JavaMetamodel.getManager().getProgressSupport().fireProgressListenerStart(0, -1); 395 List q = new ArrayList(getImplementors(false)); 396 q.addAll(getSubClasses(false)); 397 HashSet result = new HashSet(); 398 while (!q.isEmpty()) { 399 JavaClassImpl clazz = (JavaClassImpl) q.remove(0); 400 result.add(clazz); 401 q.addAll(clazz.getImplementors(false)); 402 q.addAll(clazz.getSubClasses(false)); 403 } 404 JavaMetamodel.getManager().getProgressSupport().fireProgressListenerStop(); 405 return result; 406 } 407 } 408 409 public List getPersistentContents() { 410 AttrListWrapper list = (AttrListWrapper) super_getContents(); 411 return ClassDefinitionImpl.getPersistentContent(list); 412 } 413 414 418 public List getContents() { 419 checkUpToDate(); 420 if (contents == null) { 421 contents = createChildrenList(CONTENTS_ATTR, (AttrListWrapper) super_getContents(), null, CHANGED_FEATURES); 422 } 423 return contents; 424 } 425 426 public List getFeatures() { 427 return featuresList; 428 } 429 430 public List getPersistentTypeParameters() { 431 AttrListWrapper list = (AttrListWrapper) super_getTypeParameters(); 432 list.setAttrName(TYPE_PARAMETERS_ATTR); 433 return list; 434 } 435 436 public List getTypeParameters() { 437 checkUpToDate(); 438 if (typeParameters == null) { 439 typeParameters = createChildrenList(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), null, CHANGED_TYPE_PARAMETERS); 440 } 441 return typeParameters; 442 } 443 444 protected abstract List super_getContents(); 445 446 public Field getField(String name, boolean includeSupertypes) { 447 return ClassDefinitionImpl.getField(this, name, includeSupertypes); 448 } 449 450 public Method getMethod(String name, List parameters, boolean includeSupertypes) { 451 return ClassDefinitionImpl.getMethod(this, name, parameters, includeSupertypes); 452 } 453 454 public JavaClass getInnerClass(String simpleName, boolean includeSupertypes) { 455 return ClassDefinitionImpl.getInnerClass(this, simpleName, includeSupertypes); 456 } 457 458 public Constructor getConstructor(List parameters, boolean includeSupertypes) { 459 return ClassDefinitionImpl.getConstructor(this, parameters, includeSupertypes); 460 } 461 462 466 public void reinitContents() { 467 assert contents!=null; 468 contents.setInnerList(getPersistentContents(), false); 469 } 470 471 public boolean contentsInited() { 472 return contents != null; 473 } 474 475 public Collection getInnerClasses() { 476 Collection inners; 477 478 if (!isPersisted()) { 479 StorableBaseObject delegate = _getDelegate(); 480 481 inners = (Collection) delegate.getSlot3(); 482 if (inners==null) { 483 return Collections.EMPTY_LIST; 484 } 485 } else { 486 Object [] features = getContents().toArray(); 487 488 inners=new ArrayList(); 489 for(int i=0;i<features.length;i++) { 490 Object obj = features[i]; 491 if (obj instanceof JavaClass) { 492 inners.add(obj); 493 } 494 } 495 } 496 return Collections.unmodifiableCollection(inners); 497 } 498 499 public void setParentClass(JavaClassImpl jcls) { 500 try { 501 if (jcls == null) { 502 Object parent = refImmediateComposite(); 503 ((StorableObject) _getDelegate()).clearComposite(); 504 if (parent instanceof JavaClassImpl) { 505 ((JavaClassImpl) parent).removeInnerClass(this); 506 } 507 } else { 508 ((StorableObject) _getDelegate()).setComposite(jcls._getDelegate(), null, null); 509 jcls.addInnerClass(this); 510 } 511 } catch (StorageException ex) { 512 ErrorManager.getDefault().notify(ex); 513 } 514 } 515 516 private void addInnerClass(JavaClass javaClass) { 517 StorableBaseObject delegate = _getDelegate(); 518 List inner = (List) delegate.getSlot3(); 519 if (inner == null) { 520 inner = new ArrayList(); 521 } 522 inner.add(javaClass); 523 delegate.setSlot3(inner); 524 } 525 526 private void removeInnerClass(JavaClass javaClass) { 527 StorableBaseObject delegate = _getDelegate(); 528 List inner = (List) delegate.getSlot3(); 529 if (inner == null) return; 530 if (!inner.remove(javaClass)) { 531 inner.remove(((BaseObjectHandler) javaClass)._getDelegate().getMofId()); 532 } 533 delegate.setSlot3(inner); 534 } 535 536 540 protected ElementInfo getDefaultInfo() { 541 return DEFAULT_INFO; 542 } 543 544 protected void matchName(ElementInfo info) { 545 if (!Utilities.compareObjects(info.name, this.getName())) { 546 internalSetName(info.name); 547 } 548 } 549 550 protected void matchPersistent(ElementInfo info) { 551 super.matchPersistent(info); 552 553 ClassInfo newInfo = (ClassInfo) info; 554 555 if (!isPersisted()) { 556 setPersisted(true); 557 persist(); 558 persistChildren(getPersistentList("annotations", super_getAnnotations()), ((FeatureInfo) info).annotations); 559 persistChildren(getPersistentList(TYPE_PARAMETERS_ATTR, super_getTypeParameters()), newInfo.typeParams); 560 setSuperclassRef(newInfo.superclass); 561 setInterfaceRefs(Arrays.asList(newInfo.interfaces)); 562 Collection innerClasses = (Collection) _getDelegate().getSlot3(); 563 _getDelegate().setSlot3(null); 564 persistChildren(getPersistentList(CONTENTS_ATTR, super_getContents()), newInfo.features); 565 566 if (innerClasses != null) { 567 HashSet contents = new HashSet(super_getContents()); 568 for (Iterator it = innerClasses.iterator(); it.hasNext();) { 569 Object temp = it.next(); 570 if (temp instanceof MOFID) { 571 temp = _getRepository().getByMofId((MOFID) temp); 572 } 573 JavaClassImpl cls = (JavaClassImpl) temp; 574 if (!contents.contains(cls)) { 575 try { 576 ((StorableObject) cls._getDelegate()).clearComposite(); 577 } catch (StorageException e) { 578 } 580 cls.refDelete(); 581 } 582 } 583 } 584 585 } else { 586 if (!(this instanceof AnnotationType)) { 587 processMembers(getTypeParameters(), newInfo.typeParams); 588 if (!Utilities.compareObjects(newInfo.superclass, getSuperclassRef())) { 589 setSuperClass((JavaClass) resolveType(newInfo.superclass)); 590 } 591 processMembers(getInterfaces(), newInfo.interfaces); 592 } 593 processMembers(getAnnotations(), newInfo.annotations); 594 normalizeContents(); 595 processMembers(getContents(), newInfo.features); 596 } 597 } 598 599 protected final void normalizeContents() { 600 for (ListIterator it = getContents().listIterator(); it.hasNext();) { 601 SemiPersistentElement element = (SemiPersistentElement) it.next(); 602 if (element instanceof FieldGroupImpl) { 603 Iterator it2 = ((FieldGroupImpl) element).getPersistentFields().iterator(); 604 SemiPersistentElement field = null; 605 if (it2.hasNext()) { 606 field = (SemiPersistentElement) it2.next(); 607 } 608 if (!it2.hasNext()) { 609 it.remove(); 610 if (field != null) { 611 it2.remove(); 612 ((FieldGroupImpl) element).reinitFields(); 613 it.add(field); 614 } 615 element.refDelete(); 616 } 617 } 618 } 619 } 620 621 623 protected void matchElementInfo(ElementInfo newInfo) { 624 super.matchElementInfo(newInfo); 625 resetASTElements(); 626 } 627 628 public void childChanged(MetadataElement mpi) { 629 super.childChanged(mpi); 630 if (elementsInited) { 631 if (mpi == superClassName) { 632 setSuperClassName((MultipartId) mpi); 633 } 634 } 635 } 636 637 public String toString() { 638 return "class " + getName(); } 640 641 protected void resetChildren() { 642 super.resetChildren(); 643 if (contents != null) contents.setInnerList(getPersistentContents()); 644 if (typeParameters != null) typeParameters.setInnerList(getPersistentList(TYPE_PARAMETERS_ATTR, super_getTypeParameters())); 645 if (childrenInited) { 646 resetASTElements(); 647 initChildren(); 648 } 649 if (interfaces != null) { 650 initInterfaces(); 651 } 652 } 653 654 protected List getInitedChildren() { 655 List list = super.getInitedChildren(); 656 if (childrenInited) { 657 list.addAll(getTypeParameters()); 658 list.addAll(getContents()); 659 } 660 if (elementsInited) { 661 addIfNotNull(list, superClassName); 662 list.addAll(interfaceNames); 663 } 664 return list; 665 } 666 667 public List getChildren() { 668 List list = super.getChildren(); 669 list.addAll(getTypeParameters()); 670 addIfNotNull(list, getSuperClassName()); 671 list.addAll(getInterfaceNames()); 672 list.addAll(getContents()); 673 return list; 674 } 675 676 public void fixImports(Element scope, Element original) { 677 JavaClass jcls=(JavaClass)original; 678 679 if (!(jcls instanceof AnnotationType)) { 680 fixImports(scope,getTypeParameters(),jcls.getTypeParameters()); 681 if (getSuperClassName()!=null) { 682 setSuperClassName(JavaModelUtil.resolveImportsForClass(scope,jcls.getSuperClass())); 683 } 684 fixImportsInClassList(scope,getInterfaceNames(),jcls.getInterfaces()); 685 } 686 fixImports(scope,getContents(),jcls.getContents()); 687 super.fixImports(scope,original); 688 } 689 690 701 protected void initChildren() { 702 boolean fail = true; 704 _lock(true); 705 try { 706 childrenInited = false; 707 FeatureInfo[] featureInfos = ((ClassInfo) getElementInfo()).features; 708 List featuresCollection = ClassDefinitionImpl.getNakedFeatures(this); 709 boolean needsReset = false; 710 711 if (!isNew() && (featuresCollection.size() != featureInfos.length)) { 715 fixMembers(featuresCollection, featureInfos); 716 needsReset = true; 717 } else { 718 ListIterator it = featuresCollection.listIterator(); 719 for (int i = 0; i < featureInfos.length; i++) { 720 SemiPersistentElement element = (SemiPersistentElement) it.next(); 721 if (element instanceof FieldGroup && featureInfos[i] instanceof FieldInfo) { 722 it.remove(); 723 Iterator it2 = ((FieldGroup) element).getFields().iterator(); 724 SemiPersistentElement field; 725 if (it2.hasNext()) { 726 field = (SemiPersistentElement) it.next(); 727 it2.remove(); 728 field.setElementInfo(featureInfos[i]); 729 } else { 730 field = createElement(featureInfos[i]); 731 } 732 element.refDelete(); 733 it.add(field); 734 needsReset = true; 735 } else { 736 if (checkElementType(featureInfos[i], element)) { 737 element.setElementInfo(featureInfos[i]); 738 } else { 739 JMManager.getLog().log(ErrorManager.WARNING, "Inconsistent storage - feature types do not match."); 740 fixMembers(featuresCollection, featureInfos); 741 needsReset = true; 742 break; 743 } 744 } 745 } 746 } 747 748 if (contents != null && needsReset) { 756 contents.setInnerList(getPersistentContents()); 757 } 758 759 typeParameters = createChildrenList(typeParameters, TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), ((ClassInfo) getElementInfo()).typeParams, CHANGED_TYPE_PARAMETERS); super.initChildren(); 761 762 childrenInited = true; 763 764 if (elementsInited) { 765 initASTElements(); 766 } 767 fail = false; 768 } catch (RuntimeException e) { 769 e.printStackTrace(); 770 throw e; 771 } finally { 772 _unlock(fail); 776 } 777 } 778 779 protected void setData(List annotations, java.lang.String javadocText, JavaDoc javadoc, List features, MultipartId superClassName, List interfaceNames, List typeParameters) { 780 super.setData(annotations, javadocText, javadoc); 781 this.contents = createChildrenList(CONTENTS_ATTR, (AttrListWrapper) super_getContents(), features, CHANGED_FEATURES); changeChild(null, superClassName); 783 this.superClassName = superClassName; 784 this.interfaceNames = createChildrenList("interfaceNames", interfaceNames, CHANGED_IMPLEMENTS); this.typeParameters = createChildrenList(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), typeParameters, CHANGED_TYPE_PARAMETERS); elementsInited = true; 787 } 788 789 protected abstract List super_getTypeParameters(); 790 791 795 801 protected String getIndentation() { 802 RefFeatured composite = refImmediateComposite(); 805 if (composite instanceof JavaClass) 806 return super.getIndentation(); 807 else 808 return ""; 809 } 810 811 String getRawText() { 812 StringBuffer buf = new StringBuffer (); 813 if (isNew()) { 814 generateNewJavaDoc(buf); 815 } 816 generateNewModifiers(buf); 817 if (!isInterface()) { 818 buf.append("class "); } else { 820 buf.append("interface "); } 822 buf.append(getSimpleName()); 823 generateNewTypeParameters(buf); 824 if (superClassName != null) { 825 formatElementPart(EXTENDS_KEYWORD, buf); 826 buf.append(((MetadataElement)superClassName).getSourceText()); 827 } 828 generateNewImplements(buf); 829 ClassDefinitionImpl.generateNewFeatures(this, buf, true); 830 return buf.toString(); 831 } 832 833 private void generateNewTypeParameters(StringBuffer buf) { 834 Collection typeParameters = getTypeParameters(); 835 if (!typeParameters.isEmpty()) { 836 buf.append('<'); 837 Iterator it = typeParameters.iterator(); 838 while (it.hasNext()) { 839 buf.append(((TypeParameterImpl) it.next()).getSourceText()); 840 if (it.hasNext()) { 841 formatElementPart(COMMA, buf); 842 } 843 } 844 buf.append('>'); 845 } 846 } 847 848 851 public void getDiff(List diffList) { 852 ClassInfo astInfo = (ClassInfo) getElementInfo(); 853 ASTProvider parser = getParser(); 854 ASTree[] children = getASTree().getSubTrees(); 855 856 replaceJavaDoc(diffList); 858 if (isChanged(CHANGED_MODIFIERS | CHANGED_ANNOTATION)) { 860 diffModifiers(diffList, parser.getToken(children[IDENTIFIER].getFirstToken() - 1), parser); 861 } else if (children[0] != null) { 862 getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[0].getLastToken()).getEndOffset(), " "); } 864 if (isChanged(CHANGED_NAME)) { 866 replaceNode(diffList, parser, children[IDENTIFIER], getSimpleName(), 0, null); 867 } 868 869 if (astInfo.typeParams.length == 0) { 870 if (isChanged(CHANGED_TYPE_PARAMETERS)) { 871 StringBuffer buf = new StringBuffer (); 872 generateNewTypeParameters(buf); 873 int endOffset = getEndOffset(parser, children[IDENTIFIER]); 874 diffList.add(new DiffElement(endOffset, endOffset, buf.toString())); 875 } 876 } else if (getTypeParameters().isEmpty()) { 877 if (isChanged(CHANGED_TYPE_PARAMETERS)) { 878 replaceNode(diffList, parser, children[2], "", 0, null); 879 } 880 } else { 881 getCollectionDiff(diffList, parser, CHANGED_TYPE_PARAMETERS, astInfo.typeParams, getTypeParameters(), parser.getToken(children[2].getLastToken()).getStartOffset(), ", "); } 883 884 886 if (isChanged(CHANGED_EXTENDS)) { 887 int startOffset, endOffset; 888 String extendsText = superClassName == null?"":((MetadataElement) superClassName).getSourceText(); 889 if (children[SUPERCLASS] != null) { 891 startOffset = parser.getToken(children[SUPERCLASS].getFirstToken()+(superClassName==null?0:1)).getStartOffset(); 892 endOffset = parser.getToken(children[SUPERCLASS].getLastToken()).getEndOffset(); 893 diffList.add(new DiffElement(startOffset, endOffset, extendsText)); 894 } 895 else if (superClassName != null) { 897 int index = children[TYPE_PARAMETERS] != null ? TYPE_PARAMETERS : IDENTIFIER; 898 startOffset = endOffset = parser.getToken(children[index].getLastToken()).getEndOffset(); 899 extendsText = formatElementPart(EXTENDS_KEYWORD) + extendsText; 900 diffList.add(new DiffElement(startOffset, endOffset, extendsText)); 901 } 902 } else { 903 getChildDiff(diffList, parser, children[SUPERCLASS], (MetadataElement) getSuperClassName(), CHANGED_EXTENDS); 904 } 905 906 int index = children[SUPERCLASS] != null ? SUPERCLASS : (children[TYPE_PARAMETERS] != null ? TYPE_PARAMETERS : IDENTIFIER); 908 int startOffset = parser.getToken(children[index].getLastToken()).getEndOffset(); 909 String prefix = isInterface() ? formatElementPart(EXTENDS_KEYWORD) : formatElementPart(IMPLEMENTS_KEYWORD); 910 getCollectionDiff(diffList, parser, CHANGED_IMPLEMENTS, getASTree().getSubTrees()[INTERFACES], 911 getInterfaceNames(), startOffset, formatElementPart(COMMA), prefix); 912 getCollectionDiff(diffList, parser, CHANGED_FEATURES, astInfo.features, getContents(), getContentsEndOffset(parser, getASTree()), "\n"); } 915 916 protected int getStartOffset2(ASTProvider parser, ASTree tree) { 917 Token startToken = parser.getToken(tree.getFirstToken()); 918 Token firstToken = startToken; 919 int startOffset = -1; 920 Token[] pad = startToken.getPadding(); 921 if (pad.length > 0) { 922 startToken = pad[0]; 923 for (int i = 0; i < pad.length; i++) { 924 if (pad[i].getType() == ParserTokens.EOL && startOffset < 0) { 925 String value = parser.getText(pad[i]); 926 startOffset = pad[i].getStartOffset() + value.indexOf('\n') + 1; 927 } else if (pad[i].getType() == ParserTokens.DOC_COMMENT) { 928 break; 929 } else if ((pad[i].getType() == ParserTokens.COMMENT) || (pad[i].getType() == ParserTokens.EOL_COMMENT)) { 930 startOffset = -1; 931 startToken = i + 1 < pad.length ? pad[i + 1] : firstToken; 932 } 933 } 934 } 935 if (startOffset > -1) { 936 return startOffset; 937 } 938 return startToken.getStartOffset(); 939 } 940 941 942 protected final int getContentsEndOffset(ASTProvider parser, ASTree tree) { 943 Token closeBrace = parser.getToken(tree.getLastToken()); 944 Token[] pad = closeBrace.getPadding(); 945 int endOffset = closeBrace.getStartOffset(); 946 for (int i = pad.length - 1; i >= 0; i--) { 947 switch (pad[i].getType()) { 948 case ParserTokens.EOL_COMMENT: 949 case ParserTokens.COMMENT: 950 case ParserTokens.DOC_COMMENT: 951 i = 0; 952 break; 953 case ParserTokens.EOL: 954 endOffset = pad[i].getStartOffset(); 955 } 956 } 957 return endOffset; 958 } 959 960 protected ASTree getPartTree(ElementPartKind part) { 961 if (ElementPartKindEnum.NAME.equals(part)) { 962 return getASTree().getSubTrees()[IDENTIFIER]; 963 } 964 throw new IllegalArgumentException ("Invalid part for this element: " + part); } 966 967 public void replaceChild(Element oldElement, Element newElement) { 968 if (oldElement instanceof JavaClass && newElement == null) { 969 removeInnerClass((JavaClass) oldElement); 970 } 971 List contents, typeParameters; 972 if (isPersisted()) { 973 contents = getContents(); 974 typeParameters = getTypeParameters(); 975 } else { 976 contents = super_getContents(); 977 typeParameters = super_getTypeParameters(); 978 } 979 if (replaceObject(contents, oldElement, newElement)) return; 980 if (replaceObject(typeParameters, oldElement, newElement)) return; 981 if (elementsInited) { 982 if (oldElement.equals(superClassName)) { 983 setSuperClassName((MultipartId) newElement); 984 return; 985 } 986 if (replaceObject(interfaceNames, oldElement, newElement)) return; 987 } 988 super.replaceChild(oldElement, newElement); 989 } 990 991 protected ASTree getPartStartTree(ElementPartKind part) { 992 if (ElementPartKindEnum.HEADER.equals(part)) { 993 return getASTree(); 994 } 995 return super.getPartStartTree(part); 996 } 997 998 protected ASTree getPartEndTree(ElementPartKind part) { 999 if (ElementPartKindEnum.HEADER.equals(part)) { 1000 for (int i = 4; true; i--) { 1001 ASTree result = getASTree().getSubTrees()[i]; 1002 if (result != null) { 1003 return result; 1004 } 1005 } 1006 } 1007 return super.getPartEndTree(part); 1008 } 1009 1010 private static final int IDENTIFIER = 1; 1012 private static final int TYPE_PARAMETERS = 2; 1013 private static final int SUPERCLASS = 3; 1014 private static final int INTERFACES = 4; 1015 1016 1025 protected void generateNewImplements(StringBuffer buf) { 1026 Collection interfaces = getInterfaceNames(); 1027 if (!interfaces.isEmpty()) { 1028 if (isInterface()) { 1029 formatElementPart(EXTENDS_KEYWORD, buf); 1030 } else { 1031 formatElementPart(IMPLEMENTS_KEYWORD, buf); 1032 } 1033 Iterator it = interfaces.iterator(); 1034 MultipartIdImpl impl = (MultipartIdImpl) it.next(); 1035 buf.append(impl.getSourceText()); 1036 while (it.hasNext()) { 1037 formatElementPart(COMMA, buf); 1038 impl = (MultipartIdImpl) it.next(); 1039 buf.append(impl.getSourceText()); 1040 } 1041 } 1042 } 1043 1044 public static String getSimpleName(String name) { 1045 if (name == null) return null; 1046 int lastDot = name.lastIndexOf('.'); 1047 1048 if (lastDot != -1) 1049 return name.substring(lastDot + 1); 1050 return name; 1051 } 1052 1053 public String getSimpleName() { 1054 return getSimpleName(getName()); 1055 } 1056 1057 public void setSimpleName(String name) { 1058 String fullName = getName(); 1059 if (fullName!=null) { 1060 int index = fullName.lastIndexOf('.'); 1061 if (index >= 0) { 1062 name = fullName.substring(0, index + 1) + name; 1063 } 1064 } 1065 setName(name); 1066 } 1067 1068 protected void _delete() { 1069 if (DEBUG) { 1070 System.out.println("removing class: " + getName() + " MOFID: " + refMofId()); if (refImmediateComposite() != null) { 1072 System.out.println(" in resource: " + ((NamedElement) refImmediateComposite()).getName()); } 1074 Thread.dumpStack(); 1075 } 1076 deleteChildren(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters()); 1079 if (isPersisted()) { 1081 for (Iterator it = getPersistentContents().iterator(); it.hasNext();) { 1082 RefObject feature = (RefObject) it.next(); 1083 it.remove(); 1084 feature.refDelete(); 1085 } 1086 } else { 1087 List inner = (List) _getDelegate().getSlot3(); 1088 if (inner != null) { 1089 for (Iterator it = inner.iterator(); it.hasNext();) { 1090 Object temp = it.next(); 1091 if (temp instanceof MOFID) { 1092 temp = _getRepository().getByMofId((MOFID) temp); 1093 } 1094 JavaClass cls = (JavaClass) temp; 1095 it.remove(); 1096 cls.refDelete(); 1097 } 1098 } 1099 } 1100 _getDelegate().setSlot3(null); 1101 if (elementsInited) { 1102 deleteChild(superClassName); 1103 deleteChildren(interfaceNames); 1104 } 1105 super._delete(); 1106 } 1107 1108 protected void parentChanged() { 1109 parent = refImmediateComposite(); 1110 String prefix; 1111 if (parent instanceof Resource) { 1112 prefix = ((Resource) parent).getPackageName(); 1113 } else if (parent instanceof JavaClass) { 1114 prefix = ((JavaClass) parent).getName(); 1115 } else { 1116 prefix = ""; 1117 } 1118 boolean changes = disableChanges; 1119 disableChanges = true; 1120 try { 1121 internalSetName((prefix == null || prefix.length() == 0) ? getSimpleName() : (prefix + '.' + getSimpleName())); 1122 } finally { 1123 disableChanges = changes; 1124 } 1125 } 1126 1127 public java.util.List getInterfaceNames() { 1128 if (!elementsInited) { 1129 initASTElements(); 1130 } 1131 return interfaceNames; 1132 } 1133 1134 protected void initASTElements() { 1135 elementsInited = false; 1136 if (!childrenInited) { 1137 initChildren(); 1138 } 1139 ClassInfo info = (ClassInfo) getElementInfo(); 1140 ASTree superClass = info.getTypeAST(this); 1141 ASTree[] interfaces = info.getInterfacesAST(this); 1142 superClassName = (MultipartId) initOrCreate(superClassName, superClass); 1143 interfaceNames = createChildrenList(interfaceNames, "interfaceNames", interfaces, CHANGED_IMPLEMENTS, false); elementsInited = true; 1145 } 1146 1147 protected void resetASTElements() { 1148 if (elementsInited) { 1149 if (superClassName != null) { 1150 MultipartId temp = superClassName; 1151 changeChild(superClassName, null); 1152 superClassName = null; 1153 temp.refDelete(); 1154 } 1155 deleteChildren(interfaceNames); 1156 interfaceNames = null; 1157 elementsInited = false; 1158 } 1159 } 1160 1161 public boolean isSubTypeOf(ClassDefinition clazz) { 1162 return ClassDefinitionImpl.isSubTypeOf(this, clazz); 1163 } 1164 1165 protected void setSuperclassRef(NameRef sc) { 1166 _getDelegate().setSlot1(sc); 1167 } 1168 1169 public NameRef getSuperclassRef() { 1170 return (NameRef) _getDelegate().getSlot1(); 1171 } 1172 1173 protected void setInterfaceRefs(List ifcs) { 1174 _getDelegate().setSlot2(ifcs); 1175 } 1176 1177 public List getInterfaceRefs() { 1178 return (List) _getDelegate().getSlot2(); 1179 } 1180 1181 public Element duplicate(JavaModelPackage targetExtent) { 1182 return targetExtent.getJavaClass().createJavaClass( 1183 getName(), 1184 duplicateList(getAnnotations(), targetExtent), 1185 getModifiers(), 1186 null, 1187 (JavaDoc) duplicateElement(getJavadoc(), targetExtent), 1188 duplicateList(getContents(), targetExtent), 1189 (MultipartId) duplicateElement(getSuperClassName(), targetExtent), 1190 duplicateList(getInterfaceNames(), targetExtent), 1191 duplicateList(getTypeParameters(), targetExtent) 1192 ); 1193 } 1194} 1195 | Popular Tags |