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.ast;
5   
6   import java.util.ArrayList;
7   import java.util.Collection;
8   import java.util.Collections;
9   import java.util.HashMap;
10  import java.util.List;
11  import java.util.Map;
12  import java.util.regex.Matcher;
13  import java.util.regex.Pattern;
14  
15  import net.sourceforge.pmd.util.StringUtil;
16  
17  public final class CommentUtil {
18  
19      private CommentUtil() {
20      }
21  
22      private static final String CR = "\n";
23  
24      public static String wordAfter(String text, int position) {
25  
26          if (position >= text.length()) {
27              return null;
28          }
29          int newposition = position + 1;
30          int end = newposition;
31          char ch = text.charAt(end);
32  
33          while (Character.isLetterOrDigit(ch) && end < text.length()) {
34              ch = text.charAt(++end);
35          }
36  
37          return text.substring(newposition, end);
38      }
39  
40      public static String javadocContentAfter(String text, int position) {
41  
42          int endPos = text.indexOf('\n', position);
43          if (endPos < 0) {
44              return null;
45          }
46  
47          if (StringUtil.isNotEmpty(text.substring(position, endPos))) {
48              return text.substring(position, endPos).trim();
49          }
50  
51          if (text.indexOf('@', endPos) >= 0) {
52              return null; // nope, this is another entry
53          }
54  
55          // try next line
56          int nextEndPos = text.indexOf('\n', endPos + 1);
57  
58          if (StringUtil.isNotEmpty(text.substring(endPos, nextEndPos))) {
59              return text.substring(endPos, nextEndPos).trim();
60          }
61  
62          return null;
63      }
64  
65      private static final Pattern JAVADOC_TAG = Pattern.compile("@[A-Za-z0-9]+");
66      private static final Map<String, String> JAVADOC_CACHE = new HashMap<>();
67  
68      public static Map<String, Integer> javadocTagsIn(String comment) {
69          Matcher m = JAVADOC_TAG.matcher(comment);
70          Map<String, Integer> tags = null;
71          while (m.find()) {
72              if (tags == null) {
73                  tags = new HashMap<>();
74              }
75              String match = comment.substring(m.start() + 1, m.end());
76              String tag = JAVADOC_CACHE.get(match);
77              if (tag == null) {
78                  JAVADOC_CACHE.put(match, match);
79              }
80              tags.put(tag, m.start());
81          }
82          if (tags == null) {
83              return Collections.emptyMap();
84          }
85          return tags;
86      }
87  
88      public static List<String> multiLinesIn(String comment) {
89  
90          String[] lines = comment.split(CR);
91          List<String> filteredLines = new ArrayList<>(lines.length);
92  
93          for (String rawLine : lines) {
94              String line = rawLine.trim();
95  
96              if (line.startsWith("//")) {
97                  filteredLines.add(line.substring(2));
98                  continue;
99              }
100 
101             if (line.endsWith("*/")) {
102                 int end = line.length() - 2;
103                 int start = line.startsWith("/**") ? 3 : line.startsWith("/*") ? 2 : 0;
104                 filteredLines.add(line.substring(start, end));
105                 continue;
106             }
107 
108             if (line.charAt(0) == '*') {
109                 filteredLines.add(line.substring(1));
110                 continue;
111             }
112 
113             if (line.startsWith("/**")) {
114                 filteredLines.add(line.substring(3));
115                 continue;
116             }
117 
118             if (line.startsWith("/*")) {
119                 filteredLines.add(line.substring(2));
120                 continue;
121             }
122 
123             filteredLines.add(line);
124         }
125 
126         return filteredLines;
127     }
128 
129     /**
130      * Similar to the String.trim() function, this one removes the leading and
131      * trailing empty/blank lines from the line list.
132      *
133      * @param lines
134      */
135     public static List<String> trim(List<String> lines) {
136 
137         int firstNonEmpty = 0;
138         for (; firstNonEmpty < lines.size(); firstNonEmpty++) {
139             if (StringUtil.isNotEmpty(lines.get(firstNonEmpty))) {
140                 break;
141             }
142         }
143 
144         // all of them empty?
145         if (firstNonEmpty == lines.size()) {
146             return Collections.emptyList();
147         }
148 
149         int lastNonEmpty = lines.size() - 1;
150         for (; lastNonEmpty > 0; lastNonEmpty--) {
151             if (StringUtil.isNotEmpty(lines.get(lastNonEmpty))) {
152                 break;
153             }
154         }
155 
156         List<String> filtered = new ArrayList<>();
157         for (int i = firstNonEmpty; i < lastNonEmpty; i++) {
158             filtered.add(lines.get(i));
159         }
160 
161         return filtered;
162     }
163 
164     public static void main(String[] args) {
165 
166         Collection<String> tags = javadocTagsIn(args[0]).keySet();
167 
168         for (String tag : tags) {
169             System.out.println(tag);
170         }
171     }
172 }