View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.comments;
5   
6   import java.util.ArrayList;
7   import java.util.Collections;
8   import java.util.List;
9   import java.util.SortedMap;
10  import java.util.TreeMap;
11  
12  import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
13  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
14  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
15  import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
16  import net.sourceforge.pmd.lang.java.ast.Comment;
17  import net.sourceforge.pmd.lang.java.ast.FormalComment;
18  import net.sourceforge.pmd.lang.java.ast.MultiLineComment;
19  import net.sourceforge.pmd.lang.java.ast.SingleLineComment;
20  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
21  import net.sourceforge.pmd.util.StringUtil;
22  
23  /**
24   * 
25   * @author Brian Remedios
26   */
27  public abstract class AbstractCommentRule extends AbstractJavaRule {
28  
29   
30  	protected AbstractCommentRule() {
31  		
32  	}
33  
34  	protected List<Integer> tagsIndicesIn(String comments) {
35  		
36  		int atPos = comments.indexOf('@');
37  		if (atPos < 0) return Collections.EMPTY_LIST;
38  		
39  		List<Integer> ints = new ArrayList<Integer>();
40  		ints.add(atPos);
41  		
42  		atPos = comments.indexOf('@', atPos+1);
43  		while (atPos >= 0) {
44  			ints.add(atPos);
45  			atPos = comments.indexOf('@', atPos+1);
46  		}
47  		
48  		return ints;
49  	}
50  	
51  	protected String filteredCommentIn(Comment comment) {
52  		
53  		String trimmed = comment.getImage().trim();
54  		
55  		if (comment instanceof SingleLineComment) {
56  			return singleLineIn(trimmed);
57  		}
58  		if (comment instanceof MultiLineComment) {
59  			return multiLinesIn(trimmed);
60  		}
61  		if (comment instanceof FormalComment) {
62  			return formalLinesIn(trimmed);
63  		}
64  		
65  		return trimmed;	// should never reach here
66  	}
67  	
68  	private String singleLineIn(String comment) {
69  				
70  		if (comment.startsWith("//")) return comment.substring(2);
71  		
72  		return comment;
73  	}
74  	
75  	private static String asSingleString(List<String> lines) {
76  		
77  		StringBuilder sb = new StringBuilder();
78  		for (String line : lines) {
79  			if (StringUtil.isEmpty(line)) continue;
80  			sb.append(line).append('\n');
81  		}
82  		
83  		return sb.toString().trim();
84  	}
85  	
86  	private static String multiLinesIn(String comment) {
87  		
88  		String[] lines = comment.split("\n");
89  		List<String> filteredLines = new ArrayList<String>(lines.length);
90  		
91  		for (String rawLine : lines) {		
92  			String line = rawLine.trim();
93  			
94  			if (line.endsWith("*/")) {
95  				int end = line.length()-2;
96  				int start = line.startsWith("/*") ? 2 : 0;
97  				filteredLines.add(line.substring(start, end));
98  				continue;
99  			}
100 			
101 			if (line.length() > 0 && line.charAt(0) == '*') {
102 				filteredLines.add(line.substring(1));
103 				continue;
104 			}
105 		
106 			if (line.startsWith("/*")) {
107 				filteredLines.add(line.substring(2));
108 				continue;
109 			}
110 			
111 		}
112 		
113 		return asSingleString(filteredLines);
114 	}
115 	
116 	private String formalLinesIn(String comment) {
117 		
118 		String[] lines = comment.split("\n");
119 		List<String> filteredLines = new ArrayList<String>(lines.length);
120 		
121 		for (String line : lines) {		
122 			
123 			if (line.endsWith("*/")) {
124 				filteredLines.add(line.substring(0, line.length()-2));
125 				continue;
126 			}
127 			
128 			if (line.length() > 0 && line.charAt(0) == '*') {
129 				filteredLines.add(line.substring(1));
130 				continue;
131 			}
132 			if (line.startsWith("/**")) {
133 				filteredLines.add(line.substring(3));
134 				continue;
135 			}
136 			
137 		}
138 		
139 		return asSingleString(filteredLines);
140 	}
141 	
142     protected SortedMap<Integer, Object> orderedCommentsAndDeclarations(ASTCompilationUnit cUnit) {
143   
144 		SortedMap<Integer, Object> itemsByLineNumber = new TreeMap<Integer, Object>();
145 		
146 		List<ASTPackageDeclaration> packageDecl = cUnit.findDescendantsOfType(ASTPackageDeclaration.class);
147 		for (ASTPackageDeclaration decl : packageDecl) {
148 			itemsByLineNumber.put(decl.getBeginLine(), decl);
149 		}
150 		
151 		for (Comment comment : cUnit.getComments()) {
152 			itemsByLineNumber.put(comment.getBeginLine(), comment);
153 		}
154 
155 		List<ASTFieldDeclaration> fields = cUnit.findDescendantsOfType(ASTFieldDeclaration.class);
156 		for (ASTFieldDeclaration fieldDecl : fields) {
157 			itemsByLineNumber.put(fieldDecl.getBeginLine(), fieldDecl);
158 		}
159 		
160 		List<ASTMethodDeclaration> methods = cUnit.findDescendantsOfType(ASTMethodDeclaration.class);
161 		for (ASTMethodDeclaration methodDecl : methods) {
162 			itemsByLineNumber.put(methodDecl.getBeginLine(), methodDecl);
163 		}
164 		
165 		System.out.println("Items:" + itemsByLineNumber);
166 
167         return itemsByLineNumber;
168     }
169 }