001: package org.andromda.maven.doxia.module.xdoc;
002:
003: /*
004: * Copyright 2004-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import org.apache.maven.doxia.macro.MacroRequest;
020: import org.apache.maven.doxia.parser.AbstractParser;
021: import org.apache.maven.doxia.parser.ParseException;
022: import org.apache.maven.doxia.sink.Sink;
023: import org.apache.maven.doxia.sink.StructureSink;
024: import org.codehaus.plexus.util.xml.pull.MXParser;
025: import org.codehaus.plexus.util.xml.pull.XmlPullParser;
026: import org.codehaus.plexus.util.StringUtils;
027:
028: import java.io.Reader;
029: import java.util.HashMap;
030: import java.util.Map;
031:
032: /**
033: * Parse an xdoc model and emit events into the specified doxia
034: * Sink.
035: *
036: * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
037: * @version $Id: AndromdadocParser.java,v 1.1.2.1 2006/09/14 08:10:39 vancek Exp $
038: *
039: * @plexus.component role="org.apache.maven.doxia.parser.Parser" role-hint="andromdadoc"
040: */
041: public class AndromdadocParser extends AbstractParser {
042: public void parse(Reader reader, Sink sink) throws ParseException {
043: try {
044: XmlPullParser parser = new MXParser();
045:
046: parser.setInput(reader);
047:
048: parseXdoc(parser, sink);
049: } catch (Exception ex) {
050: throw new ParseException("Error parsing the model.", ex);
051: }
052: }
053:
054: public void parseXdoc(XmlPullParser parser, Sink sink)
055: throws Exception {
056: int eventType = parser.getEventType();
057:
058: while (eventType != XmlPullParser.END_DOCUMENT) {
059: if (eventType == XmlPullParser.START_TAG) {
060: if (parser.getName().equals("document")) {
061: //Do nothing
062: } else if (parser.getName().equals("title")) {
063: sink.title();
064: } else if (parser.getName().equals("author")) {
065: sink.author();
066: } else if (parser.getName().equals("body")) {
067: sink.body();
068: } else if (parser.getName().equals("section")) {
069: sink.anchor(parser.getAttributeValue(null, "name"));
070: sink.anchor_();
071:
072: sink.section1();
073:
074: sink.sectionTitle1();
075:
076: sink.text(parser.getAttributeValue(null, "name"));
077:
078: sink.sectionTitle1_();
079: } else if (parser.getName().equals("subsection")) {
080: sink.anchor(parser.getAttributeValue(null, "name"));
081: sink.anchor_();
082:
083: sink.section2();
084:
085: sink.sectionTitle2();
086:
087: sink.text(parser.getAttributeValue(null, "name"));
088:
089: sink.sectionTitle2_();
090: } else if (parser.getName().equals("p")) {
091: final String styleClass = parser.getAttributeValue(
092: null, "class");
093: this .writeParagraph(sink, styleClass);
094: } else if (parser.getName().equals("source")) {
095: sink.verbatim(true);
096: } else if (parser.getName().equals("ul")) {
097: sink.list();
098: } else if (parser.getName().equals("ol")) {
099: sink.numberedList(Sink.NUMBERING_DECIMAL);
100: } else if (parser.getName().equals("li")) {
101: final String styleClass = parser.getAttributeValue(
102: null, "class");
103: this .writeListItem(sink, styleClass);
104: } else if (parser.getName().equals("properties")) {
105: sink.head();
106: } else if (parser.getName().equals("b")) {
107: sink.bold();
108: } else if (parser.getName().equals("i")) {
109: sink.italic();
110: } else if (parser.getName().equals("a")) {
111: final String styleClass = parser.getAttributeValue(
112: null, "class");
113: final String target = parser.getAttributeValue(
114: null, "target");
115: final String href = parser.getAttributeValue(null,
116: "href");
117:
118: if (StringUtils.isNotEmpty(href)) {
119: this .writeLink(sink, styleClass, target, href);
120: } else {
121: final String name = parser.getAttributeValue(
122: null, "name");
123: if (StringUtils.isNotEmpty(name)) {
124: this .writeAnchor(sink, styleClass, name);
125: } else {
126: handleRawText(sink, parser);
127: }
128: }
129: } else if (parser.getName().equals("macro")) {
130: String macroId = parser.getAttributeValue(null,
131: "id");
132:
133: int count = parser.getAttributeCount();
134:
135: Map parameters = new HashMap();
136:
137: for (int i = 1; i < count; i++) {
138: parameters.put(parser.getAttributeName(i),
139: parser.getAttributeValue(i));
140: }
141:
142: MacroRequest request = new MacroRequest(parameters);
143:
144: executeMacro(macroId, request, sink);
145: }
146:
147: // ----------------------------------------------------------------------
148: // Tables
149: // ----------------------------------------------------------------------
150:
151: else if (parser.getName().equals("table")) {
152: sink.table();
153: } else if (parser.getName().equals("tr")) {
154: sink.tableRow();
155: } else if (parser.getName().equals("th")) {
156: final String width = parser.getAttributeValue(null,
157: "width");
158: final String styleClass = parser.getAttributeValue(
159: null, "class");
160: this .writeTableHeaderCell(sink, width, styleClass);
161: } else if (parser.getName().equals("td")) {
162: String width = parser.getAttributeValue(null,
163: "width");
164: String styleClass = parser.getAttributeValue(null,
165: "class");
166: this .writeTableCell(sink, width, styleClass);
167: } else {
168: handleRawText(sink, parser);
169: }
170: } else if (eventType == XmlPullParser.END_TAG) {
171: if (parser.getName().equals("document")) {
172: //Do nothing
173: } else if (parser.getName().equals("title")) {
174: sink.title_();
175: } else if (parser.getName().equals("author")) {
176: sink.author_();
177: } else if (parser.getName().equals("body")) {
178: sink.body_();
179: } else if (parser.getName().equals("p")) {
180: sink.paragraph_();
181: } else if (parser.getName().equals("source")) {
182: sink.verbatim_();
183: } else if (parser.getName().equals("ul")) {
184: sink.list_();
185: } else if (parser.getName().equals("ol")) {
186: sink.numberedList_();
187: } else if (parser.getName().equals("li")) {
188: sink.listItem_();
189: } else if (parser.getName().equals("properties")) {
190: sink.head_();
191: } else if (parser.getName().equals("b")) {
192: sink.bold_();
193: } else if (parser.getName().equals("i")) {
194: sink.italic_();
195: } else if (parser.getName().equals("a")) {
196: // TODO: Note there will be badness if link_ != anchor != </a>
197: sink.link_();
198: }
199:
200: // ----------------------------------------------------------------------
201: // Tables
202: // ----------------------------------------------------------------------
203:
204: else if (parser.getName().equals("table")) {
205: sink.table_();
206: } else if (parser.getName().equals("tr")) {
207: sink.tableRow_();
208: } else if (parser.getName().equals("th")) {
209: sink.tableHeaderCell_();
210: } else if (parser.getName().equals("td")) {
211: sink.tableCell_();
212: }
213:
214: // ----------------------------------------------------------------------
215: // Sections
216: // ----------------------------------------------------------------------
217:
218: else if (parser.getName().equals("section")) {
219: sink.section1_();
220: } else if (parser.getName().equals("subsection")) {
221: sink.section2_();
222: } else {
223: sink.rawText("</");
224:
225: sink.rawText(parser.getName());
226:
227: sink.rawText(">");
228: }
229:
230: // ----------------------------------------------------------------------
231: // Sections
232: // ----------------------------------------------------------------------
233: } else if (eventType == XmlPullParser.TEXT) {
234: sink.text(parser.getText());
235: }
236:
237: eventType = parser.next();
238: }
239: }
240:
241: private void handleRawText(Sink sink, XmlPullParser parser) {
242: sink.rawText("<");
243:
244: sink.rawText(parser.getName());
245:
246: int count = parser.getAttributeCount();
247:
248: for (int i = 0; i < count; i++) {
249: sink.rawText(" ");
250:
251: sink.rawText(parser.getAttributeName(i));
252:
253: sink.rawText("=");
254:
255: sink.rawText("\"");
256:
257: sink.rawText(parser.getAttributeValue(i));
258:
259: sink.rawText("\"");
260: }
261:
262: sink.rawText(">");
263: }
264:
265: private void writeParagraph(Sink sink, String styleClass) {
266: if (styleClass != null) {
267: sink.rawText("<p class=\"" + styleClass + "\">");
268: } else {
269: sink.paragraph();
270: }
271: }
272:
273: private void writeListItem(Sink sink, String styleClass) {
274: if (StringUtils.isNotEmpty(styleClass)) {
275: sink.rawText("<li class=\"" + styleClass + "\">");
276: } else {
277: sink.listItem();
278: }
279: }
280:
281: private void writeLink(Sink sink, String styleClass, String target,
282: String href) {
283: if (StringUtils.isNotEmpty(styleClass)) {
284: sink.rawText("<a ");
285:
286: if (StringUtils.isNotEmpty(styleClass)) {
287: sink.rawText("class=\"" + styleClass + "\" ");
288: }
289:
290: if (StringUtils.isNotEmpty(target)) {
291: sink.rawText("target=\"" + target + "\" ");
292: }
293:
294: sink.rawText("href=\"" + href + "\">");
295: } else {
296: sink.link(href);
297: }
298: }
299:
300: private void writeAnchor(Sink sink, String styleClass, String name) {
301: if (StringUtils.isNotEmpty(name)) {
302: sink.rawText("<a name=\"" + name + "\" ");
303:
304: if (StringUtils.isNotEmpty(styleClass)) {
305: sink.rawText("class=\"" + styleClass + "\"");
306: } else {
307: final String id = StructureSink.linkToKey(name);
308: sink.rawText("id=\"" + id + "\"");
309: }
310: sink.rawText(">");
311: } else {
312: sink.anchor(name);
313: }
314: }
315:
316: private void writeTableHeaderCell(Sink sink, String width,
317: String styleClass) {
318: if (StringUtils.isNotEmpty(styleClass)
319: || StringUtils.isNotEmpty(width)) {
320: sink.rawText("<th ");
321:
322: if (StringUtils.isNotEmpty(styleClass)) {
323: sink.rawText(" class=\"" + styleClass + "\"");
324: }
325:
326: if (StringUtils.isNotEmpty(width)) {
327: sink.rawText("width=\"" + width + "\"");
328: }
329: sink.rawText(">");
330: } else {
331: sink.tableHeaderCell();
332: }
333: }
334:
335: private void writeTableCell(Sink sink, String width,
336: String styleClass) {
337: if (StringUtils.isNotEmpty(styleClass)
338: || StringUtils.isNotEmpty(width)) {
339: sink.rawText("<td ");
340:
341: if (StringUtils.isNotEmpty(styleClass)) {
342: sink.rawText(" class=\"" + styleClass + "\"");
343: }
344:
345: if (StringUtils.isNotEmpty(width)) {
346: sink.rawText("width=\"" + width + "\"");
347: }
348: sink.rawText(">");
349: } else {
350: sink.tableCell();
351: }
352: }
353: }
|