2 *******************************************************************************
\r
3 * Copyright (C) 2002-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.tool.docs;
\r
10 import java.text.BreakIterator;
\r
11 import java.util.Locale;
\r
12 import java.util.Map;
\r
14 import com.sun.javadoc.Doc;
\r
15 import com.sun.javadoc.Tag;
\r
16 import com.sun.tools.doclets.internal.toolkit.taglets.Taglet;
\r
17 import com.sun.tools.doclets.internal.toolkit.taglets.TagletOutput;
\r
18 import com.sun.tools.doclets.internal.toolkit.taglets.TagletWriter;
\r
20 public abstract class ICUTaglet implements Taglet {
\r
21 protected final String name;
\r
22 protected final int mask;
\r
24 protected static final int MASK_FIELD = 1;
\r
25 protected static final int MASK_CONSTRUCTOR = 2;
\r
26 protected static final int MASK_METHOD = 4;
\r
27 protected static final int MASK_OVERVIEW = 8;
\r
28 protected static final int MASK_PACKAGE = 16;
\r
29 protected static final int MASK_TYPE = 32;
\r
30 protected static final int MASK_INLINE = 64;
\r
32 protected static final int MASK_DEFAULT = 0x003f; // no inline
\r
33 protected static final int MASK_DEFAULT_INLINE = 0x007f; // includes inline
\r
34 protected static final int MASK_VALID = 0x007f;
\r
36 public static void register(Map taglets) {
\r
37 ICUInternalTaglet.register(taglets);
\r
38 ICUDraftTaglet.register(taglets);
\r
39 ICUStableTaglet.register(taglets);
\r
40 ICUProvisionalTaglet.register(taglets);
\r
41 ICUObsoleteTaglet.register(taglets);
\r
42 ICUIgnoreTaglet.register(taglets);
\r
43 ICUNewTaglet.register(taglets);
\r
44 ICUNoteTaglet.register(taglets);
\r
45 ICUEnhancedTaglet.register(taglets);
\r
48 protected ICUTaglet(String name, int mask) {
\r
50 this.mask = mask & MASK_VALID;
\r
53 public boolean inField() {
\r
54 return (mask & MASK_FIELD) != 0;
\r
57 public boolean inConstructor() {
\r
58 return (mask & MASK_CONSTRUCTOR) != 0;
\r
61 public boolean inMethod() {
\r
62 return (mask & MASK_METHOD) != 0;
\r
65 public boolean inOverview() {
\r
66 return (mask & MASK_OVERVIEW) != 0;
\r
69 public boolean inPackage() {
\r
70 return (mask & MASK_PACKAGE) != 0;
\r
73 public boolean inType() {
\r
74 return (mask & MASK_TYPE) != 0;
\r
77 public boolean isInlineTag() {
\r
78 return (mask & MASK_INLINE) != 0;
\r
81 public String getName() {
\r
85 public String toString(Tag tag) {
\r
89 public String toString(Tag[] tags) {
\r
90 if (!isInlineTag() && tags != null) {
\r
91 if (tags.length > 1) {
\r
92 String msg = "Should not have more than one ICU tag per element:\n";
\r
93 for (int i = 0; i < tags.length; ++i) {
\r
94 msg += " [" + i + "] " + tags[i] + "\n";
\r
96 throw new IllegalStateException(msg);
\r
97 } else if (tags.length > 0) {
\r
98 return toString(tags[0]);
\r
104 public TagletOutput getTagletOutput(Tag tag, TagletWriter writer)
\r
105 throws IllegalArgumentException {
\r
107 TagletOutput out = writer.getTagletOutputInstance();
\r
108 out.setOutput(toString(tag));
\r
112 public TagletOutput getTagletOutput(Doc holder, TagletWriter writer)
\r
113 throws IllegalArgumentException {
\r
115 TagletOutput out = writer.getTagletOutputInstance();
\r
116 Tag[] tags = holder.tags(getName());
\r
117 if (tags.length == 0) {
\r
120 out.setOutput(toString(tags[0]));
\r
124 protected static final String STATUS = "<dt><b>Status:</b></dt>";
\r
126 public static class ICUInternalTaglet extends ICUTaglet {
\r
127 private static final String NAME = "internal";
\r
129 public static void register(Map taglets) {
\r
130 taglets.put(NAME, new ICUInternalTaglet());
\r
133 private ICUInternalTaglet() {
\r
134 super(NAME, MASK_DEFAULT);
\r
137 public String toString(Tag tag) {
\r
138 return STATUS + "<dd><em>Internal</em>. <font color='red'>" +
\r
139 "This API is <em>ICU internal only</em>.</font></dd>";
\r
143 public static class ICUDraftTaglet extends ICUTaglet {
\r
144 private static final String NAME = "draft";
\r
146 public static void register(Map taglets) {
\r
147 taglets.put(NAME, new ICUDraftTaglet());
\r
150 private ICUDraftTaglet() {
\r
151 super(NAME, MASK_DEFAULT);
\r
154 public String toString(Tag tag) {
\r
155 String text = tag.text();
\r
156 if (text.length() == 0) {
\r
157 System.err.println("Warning: empty draft tag");
\r
159 return STATUS + "<dd>Draft " + tag.text() + ".</dd>";
\r
163 public static class ICUStableTaglet extends ICUTaglet {
\r
164 private static final String NAME = "stable";
\r
166 public static void register(Map taglets) {
\r
167 taglets.put(NAME, new ICUStableTaglet());
\r
170 private ICUStableTaglet() {
\r
171 super(NAME, MASK_DEFAULT);
\r
174 public String toString(Tag tag) {
\r
175 String text = tag.text();
\r
176 if (text.length() > 0) {
\r
177 return STATUS + "<dd>Stable " + text + ".</dd>";
\r
179 return STATUS + "<dd>Stable.</dd>";
\r
184 public static class ICUProvisionalTaglet extends ICUTaglet {
\r
185 private static final String NAME = "provisional";
\r
187 public static void register(Map taglets) {
\r
188 taglets.remove(NAME); // override standard deprecated taglet
\r
189 taglets.put(NAME, new ICUProvisionalTaglet());
\r
192 private ICUProvisionalTaglet() {
\r
193 super(NAME, MASK_DEFAULT);
\r
196 public String toString(Tag tag) {
\r
201 public static class ICUObsoleteTaglet extends ICUTaglet {
\r
202 private static final String NAME = "obsolete";
\r
204 public static void register(Map taglets) {
\r
205 taglets.put(NAME, new ICUObsoleteTaglet());
\r
208 private ICUObsoleteTaglet() {
\r
209 super(NAME, MASK_DEFAULT);
\r
212 public String toString(Tag tag) {
\r
213 BreakIterator bi = BreakIterator.getSentenceInstance(Locale.US);
\r
214 String text = tag.text();
\r
216 int first = bi.first();
\r
217 int next = bi.next();
\r
218 if (text.length() == 0) {
\r
221 return STATUS + "<dd><em>Obsolete.</em> <font color='red'>Will be removed in " +
\r
222 text.substring(first, next) + "</font>. " + text.substring(next) + "</dd>";
\r
227 public static class ICUIgnoreTaglet extends ICUTaglet {
\r
228 private static ICUTaglet singleton;
\r
230 public static void register(Map taglets) {
\r
231 if (singleton == null) {
\r
232 singleton = new ICUIgnoreTaglet();
\r
234 taglets.put("bug", singleton);
\r
235 taglets.put("test", singleton);
\r
236 taglets.put("summary", singleton);
\r
239 private ICUIgnoreTaglet() {
\r
240 super(".ignore", MASK_DEFAULT);
\r
243 public String toString(Tag tag) {
\r
248 private static String ICU_LABEL = "<strong><font color=red>[icu]</font></strong>";
\r
251 * This taglet should be used in the first line of the class description of classes
\r
252 * that are enhancements of JDK classes that similar names and APIs. The text should
\r
253 * provide the full package and name of the JDK class. A period should follow the
\r
254 * tag. This puts an 'icu enhancement' message into the first line of the class docs,
\r
255 * where it will also appear in the class summary.
\r
257 * <p>Following this tag (and period), ideally in the first paragraph, the '@icu' tag
\r
258 * should be used with the text '_label_' to generate the standard boilerplate about
\r
259 * how that tag is used in the class docs. See {@link ICUNewTaglet}.
\r
261 * <p>This cumbersome process is necessary because the javadoc code that handles
\r
262 * taglets doesn't look at punctuation in the substitution text to determine when to
\r
263 * end the first line, it looks in the original javadoc comment. So we need a tag to
\r
264 * identify the related java class, then a period, then another tag.
\r
266 public static class ICUEnhancedTaglet extends ICUTaglet {
\r
267 private static final String NAME = "icuenhanced";
\r
269 public static void register(Map taglets) {
\r
270 taglets.put(NAME, new ICUEnhancedTaglet());
\r
273 private ICUEnhancedTaglet() {
\r
274 super(NAME, MASK_DEFAULT_INLINE);
\r
277 public String toString(Tag tag) {
\r
278 String text = tag.text().trim();
\r
280 boolean isClassDoc = tag.holder().isClass() || tag.holder().isInterface();
\r
281 if (isClassDoc && text.length() > 0) {
\r
282 StringBuilder sb = new StringBuilder();
\r
283 return sb.append("<strong><font color=red>[icu enhancement]</font></strong> ")
\r
284 .append("ICU's replacement for <code>")
\r
294 * This taglet should be used in the first line of any icu-specific members in a class
\r
295 * that is an enhancement of a JDK class (see {@link ICUEnhancedTaglet}). It generates
\r
296 * the '[icu]' marker followed by the <strong> text, if any. This does not
\r
297 * start or end a paragraph or provide additional leading or trailing punctuation such
\r
298 * as spaces or periods.
\r
300 * <p>Note: if the text is '_usage_' (without quotes) this spits out a boilerplate
\r
301 * message describing the meaning of the '[icu]' tag. This should be done in the
\r
302 * first paragraph of the class docs of any class containing '@icu' tags.
\r
304 public static class ICUNewTaglet extends ICUTaglet {
\r
305 private static final String NAME = "icu";
\r
307 public static void register(Map taglets) {
\r
308 taglets.put(NAME, new ICUNewTaglet());
\r
311 private ICUNewTaglet() {
\r
312 super(NAME, MASK_DEFAULT_INLINE);
\r
315 public String toString(Tag tag) {
\r
316 String text = tag.text().trim();
\r
317 StringBuilder sb = new StringBuilder();
\r
318 if ("_usage_".equals(text)) {
\r
319 return sb.append(" Methods, fields, and other functionality specific to ICU ")
\r
320 .append("are labeled '" + ICU_LABEL + "'.</p>")
\r
324 sb.append("<strong><font color=red>[icu]</font>");
\r
325 if (text.length() > 0) {
\r
326 sb.append(" ").append(text);
\r
328 sb.append("</strong>");
\r
329 return sb.toString();
\r
334 * This taglet should be used in class or member documentation, after the first line,
\r
335 * where the behavior of the ICU method or class has notable differences from its JDK
\r
336 * counterpart. It starts a new paragraph and generates an '[icu] Note:' header.
\r
338 public static class ICUNoteTaglet extends ICUTaglet {
\r
339 private static final String NAME = "icunote";
\r
341 public static void register(Map taglets) {
\r
342 taglets.put(NAME, new ICUNoteTaglet());
\r
345 private ICUNoteTaglet() {
\r
346 super(NAME, MASK_DEFAULT_INLINE);
\r
349 public String toString(Tag tag) {
\r
350 return "<p><strong><font color=red>[icu]</font> Note:</strong> ";
\r