1 19 20 package org.netbeans.modules.javadoc.comments; 21 22 import java.text.MessageFormat ; 23 import java.text.Format ; 24 import javax.swing.*; 25 import javax.jmi.reflect.JmiException; 26 import java.lang.ref.WeakReference ; 27 import java.lang.reflect.Modifier ; 28 29 import org.openide.src.JavaDoc; 30 import org.openide.cookies.EditorCookie; 31 import org.openide.cookies.SourceCookie; 32 import org.openide.nodes.Node; 33 import org.openide.loaders.DataObject; 34 import org.openide.loaders.DataFolder; 35 import org.openide.util.Utilities; 36 import org.openide.util.RequestProcessor; 37 import org.openide.util.Lookup; 38 import org.openide.ErrorManager; 39 import org.openide.filesystems.FileObject; 40 import org.openide.src.JavaDocTag; 41 import org.openide.src.SourceException; 42 import org.openide.src.JavaDocSupport; 43 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 44 import org.netbeans.modules.java.ui.nodes.SourceNodes; 45 import org.netbeans.jmi.javamodel.*; 46 import org.netbeans.api.mdr.events.MDRChangeListener; 47 import org.netbeans.api.mdr.events.MDRChangeEvent; 48 import org.netbeans.api.mdr.events.ExtentEvent; 49 import org.netbeans.api.mdr.events.InstanceEvent; 50 import org.netbeans.api.mdr.MDRepository; 51 52 import java.beans.PropertyChangeListener ; 53 import java.beans.PropertyChangeEvent ; 54 import java.util.*; 55 import java.util.List ; 56 import java.awt.*; 57 import org.netbeans.modules.javacore.api.JavaModel; 58 59 66 public final class AutoCommenter extends Object implements JavaTagNames { 67 68 public static final int JDC_OK = 1; 69 public static final int JDC_MISSING = 2; 70 public static final int JDC_ERROR = 4; 71 72 private static final RequestProcessor QUEUE = new RequestProcessor("Auto CommenterQueue"); 74 75 private final ArrayList dataObjects; 76 ArrayList elements; 77 Node[] nodes; 78 79 private final WPCL dataObjectListener = new WPCL(this); 80 81 82 private AutoCommentChangeListener autoCommentChangeListener = null; 83 84 85 AutoCommenter() { 86 this( new Node[0] ); 87 } 88 89 90 AutoCommenter ( Node[] nodes ) { 91 dataObjects = new ArrayList(); 92 this.nodes = nodes; 93 } 94 95 private void updateDataObjects() { 96 97 List newDOs = new LinkedList(); 98 99 for (int i = 0; i < nodes.length; i++) { 100 DataFolder df = (DataFolder) nodes[i].getCookie(DataFolder.class); 101 Object cookie = null; 102 if(df != null && df.isValid()){ 103 DataObject[] children = df.getChildren(); 104 for (int n = 0; n < children.length; n++){ 105 final DataObject child = children[n]; 106 cookie = child.getCookie(SourceCookie.class); 107 FileObject childFO = child.getPrimaryFile(); 108 if (cookie != null && childFO.canWrite() 109 && !"class".equalsIgnoreCase(childFO.getExt())){ if(!newDOs.contains(child)){ 111 child.addPropertyChangeListener(dataObjectListener); 112 newDOs.add(child); 113 } 114 } 115 } 116 continue; 117 } else { 118 Lookup lkp = nodes[i].getLookup(); 119 cookie = lkp.lookup(org.netbeans.jmi.javamodel.Element.class); 120 if (cookie == null) { 121 cookie = lkp.lookup(SourceCookie.class); 122 } 123 } 124 final DataObject doj = (DataObject) nodes[i].getCookie(DataObject.class); 125 if ( cookie == null || doj == null || !doj.getPrimaryFile().canWrite() 126 || "class".equalsIgnoreCase(doj.getPrimaryFile().getExt())) continue; 128 129 if(!newDOs.contains(doj)) { 130 doj.addPropertyChangeListener(dataObjectListener); 131 newDOs.add(doj); 132 } 133 } 134 135 synchronized (dataObjects) { 136 this.dataObjects.removeAll(newDOs); 137 for (Iterator it = this.dataObjects.iterator(); it.hasNext();) { 138 DataObject dataObject = (DataObject) it.next(); 139 dataObject.removePropertyChangeListener(this.dataObjectListener); 140 } 141 this.dataObjects.clear(); 142 this.dataObjects.addAll(newDOs); 143 this.dataObjectListener.setDataObjects(newDOs); 144 } 145 } 146 147 private static class WPCL extends WeakReference implements PropertyChangeListener , MDRChangeListener, Runnable { 148 149 private List dataObjects = null; 150 private MDRepository repository; 151 152 public WPCL(AutoCommenter ac) { 153 super(ac, Utilities.activeReferenceQueue()); 154 initMDRListener(); 155 } 156 157 public synchronized void setDataObjects(List dos) { 158 this.dataObjects = dos; 159 } 160 161 public void propertyChange(PropertyChangeEvent evt) { 162 AutoCommenter ac = (AutoCommenter) get(); 163 if (ac == null) return; 164 DataObject doj = (DataObject) evt.getSource(); 165 if(evt.getPropertyName().equals(DataObject.PROP_VALID)){ 166 synchronized (this) { 167 if (dataObjects != null) { 168 doj.removePropertyChangeListener(this); 169 if (dataObjects.remove(doj)) 170 ac.refreshFromSource(); 171 } 172 } 173 } 174 } 175 176 public void change(MDRChangeEvent e) { 177 AutoCommenter ac = (AutoCommenter) get(); 178 if (ac == null) return; 179 180 if ((e instanceof ExtentEvent) && e.getType() == ExtentEvent.EVENT_EXTENT_DELETE) { 181 ac.refreshFromSource(); 182 } else if (e instanceof InstanceEvent) { 183 InstanceEvent ie = (InstanceEvent) e; 184 handleElementDelete(ie); 185 } 186 } 187 188 private void handleElementDelete(InstanceEvent e) { 189 final Object instance = e.getInstance(); 190 if (e.getType() != InstanceEvent.EVENT_INSTANCE_DELETE || !(instance instanceof ClassMember)) return; 191 192 AutoCommenter ac = (AutoCommenter) get(); 193 if (ac == null) return; 194 195 for (Iterator it = ac.elements.iterator(); it.hasNext();) { 196 Element element = (Element) it.next(); 197 if (instance == element.getSrcElement()) { 198 element.isValid = false; 199 return; 200 } 201 } 202 } 203 204 public void run() { 205 if (dataObjects != null) { 206 for (Iterator it = dataObjects.iterator(); it.hasNext();) { 207 DataObject d = (DataObject) it.next(); 208 d.removePropertyChangeListener(this); 209 } 210 } 211 if (repository != null) { 212 repository.removeListener(this); 213 } 214 } 215 216 219 private void initMDRListener() { 220 this.repository = JavaModel.getJavaRepository(); 221 this.repository.addListener(this); 222 } 223 } 224 225 228 public void refreshFromSource() { 229 QUEUE.post(new Runnable () { 230 public void run() { 231 refreshFromSourceImpl(); 232 fireAutocommentChangeEvent(); 233 } 234 }); 235 } 236 237 244 public void modifyJavadoc(final AutoCommenter.Element el, final JavaDoc doc) { 245 QUEUE.post(new Runnable () { 246 public void run() { 247 try { 248 JavaModel.getJavaRepository().beginTrans(true); 249 try { 250 if (el.getSrcElement().isValid()) { 251 el.setJavaDoc(doc); 252 el.checkError(); 253 fireElementUpdatedEvent(el); 254 } 255 } finally { 256 JavaModel.getJavaRepository().endTrans(); 257 } 258 } catch (JmiException e) { 259 ErrorManager.getDefault().notify(e); 260 } 261 } 262 }); 263 } 264 265 273 public void autoCorrectJavadoc(final AutoCommenter.Element element, final JavaDoc doc) { 274 QUEUE.post(new Runnable () { 275 public void run() { 276 try { 277 JavaModel.getJavaRepository().beginTrans(true); 278 try { 279 if (element.getSrcElement().isValid()) { 280 if (doc != null) { 281 element.setJavaDoc(doc); 282 } 283 element.autoCorrect(); 284 element.checkError(); 285 fireElementUpdatedEvent(element); 286 } 287 } finally { 288 JavaModel.getJavaRepository().endTrans(); 289 } 290 } catch (JmiException e) { 291 ErrorManager.getDefault().notify(e); 292 } catch (org.openide.src.SourceException e) { 293 ErrorManager.getDefault().notify(e); 294 } 295 } 296 }); 297 } 298 299 305 public void autoCorrectJavadoc(final AutoCommenter.Element[] elements) { 306 if (elements == null) { 307 throw new NullPointerException ("elements"); } 309 QUEUE.post(new Runnable () { 310 public void run() { 311 try { 312 JavaModel.getJavaRepository().beginTrans(true); 313 try { 314 for (int i = 0; i < elements.length; i++) { 315 Element element = elements[i]; 316 if (element.getSrcElement().isValid()) { 317 element.autoCorrect(); 318 element.checkError(); 319 } 320 } 321 fireAutocommentChangeEvent(); 322 } finally { 323 JavaModel.getJavaRepository().endTrans(); 324 } 325 } catch (JmiException e) { 326 ErrorManager.getDefault().notify(e); 327 } catch (org.openide.src.SourceException e) { 328 ErrorManager.getDefault().notify(e); 329 } 330 } 331 }); 332 } 333 334 private void refreshFromSourceImpl() { 335 updateDataObjects(); 336 List dobjs; 337 synchronized (this.dataObjects) { 338 dobjs = new ArrayList(this.dataObjects); 339 } 340 elements = new ArrayList(dobjs.size()); 341 try { 342 JavaModel.getJavaRepository().beginTrans(false); 343 try { 344 for (Iterator it = dobjs.iterator(); it.hasNext();) { 345 DataObject d = (DataObject) it.next(); 346 Resource r = JavaModel.getResource(d.getPrimaryFile()); 347 if (r != null) { 348 addCommentable(r); 349 } 350 } 351 } finally { 352 JavaModel.getJavaRepository().endTrans(); 353 } 354 } catch (JmiException ex) { 355 ErrorManager.getDefault().notify(ex); 356 } 357 } 358 359 private void addCommentable(Resource r){ 360 List classes = JMIUtils.getAllClasses(r); 361 for (Iterator it = classes.iterator(); it.hasNext();) { 362 JavaClass jc = (JavaClass) it.next(); 363 if (jc.isValid()) { 364 addElements(jc); 365 } 366 } 367 } 368 369 private void prepareListModel( DefaultListModel listModel, int mask, boolean pckg, int err_mask ) { 370 for(Iterator it = elements.iterator(); it.hasNext(); ) { 371 Element el = (Element) it.next(); 372 373 if ( acceptElement( el, mask, pckg, err_mask ) ) { 374 listModel.addElement(el); 375 } 376 } 377 } 378 379 static boolean acceptElement( Element el, int mask, boolean pckg, int err_mask ) { 380 381 383 if ( ( el.getErrorNumber() & err_mask ) == 0 ) 384 return false; 385 386 int access = el.getDescriptor().getEffectiveAccess(); 388 if (access == 0) 389 return pckg; 390 else 391 return (access & mask) > 0; 392 } 393 394 DefaultListModel prepareListModel( int mask, boolean pckg, int err_mask ) { 395 DefaultListModel dm = new DefaultListModel(); 396 prepareListModel( dm, mask, pckg, err_mask ); 397 return dm; 398 } 399 400 private void addElements(JavaClass classElement ) { 401 elements.add(createAutoCommenterElement(classElement)); 402 403 List features = classElement.getFeatures(); 404 for (Iterator it = features.iterator(); it.hasNext();) { 405 Object feature = it.next(); 406 if (feature instanceof JavaClass || !(feature instanceof ClassMember)) 407 continue; 408 Element el = createAutoCommenterElement((ClassMember) feature); 409 if (el != null) 410 elements.add(el); 411 } 412 } 413 414 419 public static Element createAutoCommenterElement(ClassMember element) { 420 Element jdElement = null; 421 if (element instanceof JavaClass) { 422 jdElement = new Element.Class((JavaClass) element); 424 } else if (element instanceof org.netbeans.jmi.javamodel.Field) { 425 jdElement = new Element.Field((org.netbeans.jmi.javamodel.Field) element); 427 } else if (element instanceof org.netbeans.jmi.javamodel.Constructor) { 428 jdElement = new Element.Constructor((org.netbeans.jmi.javamodel.Constructor) element); 429 } else if (element instanceof org.netbeans.jmi.javamodel.Method) { 430 jdElement = new Element.Method((org.netbeans.jmi.javamodel.Method) element); 431 } else if (element instanceof Attribute) { 432 jdElement = new Element.Field((Attribute) element); 433 } 434 if (jdElement != null) { 435 jdElement.initialize(); 436 } 437 return jdElement; 438 } 439 440 441 442 static abstract class Element { 443 444 private DefaultListModel errorList; 445 446 protected final ClassMember srcElement; 447 private int srcError = JDC_OK; 448 449 private JavaDoc javadoc; 450 451 private ElementDescriptor desc; 452 453 private boolean isValid = true; 454 455 protected Element(ClassMember srcElement) { 456 this.srcElement = srcElement; 457 } 458 459 464 protected final void initialize() throws JmiException { 465 javadoc = createJavaDoc(); 466 desc = new ElementDescriptor(this, getNameFormat()); 467 checkError(); 468 } 469 470 public final boolean isValid() { 471 return isValid; 472 } 473 474 477 public final ElementDescriptor getDescriptor() throws JmiException { 478 assert desc != null; 479 return desc; 480 } 481 482 public final ClassMember getSrcElement() { 483 return srcElement; 484 } 485 486 public final int getErrorNumber() { 487 return srcError; 488 } 489 490 public final void viewSource() { 491 AutoCommenter.QUEUE.post(new Runnable () { 492 int state = 0; 493 EditorCookie ec; 494 int offset; 495 DataObject dobj; 496 497 public void run() { 498 switch (state) { 499 case 0: 500 findOffset(); 501 break; 502 case 1: 503 open(); 504 break; 505 } 506 } 507 508 void findOffset() { 509 try { 510 JavaModel.getJavaRepository().beginTrans(false); 511 try { 512 if (!srcElement.isValid()) return; 513 514 Resource r = srcElement.getResource(); 515 if (r == null) return; 516 offset = JavaMetamodel.getManager(). 517 getElementPosition(srcElement).getBegin().getOffset(); 518 dobj = JavaMetamodel.getManager().getDataObject(r); 519 if (dobj == null) return; 520 ec = (EditorCookie) dobj.getCookie(EditorCookie.class); 521 if (ec == null) return; 522 ++state; 523 EventQueue.invokeLater(this); 524 } finally { 525 JavaModel.getJavaRepository().endTrans(); 526 } 527 } catch (JmiException e) { 528 ErrorManager.getDefault().notify(e); 529 return; 530 } 531 } 532 533 void open() { 534 ec.open(); 535 JEditorPane[] epane = ec.getOpenedPanes(); 536 if (epane != null && epane.length > 0) { 537 epane[0].getCaret().setDot(offset); 538 epane[0].requestFocus(); 539 } 540 } 541 }); 542 } 543 544 public synchronized final DefaultListModel getErrorList() { 545 return errorList; 546 } 547 548 protected abstract String [] getNotPermittedTags(); 549 550 555 protected abstract boolean elementTagsOk(DefaultListModel errList); 556 557 561 public abstract void autoCorrect() throws SourceException; 562 563 protected abstract JavaDoc createJavaDoc(); 564 565 public final JavaDoc getJavaDoc() { 566 assert javadoc != null; 567 return javadoc; 568 } 569 570 575 public final void setJavaDoc(final JavaDoc doc) throws JmiException { 576 if (doc == null) throw new NullPointerException ("doc"); 578 this.srcElement.setJavadocText(doc.getRawText()); 579 this.javadoc = createJavaDoc(); 580 } 581 582 protected abstract Format getNameFormat(); 583 584 protected abstract String typeToString(); 585 586 static boolean isPermittedTag(JavaDocTag tag, String [] notPermittedTags ) { 587 String tagName = tag.name(); 588 589 for ( int i = 0; i < notPermittedTags.length; i++ ) { 590 if ( tagName.equals( notPermittedTags[i] ) ) 591 return false; 592 } 593 594 return true; 595 } 596 597 private static boolean isEmptyString( String string ) { 598 return string == null || string.trim().length() <= 0; 599 } 600 601 603 604 private boolean isOkTag(JavaDocTag tag, DefaultListModel errList ) { 605 if ( isEmptyString( tag.text() ) ) { 606 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_EmptyTag" ), new Object [] { tag.name() } ) ); 608 return false; 609 } 610 611 if ( tag instanceof JavaDocTag.See ) { 612 int len; 613 String text; 614 JavaDocTag.See seetag = (JavaDocTag.See) tag; 615 616 if ((seetag.referencedClassName() != null) || (seetag.referencedMemberName() != null)) 617 return true; 618 text=tag.text(); 619 len = text.length(); 620 if (len >= 2) { 621 char first=text.charAt(0); 622 char last=text.charAt(len-1); 623 624 if (first=='"' && last==first) 625 return true; 626 if (first=='<' && last=='>') 627 return true; 628 } 629 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_InvalidTag" ), new Object [] { seetag } )); return false; 632 } 633 else if ( tag instanceof JavaDocTag.Param ) { 634 if ( isEmptyString( ((JavaDocTag.Param)tag).parameterName() ) ) { 635 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_ParamNoName" ), new Object [] { tag.name() } ) ); 637 return false; 638 } 639 if ( isEmptyString( ((JavaDocTag.Param)tag).parameterComment() ) ) { 640 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_ParamNoDescr" ), new Object [] { tag.name(), ((JavaDocTag.Param)tag).parameterName() } ) ); 642 return false; 643 } 644 } 645 else if ( tag instanceof JavaDocTag.Throws ) { 646 if ( isEmptyString( ((JavaDocTag.Throws)tag).exceptionName() ) ) { 647 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_ThrowsNoName" ), new Object [] { tag.name() } ) ); 649 return false; 650 } 651 if ( isEmptyString( ((JavaDocTag.Throws)tag).exceptionComment() ) ) { 652 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_ThrowsNoDescr" ), new Object [] { tag.name(), ((JavaDocTag.Throws)tag).exceptionName() } ) ); 654 return false; 655 } 656 } 657 else if ( tag instanceof JavaDocTag.SerialField ) { 658 if ( isEmptyString( ((JavaDocTag.SerialField)tag).fieldName() ) ) { 659 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoName" ), new Object [] { tag.name() } ) ); 661 return false; 662 } 663 if ( isEmptyString( ((JavaDocTag.SerialField)tag).fieldType() ) ) { 664 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoType" ), new Object [] { tag.name(), ((JavaDocTag.SerialField)tag).fieldName() } ) ); 666 return false; 667 } 668 669 if ( isEmptyString( ((JavaDocTag.SerialField)tag).description() ) ) { 670 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoDescr" ), new Object [] { tag.name(), ((JavaDocTag.SerialField)tag).fieldName() } ) ); 672 return false; 673 } 674 } 675 return true; 676 } 677 678 protected final boolean isMultipleTags(String tag, DefaultListModel errList) { 679 boolean error = false; 681 JavaDocTag[] tags = getJavaDoc().getTags(tag); 682 if ( tags.length > 1) { 683 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedTag" ), new Object [] { tags[0].name() } ) ); 685 error = true; 686 } 687 return error; 688 } 689 690 693 public final void checkError() { 694 695 DefaultListModel _errorList = new DefaultListModel(); 696 697 JavaDoc jdoc = getJavaDoc(); 698 699 if ( jdoc.isEmpty() ) { 700 _errorList.addElement( ResourceUtils.getBundledString( "ERR_JavadocMissing" ) ); synchronized(this) { 702 srcError = JDC_MISSING; 703 this.errorList = _errorList; 704 } 705 desc.recomputeIcon(); 706 return; 707 } 708 709 JavaDocTag[] tags = jdoc.getTags(); 710 boolean error = false; 711 712 if ( jdoc.getText() == null || jdoc.getText().trim().length() <= 0 ) { 713 _errorList.addElement( ResourceUtils.getBundledString( "ERR_EmptyText" ) ); error = true; 715 } 716 717 for ( int i = 0; i < tags.length; i ++ ) { 718 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) { 719 _errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_BadTag" ), new Object [] { tags[i].name(), typeToString() } ) ); 721 error = true; 722 continue; 723 } 724 725 if (!isOkTag(tags[i], _errorList)) { 726 error = true; 727 continue; 728 } 729 } 730 731 if (isMultipleTags(TAG_SINCE, _errorList)) { 732 error = true; 733 } 734 735 if (isMultipleTags(TAG_DEPRECATED, _errorList)) { 736 error = true; 737 } 738 739 if (!elementTagsOk(_errorList)) { 740 error = true; 741 } 742 743 if ( !error ) { 744 _errorList.addElement( ResourceUtils.getBundledString( "ERR_JavadocOK" ) ); } 746 747 synchronized (this) { 748 srcError = error ? JDC_ERROR : JDC_OK; 749 this.errorList = _errorList; 750 } 751 desc.recomputeIcon(); 752 } 753 754 759 public boolean isCorrectable() { 760 assert this.javadoc != null; 761 assert this.desc != null; 762 JavaDocTag[] tags = getJavaDoc().getTags(); 763 764 for ( int i = 0; i < tags.length; i ++ ) { 765 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) { 766 return true; 767 } 768 } 769 770 return false; 771 } 772 773 778 protected void autoCorrect( JavaDoc jdoc ) throws SourceException { 779 JavaDocTag[] tags = jdoc.getTags(); 780 ArrayList correctedTags = new ArrayList( tags.length ); 781 String correctedText; 782 783 correctedText = jdoc.getText(); 784 785 if ( correctedText == null ) { 786 correctedText = ""; } 788 789 for ( int i = 0; i < tags.length; i ++ ) { 790 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) { 791 continue; 792 } 793 correctedTags.add( tags[i] ); 794 } 795 796 jdoc.changeTags( (JavaDocTag[])correctedTags.toArray( new JavaDocTag[ correctedTags.size() ] ), JavaDoc.SET ); 797 } 798 799 private static void log(DefaultListModel errList, String txt) { 800 if (errList != null) { 801 errList.addElement(txt); 802 } 803 } 804 805 public boolean equals(Object o) { 806 if (this == o) return true; 807 if (!(o instanceof Element)) return false; 808 809 final Element element = (Element) o; 810 811 if (desc != null && element.desc != null && desc.getIdentity().equals(element.desc.getIdentity())) { 812 return true; 813 } 814 815 return false; 816 } 817 818 public int hashCode() { 819 return (desc != null ? desc.getIdentity().hashCode() : 0); 820 } 821 822 823 static class Class extends Element { 824 825 private static final String [] NOT_PERMITTED_TAGS = { 826 TAG_EXCEPTION, 827 TAG_PARAM, 828 TAG_RETURN, 829 TAG_SERIAL, 830 TAG_SERIALDATA, 831 TAG_SERIALFIELD, 832 TAG_THROWS, 833 }; 834 835 private static final Format nameFormat = SourceNodes.createElementFormat("{C}"); 837 protected Class( JavaClass element ) { 838 super( element ); 839 } 840 841 public String [] getNotPermittedTags() { 842 return NOT_PERMITTED_TAGS; 843 } 844 845 protected boolean elementTagsOk(DefaultListModel errList) { 846 boolean error = false; 847 if (this.isMultipleTags(TAG_VERSION, errList)) { 848 error = true; 849 } 850 return !error; 851 } 852 853 public void autoCorrect() throws SourceException { 854 super.autoCorrect( getJavaDoc() ); 855 setJavaDoc(getJavaDoc()); 856 } 857 858 public String typeToString() { 859 String type; 860 if (this.srcElement instanceof JavaEnum) { 861 type = "enum"; } else if (this.srcElement instanceof AnnotationType) { 863 type = "annotation type"; } else { 865 type = Modifier.isInterface(getDescriptor().getModifiers()) 866 ? "interface" : "class"; } 868 return type; 869 } 870 871 protected JavaDoc createJavaDoc() { 872 String s = srcElement.getJavadocText(); 873 JavaDoc javadoc = JavaDocSupport.createClassJavaDoc(s); 874 return javadoc; 875 } 876 877 public Format getNameFormat () { 878 return nameFormat; 879 } 880 881 } 882 883 static class Field extends Element { 884 885 private static final String [] NOT_PERMITTED_TAGS = { 886 TAG_AUTHOR, 887 TAG_EXCEPTION, 888 TAG_PARAM, 889 TAG_RETURN, 890 TAG_SERIALDATA, 891 TAG_THROWS, 892 TAG_VERSION 893 }; 894 895 private static final Format nameFormat = SourceNodes.createElementFormat("{n}"); 897 protected Field(org.netbeans.jmi.javamodel.Field element ) { 898 super( element ); 899 } 900 901 protected Field(Attribute element ) { 902 super( element ); 903 } 904 905 protected JavaDoc createJavaDoc() { 906 String s = srcElement.getJavadocText(); 907 JavaDoc javaDoc = JavaDocSupport.createFieldJavaDoc(s); 908 return javaDoc; 909 } 910 911 public String [] getNotPermittedTags() { 912 return NOT_PERMITTED_TAGS; 913 } 914 915 public String typeToString() { 916 return this.srcElement instanceof Field? "field": "attribute"; } 918 919 protected boolean elementTagsOk(DefaultListModel errList) { 920 boolean error = false; 921 if (this.isMultipleTags(TAG_SERIAL, errList)) { 922 error = true; 923 } 924 925 return !error; 926 } 927 928 public void autoCorrect() throws SourceException { 929 super.autoCorrect( getJavaDoc() ); 930 setJavaDoc(getJavaDoc()); 931 } 932 933 public Format getNameFormat () { 934 return nameFormat; 935 } 936 } 937 938 static class Constructor extends Element { 939 940 private static final String [] NOT_PERMITTED_TAGS = { 941 TAG_AUTHOR, 942 TAG_SERIAL, 943 TAG_SERIALFIELD, 944 TAG_VERSION, 945 TAG_RETURN 946 }; 947 948 private static final Format nameFormat = SourceNodes.createElementFormat("{n}({p,,,\",\"})"); 950 protected Constructor(org.netbeans.jmi.javamodel.CallableFeature element) { 951 super( element ); 952 } 953 954 protected JavaDoc createJavaDoc() { 955 String s = srcElement.getJavadocText(); 956 JavaDoc javadoc = JavaDocSupport.createMethodJavaDoc(s); 957 return javadoc; 958 } 959 960 public String [] getNotPermittedTags() { 961 return NOT_PERMITTED_TAGS; 962 } 963 964 public String typeToString() { 965 return "constructor"; } 967 968 protected boolean elementTagsOk(DefaultListModel errList) { 969 return elementTagsOk( null, false, errList ); 970 } 971 972 private boolean elementTagsOk( ArrayList correctedTags, boolean checkOnly, DefaultListModel errList ) { 973 974 boolean error = false; 975 976 978 JavaDoc jdoc = getJavaDoc(); 979 JavaDocTag.Param[] ptags = ((JavaDoc.Method) jdoc).getParamTags(); 980 boolean[] ptags_found = new boolean[ ptags.length ]; 981 982 String [] params = getDescriptor().getParameterNames(); 985 for (int j = 0; j < params.length; j++) { 986 String param = params[j]; 987 boolean tagFound = false; 988 boolean duplicateTagAlreadyFound = false; 989 for (int i = 0 ; i < ptags.length ; i++) { 990 if (ptags[i].parameterName() != null && ptags[i].parameterName().equals(param)) { 991 ptags_found[i] = true; 992 if (!tagFound) { 993 tagFound = true; 994 } else if (! duplicateTagAlreadyFound) { 995 if ( checkOnly ) { 996 return false; 997 } else if ( correctedTags == null ) { 998 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedParamTag" ), new Object [] { param } ) ); 1000 } 1001 error = true; 1002 duplicateTagAlreadyFound = true; 1003 } 1004 } 1005 } 1006 1007 if (! tagFound ) { 1008 if ( checkOnly ) { 1009 return false; 1010 } else if ( correctedTags == null ) { 1011 error = true; 1012 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoTagForParam" ), new Object [] { param } ) ); 1014 } 1015 else { 1016 correctedTags.add( JavaDocSupport.createParamTag( TAG_PARAM, param ) ); 1017 } 1018 } 1019 } 1020 1021 for( int i = 0; i < ptags.length; i++ ) { 1022 if ( !ptags_found[i] ) { 1023 if ( checkOnly ) { 1024 return false; 1025 } 1026 else if ( correctedTags == null ) { 1027 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoSuchParam" ), new Object [] { ptags[i].name(), ptags[i].parameterName() } ) ); 1029 } 1030 error = true; 1031 } 1032 else if ( correctedTags != null ) { 1033 correctedTags.add( ptags[i] ); 1034 } 1035 1036 1037 } 1038 1040 1041 JavaDocTag.Throws[] ttags = ((JavaDoc.Method) getJavaDoc()).getThrowsTags(); 1042 boolean[] ttags_found = new boolean[ ttags.length ]; 1043 String [] excs = getDescriptor().getThrowFQNames(); 1044 1045 for (int j = 0; j < excs.length; j++) { 1048 String excFQN = excs[j]; 1049 boolean tagFound = false; 1050 boolean duplicateTagAlreadyFound = false; 1051 for (int i = 0 ; i < ttags.length ; i++) { 1052 String tagExId = ttags[i].exceptionName().replaceFirst("\\.+\\z", ""); 1056 1057 if (tagExId.length() > 0 && excFQN.endsWith(tagExId)) { 1058 ttags_found[i] = true; 1059 if (!tagFound) { 1060 tagFound = true; 1061 } else if (! duplicateTagAlreadyFound){ 1062 if ( checkOnly ) { 1063 return false; 1064 } 1065 else if ( correctedTags == null ) { 1066 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedExceptionTag" ), new Object [] { excFQN })); 1068 } 1069 error = true; 1070 duplicateTagAlreadyFound = true; 1071 } 1072 } 1073 } 1074 1075 if (! tagFound ) { 1076 if ( checkOnly ) { 1077 return false; 1078 } else if ( correctedTags == null ) { 1079 error = true; 1080 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoTagForException" ), new Object [] { excFQN })); 1082 } 1083 else { 1084 correctedTags.add( JavaDocSupport.createThrowsTag( TAG_THROWS, excFQN)); 1085 } 1086 } 1087 } 1088 1089 for( int i = 0; i < ttags.length; i++ ) { 1090 if ( !ttags_found[i] ) { 1091 if ( checkOnly ) { 1092 return false; 1093 } 1094 else if ( correctedTags == null ) { 1095 log(errList, MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoSuchException" ), new Object [] { ttags[i].name(), ttags[i].exceptionName() } ) ); 1097 } 1098 error = true; 1099 } 1100 else if ( correctedTags != null ) { 1101 correctedTags.add( ttags[i] ); 1102 } 1103 1104 1105 } 1106 1107 return !error; 1108 } 1109 1110 public boolean isCorrectable () { 1111 if ( super.isCorrectable() ) 1112 return true; 1113 1114 return !elementTagsOk( null, true, null ); 1115 } 1116 1117 public void autoCorrect() throws SourceException { 1118 autoCorrect(getJavaDoc()); 1119 setJavaDoc(getJavaDoc()); 1120 } 1121 1122 public void autoCorrect( JavaDoc jDoc ) throws SourceException { 1123 JavaDoc.Method jdTemp = JavaDocSupport.createMethodJavaDoc(getJavaDoc().getRawText()); 1124 1125 1127 JavaDocTag tags[] = jdTemp.getTags(); 1128 ArrayList stdTags = new ArrayList( tags.length ); 1129 1130 for( int i = 0; i < tags.length; i++ ) { 1131 if ( !( tags[i] instanceof JavaDocTag.Param ) && 1132 !( tags[i] instanceof JavaDocTag.Throws ) ) { 1133 stdTags.add( tags[i] ); 1134 } 1135 } 1136 1137 jdTemp.changeTags( (JavaDocTag[])stdTags.toArray( new JavaDocTag[ stdTags.size() ] ), JavaDoc.SET ); 1138 1139 super.autoCorrect( jdTemp ); 1140 1141 ArrayList correctedTags = new ArrayList(); 1142 elementTagsOk( correctedTags, false, null ); 1143 1144 1146 ArrayList allTags = new ArrayList( correctedTags.size() + tags.length ); 1147 tags = jdTemp.getTags(); 1148 for( int i = 0; i < tags.length; i++ ) { 1149 allTags.add( tags[i] ); 1150 } 1151 allTags.addAll( correctedTags ); 1152 1153 jDoc.changeTags( (JavaDocTag[])allTags.toArray( new JavaDocTag[ allTags.size() ] ), JavaDoc.SET ); 1154 } 1155 1156 public Format getNameFormat () { 1157 return nameFormat; 1158 } 1159 1160 } 1161 1162 static class Method extends Constructor { 1163 1164 private static final Format nameFormat = SourceNodes.createElementFormat("{n}({p,,,\",\"})"); 1166 private static final String [] NOT_PERMITTED_TAGS = { 1167 TAG_AUTHOR, 1168 TAG_SERIAL, 1169 TAG_SERIALFIELD, 1170 TAG_VERSION 1171 }; 1172 1173 Method(org.netbeans.jmi.javamodel.Method element) { 1174 super( element ); 1175 } 1176 1177 public String typeToString() { 1178 return "method"; } 1180 1181 public String [] getNotPermittedTags() { 1182 return NOT_PERMITTED_TAGS; 1183 } 1184 1185 protected boolean elementTagsOk(DefaultListModel errList) { 1186 boolean superOk = super.elementTagsOk(errList); 1187 boolean retOk = checkReturnType(false, errList); 1188 return !superOk ? false : retOk; 1189 } 1190 1191 private boolean checkReturnType(boolean checkOnly, DefaultListModel errList) { 1192 1193 boolean retOk = true; 1194 1195 String retFQN = getDescriptor().getTypeFQName(); 1196 JavaDocTag[] retTags = getJavaDoc().getTags(TAG_RETURN); 1197 1198 boolean isVoid = "void".equals(retFQN); 1200 if (isVoid && retTags.length > 0) { 1201 if ( checkOnly ) { 1202 return false; 1203 } 1204 log(errList, ResourceUtils.getBundledString( "ERR_ReturnForVoid" ) ); retOk = false; 1206 } else if (!isVoid && retTags.length <= 0) { 1207 if ( checkOnly ) { 1208 return false; 1209 } 1210 log(errList, ResourceUtils.getBundledString( "ERR_NoReturn" ) ); retOk = false; 1212 } else if (!isVoid && retTags.length > 1) { 1213 if ( checkOnly) { 1214 return false; 1215 } 1216 log(errList, ResourceUtils.getBundledString( "ERR_DuplicatedReturn" ) ); retOk = false; 1218 } 1219 1220 return retOk; 1221 } 1222 1223 public boolean isCorrectable() { 1224 1225 if ( super.isCorrectable() ) 1226 return true; 1227 1228 return !checkReturnType(true, null); 1229 } 1230 1231 public void autoCorrect() throws SourceException { 1232 JavaDoc jdTemp = JavaDocSupport.createMethodJavaDoc( getJavaDoc().getRawText() ); 1233 super.autoCorrect( jdTemp ); 1234 1235 if (!checkReturnType(true, null) ) { 1236 String retFQN = getDescriptor().getTypeFQName(); 1237 if (!"void".equals(retFQN)) { jdTemp.changeTags( 1239 new JavaDocTag[] { JavaDocSupport.createTag( TAG_RETURN, "" ) }, JavaDoc.ADD ); 1241 } else { 1242 JavaDocTag toRemove[] = jdTemp.getTags( TAG_RETURN ); 1243 1244 jdTemp.changeTags( toRemove, JavaDoc.REMOVE ); 1245 } 1246 } 1247 1248 getJavaDoc().setRawText( jdTemp.getRawText() ); 1249 setJavaDoc(getJavaDoc()); 1250 } 1251 1252 public Format getNameFormat () { 1253 return nameFormat; 1254 } 1255 } 1256 } 1257 1258 public interface AutoCommentChangeListener extends EventListener { 1259 1262 public void listChanged(); 1263 1267 public void elementUpdated(AutoCommenter.Element el); 1268 } 1269 1270 1273 public synchronized void addAutoCommentChangeListener(AutoCommentChangeListener listener) throws java.util.TooManyListenersException { 1274 if (autoCommentChangeListener != null) { 1275 throw new java.util.TooManyListenersException (); 1276 } 1277 autoCommentChangeListener = listener; 1278 } 1279 1280 1283 public synchronized void removeAutoCommentChangeListener(AutoCommentChangeListener listener) { 1284 autoCommentChangeListener = null; 1285 } 1286 1287 1289 private void fireAutocommentChangeEvent() { 1290 if (autoCommentChangeListener == null) return; 1291 autoCommentChangeListener.listChanged(); 1292 } 1293 1294 private void fireElementUpdatedEvent(AutoCommenter.Element el) { 1295 if (autoCommentChangeListener == null) return; 1296 autoCommentChangeListener.elementUpdated(el); 1297 } 1298} 1299 | Popular Tags |