KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > javadoc > ext > AutoCommenter


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

19
20 package org.netbeans.modules.tasklist.javadoc.ext;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.text.MessageFormat JavaDoc;
25 import javax.swing.DefaultListModel JavaDoc;
26 import java.lang.reflect.Modifier JavaDoc;
27 import java.lang.ref.WeakReference JavaDoc;
28
29 import org.openide.src.*;
30 import org.openide.cookies.SourceCookie;
31 import org.openide.cookies.OpenCookie;
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 java.beans.PropertyChangeListener JavaDoc;
37 import java.beans.PropertyChangeEvent JavaDoc;
38 import java.util.EventListener JavaDoc;
39 import java.util.List JavaDoc;
40
41 /** Contains static methods for generating default JavaDoc comments for
42  * java data object hierarchy elements.
43  *
44  * Checks for Comment errors in JavaNodes
45  *
46  * @author Petr Hrebejk
47  */

48 public final class AutoCommenter extends Object JavaDoc implements JavaTagNames {
49
50     public static final int JDC_OK = 1;
51     public static final int JDC_MISSING = 2;
52     public static final int JDC_ERROR = 4;
53
54     /** List of <code>DataObject</code>s. */
55     private final ArrayList JavaDoc dataObjects;
56     ArrayList JavaDoc elements;
57     Node[] nodes;
58     /** listens to all <code>dataobjects</code> elements*/
59     private final WPCL dataObjectListener = new WPCL();
60
61     /** Utility field holding the PropertyChangeListener. */
62     private AutoCommentChangeListener autoCommentChangeListener = null;
63
64     /** Creates an empty AutoCommenter */
65     AutoCommenter() {
66         this( new Node[0] );
67     }
68
69     /** Creates Auto commenter for nodes */
70     AutoCommenter ( Node[] nodes ) {
71         dataObjects = new ArrayList JavaDoc();
72         this.nodes = nodes;
73     }
74
75     private void updateDataObjects() {
76         synchronized(this) {
77             dataObjects.clear();
78         }
79
80         for (int i = 0; i < nodes.length; i++) {
81             DataFolder df = (DataFolder) nodes[i].getCookie(DataFolder.class);
82             SourceCookie sc = null;
83             if(df != null){
84                 DataObject[] children = df.getChildren();
85                 for (int n = 0; n < children.length; n++){
86                     final DataObject child = children[n];
87                     sc = (SourceCookie) child.getCookie(SourceCookie.Editor.class);
88                     if(sc != null && child.getPrimaryFile().canWrite()){
89                         if(!dataObjects.contains(child)){
90                             child.addPropertyChangeListener(dataObjectListener);
91                             synchronized (dataObjects){
92                                 dataObjects.add(child);
93                             }
94                         }
95                     }
96                 }
97                 continue;
98             }
99             else {
100                 sc = (SourceCookie) nodes[i].getCookie(SourceCookie.Editor.class);
101             }
102             final DataObject doj = (DataObject) nodes[i].getCookie(DataObject.class);
103             if ( sc == null || !doj.getPrimaryFile().canWrite() )
104                 continue;
105
106             if( !dataObjects.contains(doj) ) {
107                 doj.addPropertyChangeListener(dataObjectListener);
108                 synchronized (dataObjects){
109                     dataObjects.add(doj);
110                 }
111             }
112         }
113     }
114
115     private class WPCL extends WeakReference JavaDoc implements PropertyChangeListener JavaDoc, Runnable JavaDoc {
116
117         public WPCL() {
118             super(AutoCommenter.this, Utilities.activeReferenceQueue());
119         }
120         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
121             DataObject doj = (DataObject) evt.getSource();
122             if(evt.getPropertyName().equals(DataObject.PROP_VALID)){
123                 synchronized (dataObjects){
124                     dataObjects.remove(doj);
125                 }
126                 doj.removePropertyChangeListener(this);
127                 fireAutocommentChangeEvent();
128             }
129         }
130
131         public void run() {
132             for (Iterator JavaDoc it = dataObjects.iterator(); it.hasNext();) {
133                 DataObject d = (DataObject) it.next();
134                 d.removePropertyChangeListener(this);
135             }
136         }
137     }
138
139     void refreshFromSource() {
140         updateDataObjects();
141         List JavaDoc dobjs = new ArrayList JavaDoc(this.dataObjects);
142         synchronized (this) {
143
144         }
145         elements = new ArrayList JavaDoc(dobjs.size());
146         for (Iterator JavaDoc it = dobjs.iterator(); it.hasNext();) {
147             DataObject d = (DataObject) it.next();
148             SourceCookie sc = (SourceCookie) d.getCookie(SourceCookie.class);
149             if (sc != null) {
150                 addCommentable(sc);
151             }
152         }
153     }
154
155     void addCommentable(SourceCookie sc){
156         SourceElement se = sc.getSource();
157         if ( se != null ) {
158             ClassElement[] ces = se.getAllClasses();
159             for( int j = 0; j < ces.length; j++ ){
160                 addElements( ces[j] );
161             }
162         }
163     }
164
165     void prepareListModel( DefaultListModel JavaDoc listModel, int mask, boolean pckg, int err_mask ) {
166
167         Iterator JavaDoc it = elements.iterator();
168
169         while( it.hasNext() ) {
170             Element el = (Element)it.next();
171
172             if ( acceptElement( el, mask, pckg, err_mask ) ) {
173                 listModel.addElement( el );
174             }
175         }
176     }
177
178     static int getEffectiveAccess(MemberElement el) {
179         int access = el.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
180         if (access == Modifier.PRIVATE)
181             return access;
182         ClassElement decl = el.getDeclaringClass();
183         if (decl == null)
184             // it is a top-level class
185
return access;
186         if (!decl.isClassOrInterface())
187             // interface members must be public
188
access = Modifier.PUBLIC;
189
190         int parentAccess = getEffectiveAccess(decl);
191         switch (parentAccess) {
192             case Modifier.PRIVATE:
193             case 0:
194                 // private members were handled above, everything else is
195
// constrained by parent's privacy
196
return parentAccess;
197             case Modifier.PROTECTED:
198                 // member can be restricted to only the package
199
return access == 0 ? 0 : parentAccess;
200             case Modifier.PUBLIC:
201             default:
202                 return access;
203         }
204     }
205
206     static boolean acceptElement( Element el, int mask, boolean pckg, int err_mask ) {
207
208         // Test whether the element is accepted by error mask
209

210         if ( ( el.getErrorNumber() & err_mask ) == 0 )
211             return false;
212
213         // Test whether the element is accepted by access mask
214
int access = getEffectiveAccess((MemberElement)el.getSrcElement());
215         if (access == 0)
216             return pckg;
217         else
218             return (access & mask) > 0;
219     }
220
221     DefaultListModel JavaDoc prepareListModel( int mask, boolean pckg, int err_mask ) {
222         DefaultListModel JavaDoc dm = new DefaultListModel JavaDoc();
223         prepareListModel( dm, mask, pckg, err_mask );
224         return dm;
225     }
226
227     /*private*/ void addElements( ClassElement classElement ) {
228         elements.add( new Element.Class( classElement ) );
229
230         FieldElement[] fe = classElement.getFields();
231         for( int i = 0; i < fe.length; i++ ) {
232             elements.add( new Element.Field ( fe[i] ) );
233         }
234
235         ConstructorElement[] ce = classElement.getConstructors();
236         for( int i = 0; i < ce.length; i++ ) {
237             elements.add( new Element.Constructor ( ce[i] ) );
238         }
239
240         MethodElement[] me = classElement.getMethods();
241         for( int i = 0; i < me.length; i++ ) {
242             elements.add( new Element.Method ( me[i] ) );
243         }
244     }
245
246     /** innerclass holds the element and the informations about comment errors */
247
248     static abstract class Element {
249
250         protected DefaultListModel JavaDoc errorList;
251
252         MemberElement srcElement = null;
253         int srcError = JDC_OK;
254
255         Element( MemberElement srcElement ) {
256             this.srcElement = srcElement;
257             // XXX it does nothing; remains just for debug pupose?; moreover it's wrong because PCL is GCed ASAP
258
// PropertyChangeListener pp = new PropertyChangeListener(){
259
// public void propertyChange(PropertyChangeEvent evt){
260
// //System.err.println(evt.getPropertyName());
261
// if( evt.getSource() instanceof org.netbeans.modules.java.JavaDataObject ) //ignore
262
// return;
263
// //System.err.println("change 2");
264
// }
265
// };
266
// //System.err.println("adding listeners");
267
// srcElement.addPropertyChangeListener(WeakListener.propertyChange(pp, srcElement));
268
checkError();
269         }
270
271         String JavaDoc getName() {
272             return getNameFormat().format( srcElement );
273         }
274
275         MemberElement getSrcElement() {
276             return srcElement;
277         }
278
279         int getModifiers() {
280             return srcElement.getModifiers();
281         }
282
283         int getErrorNumber() {
284             return srcError;
285         }
286
287         void viewSource() {
288             OpenCookie oc = ((OpenCookie)srcElement.getCookie( OpenCookie.class ));
289             oc.open();
290         }
291
292         DefaultListModel JavaDoc getErrorList() {
293             return errorList;
294         }
295
296         /** Returns the source for this particular element. Used for locking purposes.
297         */

298         SourceElement findSource() {
299             ClassElement decl = srcElement.getDeclaringClass();
300             if (decl == null && (srcElement instanceof ClassElement)) {
301                 decl = (ClassElement)srcElement;
302             }
303             if (decl == null) return null;
304             return decl.getSource();
305         }
306
307         abstract String JavaDoc[] getNotPermittedTags();
308
309         abstract boolean elementTagsOk();
310
311         abstract void autoCorrect() throws SourceException;
312
313         abstract JavaDoc getJavaDoc();
314
315         abstract ElementFormat getNameFormat();
316
317         abstract String JavaDoc typeToString();
318
319         static boolean isPermittedTag( JavaDocTag tag, String JavaDoc[] notPermittedTags ) {
320             String JavaDoc tagName = tag.name();
321
322             for ( int i = 0; i < notPermittedTags.length; i++ ) {
323                 if ( tagName.equals( notPermittedTags[i] ) )
324                     return false;
325             }
326
327             return true;
328         }
329
330         void modifyJavaDoc(Runnable JavaDoc mutator) throws SourceException {
331             SourceElement src = findSource();
332             if (src == null) {
333                 mutator.run();
334             } else {
335                 src.runAtomicAsUser(mutator);
336             }
337         }
338
339         private static boolean isEmptyString( String JavaDoc string ) {
340             return string == null || string.trim().length() <= 0;
341         }
342
343         /** Checks syntax of the tags
344          */

345
346         boolean isOkTag( JavaDocTag tag ) {
347             if ( isEmptyString( tag.text() ) ) {
348                 errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_EmptyTag" ), //NOI18N
349
new Object JavaDoc[] { tag.name() } ) );
350                 return false;
351             }
352
353             if ( tag instanceof JavaDocTag.See ) {
354                 int len;
355                 String JavaDoc text;
356                 JavaDocTag.See seetag = (JavaDocTag.See) tag;
357
358                 if ((seetag.referencedClassName() != null) || (seetag.referencedMemberName() != null))
359                     return true;
360                 text=tag.text();
361                 len = text.length();
362                 if (len >= 2) {
363                     char first=text.charAt(0);
364                     char last=text.charAt(len-1);
365
366                     if (first=='"' && last==first)
367                         return true;
368                     if (first=='<' && last=='>')
369                         return true;
370                 }
371                 errorList.addElement(MessageFormat.format( ResourceUtils.getBundledString( "ERR_InvalidTag" ), //NOI18N
372
new Object JavaDoc[] { seetag } )); //NOI18N
373
return false;
374             }
375             else if ( tag instanceof JavaDocTag.Param ) {
376                 if ( isEmptyString( ((JavaDocTag.Param)tag).parameterName() ) ) {
377                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_ParamNoName" ), //NOI18N
378
new Object JavaDoc[] { tag.name() } ) );
379                     return false;
380                 }
381                 if ( isEmptyString( ((JavaDocTag.Param)tag).parameterComment() ) ) {
382                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_ParamNoDescr" ), //NOI18N
383
new Object JavaDoc[] { tag.name(), ((JavaDocTag.Param)tag).parameterName() } ) );
384                     return false;
385                 }
386             }
387             else if ( tag instanceof JavaDocTag.Throws ) {
388                 if ( isEmptyString( ((JavaDocTag.Throws)tag).exceptionName() ) ) {
389                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_ThrowsNoName" ), //NOI18N
390
new Object JavaDoc[] { tag.name() } ) );
391                     return false;
392                 }
393                 if ( isEmptyString( ((JavaDocTag.Throws)tag).exceptionComment() ) ) {
394                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_ThrowsNoDescr" ), //NOI18N
395
new Object JavaDoc[] { tag.name(), ((JavaDocTag.Throws)tag).exceptionName() } ) );
396                     return false;
397                 }
398             }
399             else if ( tag instanceof JavaDocTag.SerialField ) {
400                 if ( isEmptyString( ((JavaDocTag.SerialField)tag).fieldName() ) ) {
401                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoName" ), //NOI18N
402
new Object JavaDoc[] { tag.name() } ) );
403                     return false;
404                 }
405                 if ( isEmptyString( ((JavaDocTag.SerialField)tag).fieldType() ) ) {
406                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoType" ), //NOI18N
407
new Object JavaDoc[] { tag.name(), ((JavaDocTag.SerialField)tag).fieldName() } ) );
408                     return false;
409                 }
410
411                 if ( isEmptyString( ((JavaDocTag.SerialField)tag).description() ) ) {
412                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_SerialFieldNoDescr" ), //NOI18N
413
new Object JavaDoc[] { tag.name(), ((JavaDocTag.SerialField)tag).fieldName() } ) );
414                     return false;
415                 }
416             }
417             return true;
418         }
419
420         boolean isMultipleTags(String JavaDoc tag) {
421             // Check for multiple tags
422
boolean error = false;
423             JavaDocTag[] tags = getJavaDoc().getTags(tag);
424             if ( tags.length > 1) {
425                 errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedTag" ), //NOI18N
426
new Object JavaDoc[] { tags[0].name() } ) );
427                 error = true;
428             }
429             return error;
430         }
431
432         void checkError() {
433
434             errorList = new DefaultListModel JavaDoc();
435
436             JavaDoc jdoc = getJavaDoc();
437
438             if ( jdoc.isEmpty() ) {
439                 srcError = JDC_MISSING;
440                 errorList.addElement( ResourceUtils.getBundledString( "ERR_JavadocMissing" ) ); //NOI18N
441
return;
442             }
443
444             JavaDocTag[] tags = jdoc.getTags();
445             boolean error = false;
446
447             if ( jdoc.getText() == null || jdoc.getText().trim().length() <= 0 ) {
448                 errorList.addElement( ResourceUtils.getBundledString( "ERR_EmptyText" ) ); //NOI18N
449
error = true;
450             }
451
452             for ( int i = 0; i < tags.length; i ++ ) {
453                 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) {
454                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_BadTag" ), //NOI18N
455
new Object JavaDoc[] { tags[i].name(), typeToString() } ) );
456                     error = true;
457                     continue;
458                 }
459
460                 if ( !isOkTag( tags[i] ) ) {
461                     error = true;
462                     continue;
463                 }
464             }
465
466             if (isMultipleTags(TAG_SINCE)) {
467                 error = true;
468             }
469
470             if (isMultipleTags(TAG_DEPRECATED)) {
471                 error = true;
472             }
473
474             if ( !elementTagsOk( ) ) {
475                 error = true;
476             }
477
478             if ( !error ) {
479                 errorList.addElement( ResourceUtils.getBundledString( "ERR_JavadocOK" ) ); //NOI18N
480
}
481
482             srcError = error ? JDC_ERROR : JDC_OK;
483
484         }
485
486         boolean isCorrectable() {
487
488             JavaDocTag[] tags = getJavaDoc().getTags();
489
490             for ( int i = 0; i < tags.length; i ++ ) {
491                 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) {
492                     return true;
493                 }
494             }
495
496             return false;
497         }
498
499         void autoCorrect( JavaDoc jdoc ) throws SourceException {
500             JavaDocTag[] tags = jdoc.getTags();
501             ArrayList JavaDoc correctedTags = new ArrayList JavaDoc( tags.length );
502             String JavaDoc correctedText;
503
504             correctedText = jdoc.getText();
505
506             if ( correctedText == null ) {
507                 correctedText = ""; // NOI18N
508
}
509
510             for ( int i = 0; i < tags.length; i ++ ) {
511                 if ( !Element.isPermittedTag( tags[i], getNotPermittedTags() ) ) {
512                     continue;
513                 }
514                 correctedTags.add( tags[i] );
515             }
516
517             jdoc.changeTags( (JavaDocTag[])correctedTags.toArray( new JavaDocTag[ correctedTags.size() ] ), JavaDoc.SET );
518         }
519
520
521         static class Class extends Element {
522
523             private static final String JavaDoc[] NOT_PERMITTED_TAGS = {
524                 TAG_EXCEPTION,
525                 TAG_PARAM,
526                 TAG_RETURN,
527                 TAG_SERIAL,
528                 TAG_SERIALDATA,
529                 TAG_SERIALFIELD,
530                 TAG_THROWS,
531             };
532
533             private static final ElementFormat nameFormat = new ElementFormat( "{m} {C}" ); // NOI18N
534

535             Class( ClassElement element ) {
536                 super( element );
537             }
538
539             String JavaDoc[] getNotPermittedTags() {
540                 return NOT_PERMITTED_TAGS;
541             }
542
543             boolean elementTagsOk() {
544                 boolean error = false;
545                 if (this.isMultipleTags(TAG_VERSION)) {
546                     error = true;
547                 }
548                 return !error;
549             }
550
551             void autoCorrect() throws SourceException {
552                 super.autoCorrect( getJavaDoc() );
553             }
554
555             boolean isCorrectable() {
556                 return super.isCorrectable();
557             }
558
559             String JavaDoc typeToString() {
560                 return ((ClassElement)srcElement).isInterface() ? "interface" : "class"; // NOI18N
561
}
562
563             JavaDoc getJavaDoc() {
564                 return ((ClassElement)srcElement).getJavaDoc();
565             }
566
567             ElementFormat getNameFormat () {
568                 return nameFormat;
569             }
570
571         }
572
573         static class Field extends Element {
574
575             private static final String JavaDoc[] NOT_PERMITTED_TAGS = {
576                 TAG_AUTHOR,
577                 TAG_EXCEPTION,
578                 TAG_PARAM,
579                 TAG_RETURN,
580                 TAG_SERIALDATA,
581                 TAG_THROWS,
582                 TAG_VERSION
583             };
584
585             private static final ElementFormat nameFormat = new ElementFormat( "{m} {t} {n}" ); // NOI18N
586

587             Field( FieldElement element ) {
588                 super( element );
589             }
590
591             JavaDoc getJavaDoc() {
592                 return ((FieldElement)srcElement).getJavaDoc();
593             }
594
595             String JavaDoc[] getNotPermittedTags() {
596                 return NOT_PERMITTED_TAGS;
597             }
598
599             String JavaDoc typeToString() {
600                 return "field"; // NOI18N
601
}
602
603             boolean elementTagsOk() {
604                 boolean error = false;
605                 if (this.isMultipleTags(TAG_SERIAL)) {
606                     error = true;
607                 }
608
609                 return !error;
610             }
611
612             void autoCorrect() throws SourceException {
613                 super.autoCorrect( getJavaDoc() );
614             }
615
616             boolean isCorrectable() {
617                 return super.isCorrectable();
618             }
619
620             ElementFormat getNameFormat () {
621                 return nameFormat;
622             }
623         }
624
625         static class Constructor extends Element {
626
627             private static final String JavaDoc[] NOT_PERMITTED_TAGS = {
628                 TAG_AUTHOR,
629                 TAG_SERIAL,
630                 TAG_SERIALFIELD,
631                 TAG_VERSION,
632                 TAG_RETURN
633             };
634
635             private static final ElementFormat nameFormat = new ElementFormat( "{m} {n} ( {p} )" ); // NOI18N
636

637             Constructor( ConstructorElement element ) {
638                 super( element );
639             }
640
641             JavaDoc getJavaDoc() {
642                 return ((ConstructorElement)srcElement).getJavaDoc();
643             }
644
645             String JavaDoc[] getNotPermittedTags() {
646                 return NOT_PERMITTED_TAGS;
647             }
648
649             String JavaDoc typeToString() {
650                 return "constructor"; // NOI18N
651
}
652
653             boolean elementTagsOk() {
654                 return elementTagsOk( null, false );
655             }
656
657
658             boolean elementTagsOk( ArrayList JavaDoc correctedTags, boolean checkOnly ) {
659
660                 boolean error = false;
661
662                 // Check param tags
663

664                 JavaDocTag.Param[] ptags = ((ConstructorElement)srcElement).getJavaDoc().getParamTags();
665                 boolean[] ptags_found = new boolean[ ptags.length ];
666                 MethodParameter[] params = ((ConstructorElement)srcElement).getParameters();
667
668                 // Check if all parameters for the method are in the javadoc
669
// and if there are any parameter tag duplicates.
670
for (int j = 0 ; j < params.length ; j++) {
671                     boolean tagFound = false;
672                     boolean duplicateTagAlreadyFound = false;
673                     for (int i = 0 ; i < ptags.length ; i++) {
674                         if ( ptags[i].parameterName() != null && ptags[i].parameterName().equals( params[j].getName() ) ) {
675                             ptags_found[i] = true;
676                             if (!tagFound) {
677                                 tagFound = true;
678                             } else if (! duplicateTagAlreadyFound) {
679                                 if ( checkOnly ) {
680                                     return false;
681                                 }
682                                 else if ( correctedTags == null ) {
683                                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedParamTag" ), //NOI18N
684
new Object JavaDoc[] { params[j].getName() } ) );
685                                 }
686                                 error = true;
687                                 duplicateTagAlreadyFound = true;
688                             }
689                         }
690                     }
691
692                     if (! tagFound ) {
693                         if ( checkOnly ) {
694                             return false;
695                         } else if ( correctedTags == null ) {
696                             error = true;
697                             errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoTagForParam" ), //NOI18N
698
new Object JavaDoc[] { params[j].getName() } ) );
699                         }
700                         else {
701                             correctedTags.add( JavaDocSupport.createParamTag( TAG_PARAM, params[j].getName() ) );
702                         }
703                     }
704                 }
705
706                 for( int i = 0; i < ptags.length; i++ ) {
707                     if ( !ptags_found[i] ) {
708                         if ( checkOnly ) {
709                             return false;
710                         }
711                         else if ( correctedTags == null ) {
712                             errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoSuchParam" ), //NOI18N
713
new Object JavaDoc[] { ptags[i].name(), ptags[i].parameterName() } ) );
714                         }
715                         error = true;
716                     }
717                     else if ( correctedTags != null ) {
718                         correctedTags.add( ptags[i] );
719                     }
720
721
722                 }
723                 // Check throws tags
724

725
726                 JavaDocTag.Throws[] ttags = ((ConstructorElement)srcElement).getJavaDoc().getThrowsTags();
727                 boolean[] ttags_found = new boolean[ ttags.length ];
728                 Identifier[] excs = ((ConstructorElement)srcElement).getExceptions();
729
730                 // Check if all exceptions for the method are in the javadoc
731
// and if there are any exception tag duplicates.
732
for (int j = 0 ; j < excs.length ; j++) {
733                     boolean tagFound = false;
734                     boolean duplicateTagAlreadyFound = false;
735                     for (int i = 0 ; i < ttags.length ; i++) {
736                         Identifier tagExId = Identifier.create(ttags[i].exceptionName() );
737                         if ( tagExId != null && ( tagExId.compareTo( excs[j], false ) ||
738                                   tagExId.getName().equals(excs[j].getName() ) ) ) {
739                             ttags_found[i] = true;
740                             if (!tagFound) {
741                                 tagFound = true;
742                             } else if (! duplicateTagAlreadyFound){
743                                 if ( checkOnly ) {
744                                     return false;
745                                 }
746                                 else if ( correctedTags == null ) {
747                                     errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_DuplicatedExceptionTag" ), //NOI18N
748
new Object JavaDoc[] { excs[j].getName() } ) );
749                                 }
750                                 error = true;
751                                 duplicateTagAlreadyFound = true;
752                             }
753                         }
754                     }
755
756                     if (! tagFound ) {
757                         if ( checkOnly ) {
758                             return false;
759                         } else if ( correctedTags == null ) {
760                             error = true;
761                             errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoTagForException" ), //NOI18N
762
new Object JavaDoc[] { excs[j].getName() } ) );
763                         }
764                         else {
765                             correctedTags.add( JavaDocSupport.createThrowsTag( TAG_THROWS, excs[j].getName() ) );
766                         }
767                     }
768                 }
769
770                 for( int i = 0; i < ttags.length; i++ ) {
771                     if ( !ttags_found[i] ) {
772                         if ( checkOnly ) {
773                             return false;
774                         }
775                         else if ( correctedTags == null ) {
776                             errorList.addElement( MessageFormat.format( ResourceUtils.getBundledString( "ERR_NoSuchException" ), //NOI18N
777
new Object JavaDoc[] { ttags[i].name(), ttags[i].exceptionName() } ) );
778                         }
779                         error = true;
780                     }
781                     else if ( correctedTags != null ) {
782                         correctedTags.add( ttags[i] );
783                     }
784
785
786                 }
787
788                 return !error;
789             }
790
791             boolean isCorrectable () {
792                 if ( super.isCorrectable() )
793                     return true;
794
795                 return !elementTagsOk( null, true );
796             }
797
798             void autoCorrect() throws SourceException {
799                 autoCorrect( getJavaDoc() );
800             }
801
802             void autoCorrect( JavaDoc jDoc ) throws SourceException {
803                 JavaDoc.Method jdTemp = JavaDocSupport.createMethodJavaDoc(getJavaDoc().getRawText());
804
805                 // create comment without throws and params
806

807                 JavaDocTag tags[] = jdTemp.getTags();
808                 ArrayList JavaDoc stdTags = new ArrayList JavaDoc( tags.length );
809
810                 for( int i = 0; i < tags.length; i++ ) {
811                     if ( !( tags[i] instanceof JavaDocTag.Param ) &&
812                             !( tags[i] instanceof JavaDocTag.Throws ) ) {
813                         stdTags.add( tags[i] );
814                     }
815                 }
816
817                 jdTemp.changeTags( (JavaDocTag[])stdTags.toArray( new JavaDocTag[ stdTags.size() ] ), JavaDoc.SET );
818
819                 super.autoCorrect( jdTemp );
820
821                 ArrayList JavaDoc correctedTags = new ArrayList JavaDoc();
822                 elementTagsOk( correctedTags, false );
823
824                 // Build all tags collection
825

826                 ArrayList JavaDoc allTags = new ArrayList JavaDoc( correctedTags.size() + tags.length );
827                 tags = jdTemp.getTags();
828                 for( int i = 0; i < tags.length; i++ ) {
829                     allTags.add( tags[i] );
830                 }
831                 allTags.addAll( correctedTags );
832
833                 jDoc.changeTags( (JavaDocTag[])allTags.toArray( new JavaDocTag[ allTags.size() ] ), JavaDoc.SET );
834             }
835
836             ElementFormat getNameFormat () {
837                 return nameFormat;
838             }
839
840         }
841
842         static class Method extends Constructor {
843
844             private static final ElementFormat nameFormat = new ElementFormat( "{m} {r} {n} ( {p} )" ); // NOI18N
845

846             private static final String JavaDoc[] NOT_PERMITTED_TAGS = {
847                 TAG_AUTHOR,
848                 TAG_SERIAL,
849                 TAG_SERIALFIELD,
850                 TAG_VERSION
851             };
852
853             Method( MethodElement element ) {
854                 super( element );
855             }
856
857             JavaDoc getJavaDoc() {
858                 return ((MethodElement)srcElement).getJavaDoc();
859             }
860
861             String JavaDoc typeToString() {
862                 return "method"; // NOI18N
863
}
864
865             String JavaDoc[] getNotPermittedTags() {
866                 return NOT_PERMITTED_TAGS;
867             }
868
869             boolean elementTagsOk() {
870                 boolean superOk = super.elementTagsOk();
871                 boolean retOk = checkReturnType( false );
872                 return !superOk ? false : retOk;
873             }
874
875             private boolean checkReturnType( boolean checkOnly ) {
876
877                 boolean retOk = true;
878
879                 Type ret = ((MethodElement)srcElement).getReturn();
880                 JavaDocTag[] retTags = ((MethodElement)srcElement).getJavaDoc().getTags( TAG_RETURN );
881
882                 if ( ret == Type.VOID && retTags.length > 0 ) {
883                     if ( checkOnly ) {
884                         return false;
885                     }
886                     errorList.addElement( ResourceUtils.getBundledString( "ERR_ReturnForVoid" ) ); //NOI18N
887
retOk = false;
888                 }
889                 else if ( ret != Type.VOID && retTags.length <= 0 ) {
890                     if ( checkOnly ) {
891                         return false;
892                     }
893                     errorList.addElement( ResourceUtils.getBundledString( "ERR_NoReturn" ) ); //NOI18N
894
retOk = false;
895                 } else if ( ret != Type.VOID && retTags.length > 1 ) {
896                     if ( checkOnly) {
897                         return false;
898                     }
899                     errorList.addElement( ResourceUtils.getBundledString( "ERR_DuplicatedReturn" ) ); //NOI18N
900
retOk = false;
901                 }
902
903                 return retOk;
904             }
905
906
907             boolean isCorrectable() {
908
909                 if ( super.isCorrectable() )
910                     return true;
911
912                 return !checkReturnType( true );
913             }
914
915             void autoCorrect() throws SourceException {
916                 JavaDoc jdTemp = JavaDocSupport.createMethodJavaDoc( getJavaDoc().getRawText() );
917                 super.autoCorrect( jdTemp );
918
919                 if (!checkReturnType( true ) ) {
920                     if ( ((MethodElement)srcElement).getReturn() != Type.VOID ) {
921                         jdTemp.changeTags(
922                             new JavaDocTag[] { JavaDocSupport.createTag( TAG_RETURN, "" ) }, // NOI18N
923
JavaDoc.ADD );
924                     }
925                     else {
926                         JavaDocTag toRemove[] = jdTemp.getTags( TAG_RETURN );
927
928                         jdTemp.changeTags( toRemove, JavaDoc.REMOVE );
929                     }
930                 }
931
932                 getJavaDoc().setRawText( jdTemp.getRawText() );
933
934             }
935
936             ElementFormat getNameFormat () {
937                 return nameFormat;
938             }
939         }
940     }
941
942     public interface AutoCommentChangeListener extends EventListener JavaDoc {
943         public void listChanged();
944     }
945
946     /** Registers PropertyChangeListener to receive events.
947      * @param listener The listener to register.
948      */

949     public synchronized void addAutoCommentChangeListener(AutoCommentChangeListener listener) throws java.util.TooManyListenersException JavaDoc {
950         if (autoCommentChangeListener != null) {
951             throw new java.util.TooManyListenersException JavaDoc();
952         }
953         autoCommentChangeListener = listener;
954     }
955
956     /** Removes PropertyChangeListener from the list of listeners.
957      * @param listener The listener to remove.
958      */

959     public synchronized void removeAutoCommentChangeListener(AutoCommentChangeListener listener) {
960         autoCommentChangeListener = null;
961     }
962
963     /** Notifies the registered listener about the event.
964      */

965     private void fireAutocommentChangeEvent() {
966         if (autoCommentChangeListener == null) return;
967         autoCommentChangeListener.listChanged();
968     }
969 }
970
Popular Tags