• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2 *******************************************************************************
3 * Copyright (C) 2002-2011, 2015 International Business Machines Corporation   *
4 * and others. All Rights Reserved.                                            *
5 *******************************************************************************
6 */
7 
8 package com.ibm.icu.dev.tool.docs;
9 
10 import java.text.BreakIterator;
11 import java.util.Locale;
12 import java.util.Map;
13 
14 import com.sun.javadoc.Tag;
15 import com.sun.tools.doclets.internal.toolkit.taglets.Taglet;
16 
17 public abstract class ICUTaglet extends ICUTagletAdapter implements Taglet {
18     protected final String name;
19     protected final int mask;
20 
21     protected static final int MASK_FIELD = 1;
22     protected static final int MASK_CONSTRUCTOR = 2;
23     protected static final int MASK_METHOD = 4;
24     protected static final int MASK_OVERVIEW = 8;
25     protected static final int MASK_PACKAGE = 16;
26     protected static final int MASK_TYPE = 32;
27     protected static final int MASK_INLINE = 64;
28 
29     protected static final int MASK_DEFAULT = 0x003f; // no inline
30     protected static final int MASK_DEFAULT_INLINE = 0x007f; // includes inline
31     protected static final int MASK_VALID = 0x007f;
32 
register(Map taglets)33     public static void register(Map taglets) {
34         ICUInternalTaglet.register(taglets);
35         ICUDraftTaglet.register(taglets);
36         ICUStableTaglet.register(taglets);
37         ICUProvisionalTaglet.register(taglets);
38         ICUObsoleteTaglet.register(taglets);
39         ICUIgnoreTaglet.register(taglets);
40         ICUNewTaglet.register(taglets);
41         ICUNoteTaglet.register(taglets);
42         ICUEnhancedTaglet.register(taglets);
43     }
44 
ICUTaglet(String name, int mask)45     protected ICUTaglet(String name, int mask) {
46         this.name = name;
47         this.mask = mask & MASK_VALID;
48     }
49 
inField()50     public boolean inField() {
51         return (mask & MASK_FIELD) != 0;
52     }
53 
inConstructor()54     public boolean inConstructor() {
55         return (mask & MASK_CONSTRUCTOR) != 0;
56     }
57 
inMethod()58     public boolean inMethod() {
59         return (mask & MASK_METHOD) != 0;
60     }
61 
inOverview()62     public boolean inOverview() {
63         return (mask & MASK_OVERVIEW) != 0;
64     }
65 
inPackage()66     public boolean inPackage() {
67         return (mask & MASK_PACKAGE) != 0;
68     }
69 
inType()70     public boolean inType() {
71         return (mask & MASK_TYPE) != 0;
72     }
73 
isInlineTag()74     public boolean isInlineTag() {
75         return (mask & MASK_INLINE) != 0;
76     }
77 
getName()78     public String getName() {
79         return name;
80     }
81 
toString(Tag tag)82     public String toString(Tag tag) {
83         return tag.text();
84     }
85 
toString(Tag[] tags)86     public String toString(Tag[] tags) {
87       if (!isInlineTag() && tags != null) {
88             if (tags.length > 1) {
89                 String msg = "Should not have more than one ICU tag per element:\n";
90                 for (int i = 0; i < tags.length; ++i) {
91                     msg += "  [" + i + "] " + tags[i] + "\n";
92                 }
93                 throw new IllegalStateException(msg);
94             } else if (tags.length > 0) {
95                 return toString(tags[0]);
96             }
97         }
98         return null;
99     }
100 
101     protected static final String STATUS = "<dt><b>Status:</b></dt>";
102 
103     public static class ICUInternalTaglet extends ICUTaglet {
104         private static final String NAME = "internal";
105 
register(Map taglets)106         public static void register(Map taglets) {
107             taglets.put(NAME, new ICUInternalTaglet());
108         }
109 
ICUInternalTaglet()110         private ICUInternalTaglet() {
111             super(NAME, MASK_DEFAULT);
112         }
113 
toString(Tag tag)114         public String toString(Tag tag) {
115             if (tag.text().toLowerCase(Locale.US).indexOf("technology preview") >= 0) {
116                 return STATUS + "<dd><em>Technology Preview</em>. <font color='red'>" +
117                     "This API is still in the early stages of development. Use at your own risk.</font></dd>";
118             }
119             return STATUS + "<dd><em>Internal</em>. <font color='red'>" +
120                 "This API is <em>ICU internal only</em>.</font></dd>";
121         }
122     }
123 
124     public static class ICUDraftTaglet extends ICUTaglet {
125         private static final String NAME = "draft";
126 
register(Map taglets)127         public static void register(Map taglets) {
128             taglets.put(NAME, new ICUDraftTaglet());
129         }
130 
ICUDraftTaglet()131         private ICUDraftTaglet() {
132             super(NAME, MASK_DEFAULT);
133         }
134 
toString(Tag tag)135         public String toString(Tag tag) {
136             String text = tag.text();
137             if (text.length() == 0) {
138                 System.err.println("Warning: empty draft tag");
139             }
140             return STATUS + "<dd>Draft " + tag.text() + ".</dd>";
141         }
142     }
143 
144     public static class ICUStableTaglet extends ICUTaglet {
145         private static final String NAME = "stable";
146 
register(Map taglets)147         public static void register(Map taglets) {
148             taglets.put(NAME, new ICUStableTaglet());
149         }
150 
ICUStableTaglet()151         private ICUStableTaglet() {
152             super(NAME, MASK_DEFAULT);
153         }
154 
toString(Tag tag)155         public String toString(Tag tag) {
156             String text = tag.text();
157             if (text.length() > 0) {
158                 return STATUS + "<dd>Stable " + text + ".</dd>";
159             } else {
160                 return STATUS + "<dd>Stable.</dd>";
161             }
162         }
163     }
164 
165     public static class ICUProvisionalTaglet extends ICUTaglet {
166         private static final String NAME = "provisional";
167 
register(Map taglets)168         public static void register(Map taglets) {
169             taglets.remove(NAME); // override standard deprecated taglet
170             taglets.put(NAME, new ICUProvisionalTaglet());
171         }
172 
ICUProvisionalTaglet()173         private ICUProvisionalTaglet() {
174             super(NAME, MASK_DEFAULT);
175         }
176 
toString(Tag tag)177         public String toString(Tag tag) {
178             return null;
179         }
180     }
181 
182     public static class ICUObsoleteTaglet extends ICUTaglet {
183         private static final String NAME = "obsolete";
184 
register(Map taglets)185         public static void register(Map taglets) {
186             taglets.put(NAME, new ICUObsoleteTaglet());
187         }
188 
ICUObsoleteTaglet()189         private ICUObsoleteTaglet() {
190             super(NAME, MASK_DEFAULT);
191         }
192 
toString(Tag tag)193         public String toString(Tag tag) {
194             BreakIterator bi = BreakIterator.getSentenceInstance(Locale.US);
195             String text = tag.text();
196             bi.setText(text);
197             int first = bi.first();
198             int next = bi.next();
199             if (text.length() == 0) {
200                 first = next = 0;
201             }
202             return STATUS + "<dd><em>Obsolete.</em> <font color='red'>Will be removed in " +
203                 text.substring(first, next) + "</font>. " + text.substring(next) + "</dd>";
204 
205         }
206     }
207 
208     public static class ICUIgnoreTaglet extends ICUTaglet {
209         private static ICUTaglet singleton;
210 
register(Map taglets)211         public static void register(Map taglets) {
212             if (singleton == null) {
213                 singleton = new ICUIgnoreTaglet();
214             }
215             taglets.put("bug", singleton);
216             taglets.put("test", singleton);
217             taglets.put("summary", singleton);
218         }
219 
ICUIgnoreTaglet()220         private ICUIgnoreTaglet() {
221             super(".ignore", MASK_DEFAULT);
222         }
223 
toString(Tag tag)224         public String toString(Tag tag) {
225             return null;
226         }
227     }
228 
229     private static String ICU_LABEL = "<strong><font color=red>[icu]</font></strong>";
230 
231     /**
232      * This taglet should be used in the first line of the class description of classes
233      * that are enhancements of JDK classes that similar names and APIs.  The text should
234      * provide the full package and name of the JDK class.  A period should follow the
235      * tag.  This puts an 'icu enhancement' message into the first line of the class docs,
236      * where it will also appear in the class summary.
237      *
238      * <p>Following this tag (and period), ideally in the first paragraph, the '@icu' tag
239      * should be used with the text '_label_' to generate the standard boilerplate about
240      * how that tag is used in the class docs.  See {@link ICUNewTaglet}.
241      *
242      * <p>This cumbersome process is necessary because the javadoc code that handles
243      * taglets doesn't look at punctuation in the substitution text to determine when to
244      * end the first line, it looks in the original javadoc comment.  So we need a tag to
245      * identify the related java class, then a period, then another tag.
246      */
247      public static class ICUEnhancedTaglet extends ICUTaglet {
248         private static final String NAME = "icuenhanced";
249 
register(Map taglets)250         public static void register(Map taglets) {
251             taglets.put(NAME, new ICUEnhancedTaglet());
252         }
253 
ICUEnhancedTaglet()254         private ICUEnhancedTaglet() {
255             super(NAME, MASK_DEFAULT_INLINE);
256         }
257 
toString(Tag tag)258         public String toString(Tag tag) {
259             String text = tag.text().trim();
260 
261             boolean isClassDoc = tag.holder().isClass() || tag.holder().isInterface();
262             if (isClassDoc && text.length() > 0) {
263                 StringBuilder sb = new StringBuilder();
264                 return sb.append("<strong><font color=red>[icu enhancement]</font></strong> ")
265                     .append("ICU's replacement for <code>")
266                     .append(text)
267                     .append("</code>")
268                     .toString();
269             }
270             return "";
271         }
272     }
273 
274     /**
275      * This taglet should be used in the first line of any icu-specific members in a class
276      * that is an enhancement of a JDK class (see {@link ICUEnhancedTaglet}). It generates
277      * the '[icu]' marker followed by the &lt;strong&gt; text, if any.  This does not
278      * start or end a paragraph or provide additional leading or trailing punctuation such
279      * as spaces or periods.
280      *
281      * <p>Note: if the text is '_usage_' (without quotes) this spits out a boilerplate
282      * message describing the meaning of the '[icu]' tag.  This should be done in the
283      * first paragraph of the class docs of any class containing '@icu' tags.
284      */
285     public static class ICUNewTaglet extends ICUTaglet {
286         private static final String NAME = "icu";
287 
register(Map taglets)288         public static void register(Map taglets) {
289             taglets.put(NAME, new ICUNewTaglet());
290         }
291 
ICUNewTaglet()292         private ICUNewTaglet() {
293             super(NAME, MASK_DEFAULT_INLINE);
294         }
295 
toString(Tag tag)296         public String toString(Tag tag) {
297             String text = tag.text().trim();
298             StringBuilder sb = new StringBuilder();
299             if ("_usage_".equals(text)) {
300                 return sb.append(" Methods, fields, and other functionality specific to ICU ")
301                     .append("are labeled '" + ICU_LABEL + "'.</p>")
302                     .toString();
303             }
304 
305             sb.append("<strong><font color=red>[icu]</font>");
306             if (text.length() > 0) {
307                 sb.append(" ").append(text);
308             }
309             sb.append("</strong>");
310             return sb.toString();
311         }
312     }
313 
314     /**
315      * This taglet should be used in class or member documentation, after the first line,
316      * where the behavior of the ICU method or class has notable differences from its JDK
317      * counterpart. It starts a new paragraph and generates an '[icu] Note:' header.
318      */
319     public static class ICUNoteTaglet extends ICUTaglet {
320         private static final String NAME = "icunote";
321 
register(Map taglets)322         public static void register(Map taglets) {
323             taglets.put(NAME, new ICUNoteTaglet());
324         }
325 
ICUNoteTaglet()326         private ICUNoteTaglet() {
327             super(NAME, MASK_DEFAULT_INLINE);
328         }
329 
toString(Tag tag)330         public String toString(Tag tag) {
331             return "<p><strong><font color=red>[icu]</font> Note:</strong> ";
332         }
333     }
334 }
335