001: /*
002: * Author: Chris Seguin
003: *
004: * This software has been developed under the copyleft
005: * rules of the GNU General Public License. Please
006: * consult the GNU General Public License for more
007: * details about use and distribution of this software.
008: */
009: package org.acm.seguin.pretty;
010:
011: import net.sourceforge.jrefactory.ast.Node;
012: import net.sourceforge.jrefactory.parser.JavaParserConstants;
013: import net.sourceforge.jrefactory.parser.Token;
014:
015: /**
016: * Consume a javadoc comment
017: *
018: *@author Chris Seguin
019: *@author Mike Atkinson
020: *@created April 10, 1999
021: */
022: public class PrintSpecialJavadocComment extends PrintSpecial {
023: /**
024: * Determines if this print special can handle the current object
025: *
026: *@param spec Description of Parameter
027: *@return true if this one should process the input
028: */
029: public boolean isAcceptable(SpecialTokenData spec) {
030: return (spec.getTokenType() == JavaParserConstants.FORMAL_COMMENT);
031: }
032:
033: /**
034: * Processes the special token
035: *
036: *@param node the type of node this special is being processed for
037: *@param spec the special token data
038: *@return Description of the Returned Value
039: */
040: public boolean process(Node node, SpecialTokenData spec) {
041: JavaDocable docable = null;
042:
043: if (spec.getJDI() != null) {
044: docable = spec.getJDI();
045: } else if (spec.getPrintData().isAllJavadocKept()) {
046: docable = new JavaDocableImpl();
047: } else {
048: return false;
049: }
050:
051: // Current components
052: JavaDocComponent jdc = new JavaDocComponent();
053: StringBuffer description = new StringBuffer();
054:
055: // Break into lines
056: JavadocTokenizer tok = new JavadocTokenizer(spec
057: .getTokenImage());
058: while (tok.hasNext()) {
059: Token next = tok.next();
060:
061: if ((next.image == null) || (next.image.length() == 0)) {
062: // Do nothing
063: } else if (isJavadocTag(next)) {
064: storeJDCinNode(docable, jdc, description);
065: jdc = createJavaDocComponent(next.image, tok,
066: description);
067: } else {
068: description.append(next.image);
069: }
070: }
071:
072: // Last JDC
073: if (jdc != null) {
074: storeJDCinNode(docable, jdc, description);
075: }
076:
077: // Finish the JavaDoc by adding @param, @return, @throws from method
078: // but only if this is the last JavaDoc before the method.
079: if (spec.isLastJavadocComment()) {
080: docable.finish();
081: }
082: docable.printJavaDocComponents(spec.getPrintData());
083: return true;
084: }
085:
086: /**
087: * Checks to see if the token is a javadoc tag that should be separated out
088: * from the rest of the code.
089: *
090: *@param next the token that we are checking
091: *@return true if this tag should be beautified
092: */
093: private boolean isJavadocTag(Token next) {
094: if (next.kind != JavadocTokenizer.WORD) {
095: return false;
096: }
097:
098: String image = next.image;
099: if (image.charAt(0) != '@') {
100: return false;
101: }
102:
103: int imageLength = image.length();
104: if (image.charAt(imageLength - 1) == '@') {
105: return false;
106: }
107:
108: for (int ndx = 1; ndx < imageLength; ndx++) {
109: char c = image.charAt(ndx);
110: if (!(Character.isLetterOrDigit(c) || c == '.' || c == '-'))
111: return false;
112: }
113:
114: return true;
115: }
116:
117: /**
118: * Create new JavaDocComponent
119: *
120: *@param current the current item
121: *@param parts the tokenizer
122: *@return the new JavaDocComponent
123: */
124: private JavaDocComponent createJavaDocComponent(String current,
125: JavadocTokenizer parts, StringBuffer descr) {
126: JavaDocComponent jdc;
127:
128: // Create the new jdc
129: if (current.equals("@param") || current.equals("@exception")
130: || current.equals("@throws")) {
131: jdc = new NamedJavaDocComponent();
132: jdc.setType(current);
133:
134: while (parts.hasNext()) {
135: Token next = parts.next();
136: if (next.kind == JavadocTokenizer.WORD) {
137: ((NamedJavaDocComponent) jdc).setID(next.image);
138: return jdc;
139: }
140: }
141:
142: return null;
143: } else if (current.indexOf('.') >= 0) {
144: jdc = new XDocletJavaDocComponent();
145: jdc.setType(current);
146: } else {
147: jdc = new NamedJavaDocComponent();
148: jdc.setType(current);
149: }
150:
151: // Return the result
152: return jdc;
153: }
154:
155: /**
156: * Store JavaDocComponent in the node
157: *
158: *@param node the next node
159: *@param jdc the component
160: *@param descr the description
161: */
162: private void storeJDCinNode(JavaDocable node, JavaDocComponent jdc,
163: StringBuffer descr) {
164: if (jdc == null) {
165: return;
166: }
167:
168: jdc.setDescription(descr.toString().trim());
169: node.addJavaDocComponent(jdc);
170: descr.setLength(0);
171: }
172: }
|