1 19 20 package org.netbeans.modules.javacore.jmiimpl.javamodel; 21 22 import org.netbeans.jmi.javamodel.*; 23 import org.netbeans.lib.java.parser.ASTree; 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.storagemodel.StorableObject; 28 import org.netbeans.modules.javacore.ClassIndex; 29 import org.netbeans.modules.javacore.JMManager; 30 import org.netbeans.modules.javacore.api.JavaModel; 31 import org.netbeans.modules.javacore.parser.ASTProvider; 32 import org.netbeans.modules.javacore.parser.ElementInfo; 33 import org.netbeans.modules.javacore.parser.FeatureInfo; 34 import org.netbeans.modules.javacore.parser.JavaDocParser; 35 import org.openide.util.Utilities; 36 import javax.jmi.model.MofClass; 37 import javax.jmi.reflect.ConstraintViolationException; 38 import javax.jmi.reflect.RefFeatured; 39 import javax.jmi.reflect.RefObject; 40 import java.lang.reflect.Modifier ; 41 import java.util.*; 42 import org.netbeans.api.mdr.MDRepository; 43 import org.netbeans.modules.javacore.parser.MDRParser; 44 import org.netbeans.modules.javacore.parser.TypeRef; 45 import org.openide.text.PositionBounds; 46 47 48 53 public abstract class FeatureImpl extends SemiPersistentElement { 54 55 public static final int DEPRECATED = 0x80000000; 56 57 public static final String TYPE_PARAMETERS_ATTR = "typeParameters"; 59 protected String javadocText = null; 60 protected JavaDoc javadoc = null; 61 protected LightAttrList annotations = null; 62 63 64 public FeatureImpl(StorableObject s) { 65 super(s); 66 } 67 68 protected void initChildren() { 69 annotations = createChildrenList(annotations, "annotations", (AttrListWrapper)super_getAnnotations(), ((FeatureInfo) getElementInfo()).annotations, CHANGED_ANNOTATION); 71 } 72 73 protected void resetChildren() { 74 super.resetChildren(); 75 if (childrenInited) { 76 if (annotations != null) { 77 annotations.setInnerList(getPersistentList("annotations", super_getAnnotations())); } 79 } 80 resetJavaDoc(); 81 } 82 83 public List getPersistentAnnotations() { 84 AttrListWrapper list = (AttrListWrapper) super_getAnnotations(); 85 list.setAttrName("annotations"); return list; 87 } 88 89 93 public List getAnnotations() { 94 checkUpToDate(); 95 if (annotations == null) { 96 annotations = createChildrenList("annotations", (AttrListWrapper) super_getAnnotations(), null, CHANGED_ANNOTATION); 97 } 98 return annotations; 99 } 100 101 protected abstract void super_setModifiers(int modifiers); 102 protected abstract int super_getModifiers(); 103 104 108 public int getModifiers() { 109 int mods = super_getModifiers(); 110 ClassDefinition cd = getDeclaringClass(); 111 if (cd instanceof JavaClass) { 112 JavaClass jc = (JavaClass)cd; 113 if ((jc.getModifiers() & Modifier.STRICT) != 0) { 114 mods = mods | Modifier.STRICT; 115 } 116 if (jc.isInterface()) { 117 mods = mods | Modifier.PUBLIC; 118 if (this instanceof Method) { 119 mods |= Modifier.ABSTRACT; 120 } 121 } else { 122 if (this instanceof Method && ((jc.getModifiers() & Modifier.FINAL) != 0)) { 123 mods |= Modifier.FINAL; 124 } 125 } 126 } 127 return ~DEPRECATED & mods; 128 } 129 130 public int getSourceModifiers() { 131 int mods = super_getModifiers(); 132 return ~DEPRECATED & mods; 133 } 134 135 140 public void setModifiers(int newValue) { 141 boolean isDeprecated = isDeprecated(); 142 objectChanged(CHANGED_MODIFIERS); 143 super_setModifiers((newValue & ~DEPRECATED) | (isDeprecated ? DEPRECATED : 0)); 144 } 145 146 public boolean isDeprecated() { 147 int mods = super_getModifiers(); 148 return (mods & DEPRECATED) != 0; 149 } 150 151 public void setDeprecated(boolean deprecated) { 152 throw new UnsupportedOperationException (); 153 } 154 155 162 public java.lang.String getJavadocText() { 163 checkUpToDate(); 164 if (javadoc != null) { 165 List tags = javadoc.getTags(); 166 JavaDocParser.JavaDocTag[] javaDocTags = null; 167 if (tags != null) { 168 javaDocTags = new JavaDocParser.JavaDocTag[tags.size()]; 169 int i = 0; 170 for (Iterator it = tags.iterator(); it.hasNext(); ) { 171 TagValue tagValue = (TagValue) it.next(); 172 javaDocTags[i++] = new JavaDocParser.JavaDocTag(tagValue.getDefinition().getName(), tagValue.getValue()); 173 } 174 } 175 JavaDocParser parser = new JavaDocParser(javadoc.getText(), javaDocTags); 176 return parser.getRawText(true); } else if (javadocText!=null) { 178 return javadocText; 179 } else { 180 MDRParser parser = getParser(); 181 if (parser != null) { 182 javadocText = parser.getJavaDoc(getASTree()); 183 if (javadocText != null) { if (javadocText.startsWith("\n")) { javadocText = javadocText.substring(1); 186 } 187 if (javadocText.startsWith("\r\n")) { javadocText = javadocText.substring(2); 189 } 190 } 191 return javadocText; 192 } 193 } 194 return null; 195 } 196 201 public void setJavadocText(java.lang.String newValue) { 202 objectChanged(CHANGED_JAVADOC); 203 if (javadoc !=null) { 204 changeChild(javadoc, null); 205 javadoc = null; 206 } 207 javadocText = newValue; 208 if ((getParser() != null) && Utilities.compareObjects(getParser().getJavaDoc(getASTree()), newValue)) { 209 resetChange(CHANGED_JAVADOC); 210 } 211 } 212 213 217 public JavaDoc getJavadoc() { 218 checkUpToDate(); 219 if (javadoc != null) 220 return javadoc; 221 String javaDocText = getJavadocText(); 222 if (javaDocText == null) 223 return null; 224 225 JavaModelPackage pkg = (JavaModelPackage) refImmediatePackage(); 226 TagValueClassImpl tagValueClass = (TagValueClassImpl) pkg.getTagValue(); 227 JavaDocClassImpl javaDocClass = (JavaDocClassImpl) pkg.getJavaDoc(); 228 229 JavaDocParser parser = new JavaDocParser(javaDocText); 230 JavaDocParser.JavaDocTag[] tags = parser.getTags(); 231 232 List tagsList = new ArrayList(); 233 String text = null; 234 235 if (tags != null && tags.length > 0) { 236 for (int i = 0; i < tags.length; i++) { 237 JavaDocParser.JavaDocTag tag = tags[i]; 238 if (tag.isText()) { 239 text = tag.getValue(); 240 continue; 241 } 242 String tagName = tag.getName(); 243 String tagText = tag.getValue(); 244 tagsList.add(tagValueClass.create(tagName, tagText)); 245 } 246 } 247 248 JavaDocImpl javaDoc = (JavaDocImpl) javaDocClass.createJavaDoc(text, tagsList); 249 250 changeChild(javadoc, javaDoc); 251 return javadoc = javaDoc; 252 } 253 254 259 public void setJavadoc(JavaDoc newValue) { 260 objectChanged(CHANGED_JAVADOC); 261 changeChild(javadoc, newValue); 262 javadocText = null; 263 javadoc = newValue; 264 } 265 266 268 public ClassDefinition getDeclaringClass() { 269 RefFeatured obj = refImmediateComposite(); 270 271 if (obj instanceof ClassDefinition) { 272 return (ClassDefinition) obj; 273 } else if (this instanceof Field && obj instanceof FieldGroup) { 274 return ((FieldGroup) obj).getDeclaringClass(); 275 } 276 return null; 277 } 278 279 public PositionBounds getPosition(boolean inclDoc) { 280 ResourceImpl resource = (ResourceImpl)getResource(); 281 PositionBounds result = null; 282 if (!inclDoc && (result = resource.getFeaturePosition(this)) != null) 283 return result; 284 else { 285 MDRepository repository = repository(); 286 repository.beginTrans(false); 287 try { 288 if (JMManager.getTransactionMutex().getClassPath() == null) { 289 JavaModel.setClassPath(resource); 290 } 291 return super.getPosition(false); 292 } finally { 293 repository.endTrans(false); 294 } 295 } 296 } 297 298 300 protected RefObject getNameAttr(String name) { 301 try { 302 return ((MofClass) refMetaObject()).lookupElementExtended(name); 303 } 304 catch (javax.jmi.model.NameNotFoundException e) { 305 return null; 306 } 307 } 308 309 316 protected void replaceJavaDoc(List diff) { 317 if (isChanged(CHANGED_JAVADOC)) { 318 ASTree tree = getASTree(); 319 Token docToken = getParser().getComment(tree); 320 String newContent = JavaDocParser.surroundWithJavaDocStars(javadocText); 324 if (docToken.getType() == ParserTokens.DOC_COMMENT && javadocText != null) { 325 diff.add(new DiffElement(docToken.getStartOffset(), 327 docToken.getEndOffset(), 328 indentJavaDoc(newContent).trim() 329 ) 330 ); 331 } else { 343 if (javadocText == null) { 345 int startOffset = docToken.getStartOffset(); 346 int endOffset = docToken.getEndOffset(); 347 if (getParser().getSourceText().length() > endOffset) { 348 int temp = getParser().getSourceText().indexOf('\n', endOffset); 349 if (temp > -1) { 350 endOffset = temp + 1; 351 } 352 } 353 diff.add(new DiffElement(startOffset, endOffset, "")); 354 } else { 355 int startOffset = getLastNewLineOffset(docToken) + 1; 362 String indentedDoc = getIndentation().concat(indentJavaDoc(newContent).trim()).concat("\n"); 363 if (startOffset <= 0) { 364 startOffset = docToken.getStartOffset(); 365 indentedDoc = '\n' + indentedDoc + getIndentation(); 366 } 367 diff.add(new DiffElement(startOffset, 368 startOffset, 369 indentedDoc 370 ) 371 ); 372 } 373 } 374 } 375 } 376 377 383 private int getLastNewLineOffset(Token token) { 384 Token[] pad = token.getPadding(); 385 if (pad == null) return -1; 388 for (int i = pad.length; i > 0; i--) { 389 if (pad[i-1].getType() == ParserTokens.EOL) { 390 String value = getParser().getText(pad[i-1]); 391 return pad[i-1].getStartOffset() + value.lastIndexOf('\n'); 392 } 393 } 394 return -1; 395 } 396 397 String getModifiersText() { 398 StringBuffer sb = new StringBuffer (); 399 int mod = getSourceModifiers(); 400 int len; 401 402 if ((mod & Modifier.PUBLIC) != 0) sb.append("public "); if ((mod & Modifier.PROTECTED) != 0) sb.append("protected "); if ((mod & Modifier.PRIVATE) != 0) sb.append("private "); 406 407 if ((mod & Modifier.ABSTRACT) != 0) sb.append("abstract "); if ((mod & Modifier.STATIC) != 0) sb.append("static "); if ((mod & Modifier.FINAL) != 0) sb.append("final "); if ((mod & Modifier.TRANSIENT) != 0) sb.append("transient "); if ((mod & Modifier.VOLATILE) != 0) sb.append("volatile "); if ((mod & Modifier.SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & Modifier.NATIVE) != 0) sb.append("native "); if ((mod & Modifier.STRICT) != 0) sb.append("strictfp "); 416 if ((len = sb.length()) > 0) 417 return sb.toString().substring(0, len-1); 418 return ""; 419 } 420 421 protected void diffModifiers(List diffList, ASTree nextNode, ASTProvider parser) { 422 String text = ""; 423 for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { 424 AnnotationImpl ann = (AnnotationImpl) annIt.next(); 425 text += ann.getSourceText() + '\n'; 426 text += getIndentation(); 427 } 428 String modText = getModifiersText(); 429 if (modText.length() > 0) { 430 text += modText; 431 } 432 int nextToken = nextNode.getFirstToken(); 433 int startOffset, endOffset; 434 int startToken; 435 endOffset = parser.getToken(nextToken).getStartOffset(); 436 ASTree modifiers = getASTree().getSubTrees()[0]; 437 if (modifiers != null) { 438 startToken = modifiers.getFirstToken(); 439 startOffset = parser.getToken(startToken).getStartOffset(); 440 if (text.length() > 0) { 441 int endToken = modifiers.getLastToken(); 442 endOffset = parser.getToken(endToken).getEndOffset(); 443 } 444 } else { 445 startOffset = endOffset; 446 if (modText.length() > 0) { 447 text += ' '; 448 } 449 } 450 diffList.add(new DiffElement(startOffset, endOffset, text)); 451 } 452 453 459 public boolean generateNewJavaDoc(StringBuffer buf) { 460 String javadoc = getJavadocText(); 461 if (javadoc != null) { 462 buf.append(indentJavaDoc(JavaDocParser.surroundWithJavaDocStars(javadoc))); 463 buf.append('\n').append(getIndentation()); 464 return true; 465 } 466 else 467 return false; 468 } 469 470 477 public boolean generateNewModifiers(StringBuffer buf) { 478 boolean nju = isNew(); 479 if (!nju) IndentUtil.reformatHeadGarbage(this, buf); 480 for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { 481 AnnotationImpl ann = (AnnotationImpl) annIt.next(); 482 buf.append(ann.getSourceText()).append('\n').append(getIndentation()); 483 } 484 String modString = getModifiersText(); 485 if (modString.length() > 0) { 486 buf.append(modString); 487 buf.append(' '); 488 return true; 489 } 490 else 491 return false; 492 } 493 494 498 Resource[] findReferencedResources() { 499 return findReferencedResources(false); 500 } 501 502 506 Resource[] findReferencedResources(boolean includeLibraries) { 507 int modifiers=getModifiers(); 508 String name; 509 Resource[] res; 510 511 if (Modifier.isPrivate(modifiers) || isTransient()) { 512 return new Resource[] {getResource()}; 513 } 514 if (this instanceof JavaClass) { 515 name=((JavaClass)this).getSimpleName(); 516 } else if (this instanceof Constructor) { 517 name=((JavaClass)getDeclaringClass()).getSimpleName(); 518 } else { 519 name=getName(); 520 } 521 res=ClassIndex.findResourcesForIdentifier(name, includeLibraries); 522 523 if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) { 524 if (this instanceof Field) { 525 Element cd = getDeclaringClass(); 526 boolean isPrivate = false; 527 boolean isPackagePrivate = false; 528 while (cd != null && !(cd instanceof Resource)) { 529 if (cd instanceof JavaClass) { 530 int m = ((JavaClass) cd).getModifiers(); 531 if (Modifier.isPrivate(m)) { 532 isPrivate = true; 533 break; 534 } else if (!isPackagePrivate && !Modifier.isPublic(m) && !Modifier.isProtected(m)) { 535 isPackagePrivate = true; 536 } 537 } 538 cd = (Element) cd.refImmediateComposite(); 539 } 540 if (isPrivate) { 541 return new Resource[] {getResource()}; 542 } else if (isPackagePrivate) { 543 return filterResourcesFromThisPackage(res); 544 } 545 } 546 return res; 547 } 548 return filterResourcesFromThisPackage(res); 549 } 550 551 Resource[] filterResourcesFromThisPackage(Resource[] res) { 552 List filteredResources=new ArrayList(res.length); 553 String packageName=getResource().getPackageName(); 554 for (int i=0;i<res.length;i++) { 555 Resource r=res[i]; 556 557 if (r.getPackageName().equals(packageName)) 558 filteredResources.add(r); 559 } 560 return (Resource[])filteredResources.toArray(new Resource[filteredResources.size()]); 561 } 562 563 568 protected String indentJavaDoc(String javadoc) { 569 if (javadoc == null) 570 return ""; 571 StringTokenizer t = new StringTokenizer(javadoc, "\n", true); StringBuffer b = new StringBuffer (); 573 String i = getIndentation(); 574 while (t.hasMoreTokens()) { 575 String line = t.nextToken(); 576 b.append(line); 577 if (line.equals("\n")) b.append(i); 579 } 580 return b.toString(); 581 } 582 583 protected String getIndentation() { 584 return ((MetadataElement) refImmediateComposite()).getIndentation().concat(INDENTATION); 585 } 586 587 public List getChildren() { 588 List list = new ArrayList(); 589 list.addAll(getAnnotations()); 590 return list; 591 } 592 593 public void fixImports(Element scope, Element original) { 594 fixImports(scope,getAnnotations(),((Feature)original).getAnnotations()); 595 } 596 597 protected List getInitedChildren() { 598 List result = new ArrayList(); 599 if (childrenInited) { 600 result.addAll(getAnnotations()); 601 } 602 return result; 603 } 604 605 protected ASTree getPartTree(ElementPartKind part) { 607 if (ElementPartKindEnum.HEADER.equals(part)) { 608 return getASTree(); 609 } 610 throw new IllegalArgumentException ("Invalid part for this element: " + part.toString()); } 612 613 public void replaceChild(Element oldElement, Element newElement) { 614 super.replaceChild(oldElement, newElement); 615 if (childrenInited) { 616 if (replaceObject(getAnnotations(), oldElement, newElement)) return; 617 } 618 if (javadoc != null) { 619 if (javadoc.equals(oldElement)) { 620 changeChild(oldElement, newElement); 621 javadoc.refDelete(); 622 javadoc = (JavaDoc) newElement; 623 return; 624 } 625 } 626 } 627 628 protected void setData(List annotations, String javadocText, JavaDoc javadoc) { 629 this.annotations = createChildrenList( "annotations", (AttrListWrapper) super_getAnnotations(), annotations, CHANGED_ANNOTATION); if (javadocText == null) { 631 changeChild(null, javadoc); 632 this.javadoc = javadoc; 633 } else { 634 if (javadoc != null) { 635 throw new ConstraintViolationException(this, getNameAttr("javadoc"), "Cannot set both javadocText and javadoc."); } 637 this.javadocText = javadocText; 638 } 639 childrenInited = true; 640 } 641 642 protected void setTypeRef(TypeRef type) { 643 _getDelegate().setSlot1(type); 644 } 645 646 public TypeRef getTypeRef() { 647 return (TypeRef) _getDelegate().getSlot1(); 648 } 649 650 protected void matchPersistent(ElementInfo info) { 651 super.matchPersistent(info); 652 matchModifiers(info); 653 } 654 655 protected void matchElementInfo(ElementInfo newInfo) { 656 super.matchElementInfo(newInfo); 657 resetJavaDoc(); 658 } 659 660 protected void matchModifiers(ElementInfo info) { 661 if (((FeatureInfo) info).modifiers != getSourceModifiers()) { 662 setModifiers(((FeatureInfo) info).modifiers); 663 } 664 } 665 666 protected abstract List super_getAnnotations(); 667 protected abstract String super_getJavadocText(); 668 protected abstract void super_setJavadocText(String text); 669 670 public boolean isPersisted() { 671 return super_getJavadocText() != null; 672 } 673 674 public void setPersisted(boolean persisted) { 675 super_setJavadocText(persisted ? "" : null); 676 } 677 678 private void resetJavaDoc() { 679 javadocText = null; 680 if (javadoc != null) { 681 changeChild(javadoc, null); 682 javadoc.refDelete(); 683 javadoc = null; 684 } 685 } 686 687 protected void _delete() { 688 deleteChildren("annotations", (AttrListWrapper) super_getAnnotations()); 691 resetJavaDoc(); 692 super._delete(); 697 } 698 699 protected void reformatComment(final StringBuffer buf) { 700 Token[] t = getParser().getToken(getASTree().getFirstToken()).getPadding(); 701 if (t.length > 0) { 702 String doc = IndentUtil.indentExistingElement(this, 703 getParser().getSourceText().substring(t[0].getStartOffset(), t[t.length-1].getEndOffset())); 704 if (doc.length() > 0) { 705 doc = doc.substring(1) + '\n'; 706 buf.append(doc); 707 } 708 } 709 } 710 } 711 | Popular Tags |