001: package org.andromda.maven.site;
002:
003: import org.apache.commons.jelly.XMLOutput;
004: import org.apache.commons.lang.StringUtils;
005: import org.xml.sax.SAXException;
006:
007: import java.util.HashSet;
008: import java.util.Set;
009: import java.util.StringTokenizer;
010:
011: public class HighlightJavaTag extends AbstractHighlightTag {
012: private String keywordClass = null;
013: private String stringLiteralClass = null;
014: private String numericLiteralClass = null;
015: private String commentClass = null;
016:
017: public String getCommentClass() {
018: return commentClass;
019: }
020:
021: public void setCommentClass(String commentClass) {
022: this .commentClass = commentClass;
023: }
024:
025: public String getKeywordClass() {
026: return keywordClass;
027: }
028:
029: public void setKeywordClass(String keywordClass) {
030: this .keywordClass = keywordClass;
031: }
032:
033: public String getStringLiteralClass() {
034: return stringLiteralClass;
035: }
036:
037: public void setStringLiteralClass(String stringLiteralClass) {
038: this .stringLiteralClass = stringLiteralClass;
039: }
040:
041: public String getNumericLiteralClass() {
042: return numericLiteralClass;
043: }
044:
045: public void setNumericLiteralClass(String numericLiteralClass) {
046: this .numericLiteralClass = numericLiteralClass;
047: }
048:
049: protected void highlight(XMLOutput output, String text)
050: throws SAXException {
051: boolean inPreComment = false; // first slash
052: boolean inLineComment = false;
053: boolean inBlockComment = false;
054: boolean inPostComment = false; // asterisk of closing */
055: boolean inString = false;
056:
057: StringTokenizer tokenizer = new StringTokenizer(text,
058: " \n\r\t\f\"\'(){}[].,;:?!+-*/%^&|<>=~", true);
059: while (tokenizer.hasMoreTokens()) {
060: String token = tokenizer.nextToken();
061:
062: if (inPreComment) {
063: if (token.equals("/")) {
064: inPreComment = false;
065: inLineComment = true;
066: startTokenHighlight(output, getCommentClass());
067: output.write("//");
068: continue;
069: } else if (token.equals("*")) {
070: inPreComment = false;
071: inBlockComment = true;
072: startTokenHighlight(output, getCommentClass());
073: output.write("/*");
074: continue;
075: } else {
076: output.write("/");
077: inPreComment = false;
078: }
079: } else if (inLineComment) {
080: if (token.equals("\n")) {
081: endTokenHighlight(output);
082: inLineComment = false;
083: } else {
084: output.write(token);
085: continue;
086: }
087: } else if (inBlockComment) {
088: output.write(token);
089: if (token.equals("*")) {
090: inBlockComment = false;
091: inPostComment = true;
092: }
093: continue;
094: } else if (inPostComment) {
095: output.write(token);
096: if (token.equals("/")) {
097: endTokenHighlight(output);
098: inPostComment = false;
099: } else if (!token.equals("*")) {
100: inPostComment = false;
101: inBlockComment = true;
102: }
103: continue;
104: }
105:
106: if (inString) {
107: output.write(token);
108: if (token.equals("\"") || token.equals("\'")) {
109: inString = false;
110: endTokenHighlight(output);
111: }
112: } else {
113: if (JAVA_KEYWORDS.contains(token)) {
114: startTokenHighlight(output, getKeywordClass());
115: output.write(token);
116: endTokenHighlight(output);
117: } else if (StringUtils.isNumeric(token)) {
118: startTokenHighlight(output,
119: getNumericLiteralClass());
120: output.write(token);
121: endTokenHighlight(output);
122: } else {
123: if (token.equals("\"") || token.equals("\'")) {
124: startTokenHighlight(output,
125: getStringLiteralClass());
126: output.write(token);
127: inString = true;
128: } else if (token.equals("/")) {
129: inPreComment = true;
130: } else {
131: output.write(token);
132: }
133: }
134: }
135: }
136: }
137:
138: private final static Set JAVA_KEYWORDS = new HashSet(52, 1);
139:
140: static {
141: JAVA_KEYWORDS.add("abstract");
142: JAVA_KEYWORDS.add("boolean");
143: JAVA_KEYWORDS.add("break");
144: JAVA_KEYWORDS.add("byte");
145: JAVA_KEYWORDS.add("case");
146: JAVA_KEYWORDS.add("catch");
147: JAVA_KEYWORDS.add("char");
148: JAVA_KEYWORDS.add("class");
149: JAVA_KEYWORDS.add("const");
150: JAVA_KEYWORDS.add("continue");
151: JAVA_KEYWORDS.add("default");
152: JAVA_KEYWORDS.add("do");
153: JAVA_KEYWORDS.add("double");
154: JAVA_KEYWORDS.add("else");
155: JAVA_KEYWORDS.add("enum");
156: JAVA_KEYWORDS.add("extends");
157: JAVA_KEYWORDS.add("final");
158: JAVA_KEYWORDS.add("finally");
159: JAVA_KEYWORDS.add("float");
160: JAVA_KEYWORDS.add("for");
161: JAVA_KEYWORDS.add("goto");
162: JAVA_KEYWORDS.add("if");
163: JAVA_KEYWORDS.add("implements");
164: JAVA_KEYWORDS.add("import");
165: JAVA_KEYWORDS.add("instanceof");
166: JAVA_KEYWORDS.add("int");
167: JAVA_KEYWORDS.add("interface");
168: JAVA_KEYWORDS.add("long");
169: JAVA_KEYWORDS.add("native");
170: JAVA_KEYWORDS.add("new");
171: JAVA_KEYWORDS.add("package");
172: JAVA_KEYWORDS.add("private");
173: JAVA_KEYWORDS.add("protected");
174: JAVA_KEYWORDS.add("public");
175: JAVA_KEYWORDS.add("return");
176: JAVA_KEYWORDS.add("short");
177: JAVA_KEYWORDS.add("static");
178: JAVA_KEYWORDS.add("strictfp");
179: JAVA_KEYWORDS.add("super");
180: JAVA_KEYWORDS.add("switch");
181: JAVA_KEYWORDS.add("synchronized");
182: JAVA_KEYWORDS.add("this");
183: JAVA_KEYWORDS.add("throw");
184: JAVA_KEYWORDS.add("throws");
185: JAVA_KEYWORDS.add("transient");
186: JAVA_KEYWORDS.add("try");
187: JAVA_KEYWORDS.add("void");
188: JAVA_KEYWORDS.add("volatile");
189: JAVA_KEYWORDS.add("while");
190:
191: // these are not Java language keywords, but we want them highlighted anyway
192: JAVA_KEYWORDS.add("null");
193: JAVA_KEYWORDS.add("false");
194: JAVA_KEYWORDS.add("true");
195: }
196:
197: }
|