001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.ide.dialogs;
011:
012: import java.io.IOException;
013: import java.io.InputStream;
014: import java.util.ArrayList;
015:
016: import javax.xml.parsers.FactoryConfigurationError;
017: import javax.xml.parsers.ParserConfigurationException;
018: import javax.xml.parsers.SAXParser;
019: import javax.xml.parsers.SAXParserFactory;
020:
021: import org.eclipse.core.runtime.IStatus;
022: import org.eclipse.core.runtime.Status;
023: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
024: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
025: import org.xml.sax.Attributes;
026: import org.xml.sax.ContentHandler;
027: import org.xml.sax.InputSource;
028: import org.xml.sax.Locator;
029: import org.xml.sax.SAXException;
030: import org.xml.sax.helpers.DefaultHandler;
031:
032: /**
033: * A parser for the the welcome page
034: */
035: public class WelcomeParser extends DefaultHandler {
036: private static final String TAG_WELCOME_PAGE = "welcomePage"; //$NON-NLS-1$
037:
038: private static final String TAG_INTRO = "intro"; //$NON-NLS-1$
039:
040: private static final String TAG_ITEM = "item"; //$NON-NLS-1$
041:
042: private static final String TAG_BOLD = "b"; //$NON-NLS-1$
043:
044: private static final String TAG_ACTION = "action"; //$NON-NLS-1$
045:
046: private static final String TAG_PARAGRAPH = "p"; //$NON-NLS-1$
047:
048: private static final String TAG_TOPIC = "topic"; //$NON-NLS-1$
049:
050: private static final String ATT_TITLE = "title"; //$NON-NLS-1$
051:
052: private static final String ATT_FORMAT = "format"; //$NON-NLS-1$
053:
054: private static final String ATT_PLUGIN_ID = "pluginId"; //$NON-NLS-1$
055:
056: private static final String ATT_CLASS = "class"; //$NON-NLS-1$
057:
058: private static final String ATT_ID = "id"; //$NON-NLS-1$
059:
060: private static final String ATT_HREF = "href"; //$NON-NLS-1$
061:
062: private static final String FORMAT_WRAP = "wrap"; //$NON-NLS-1$
063:
064: private static final char DELIMITER = '\n'; // sax parser replaces crlf with lf
065:
066: private SAXParser parser;
067:
068: private String title;
069:
070: private WelcomeItem introItem;
071:
072: private ArrayList items = new ArrayList();
073:
074: private String format;
075:
076: private class WelcomeContentHandler implements ContentHandler {
077: protected ContentHandler parent;
078:
079: public void setParent(ContentHandler p) {
080: parent = p;
081: }
082:
083: public void characters(char[] ch, int start, int length)
084: throws SAXException {
085: }
086:
087: public void endDocument() throws SAXException {
088: }
089:
090: public void endElement(String namespaceURI, String localName,
091: String qName) throws SAXException {
092: }
093:
094: public void endPrefixMapping(String prefix) throws SAXException {
095: }
096:
097: public void ignorableWhitespace(char[] ch, int start, int length)
098: throws SAXException {
099: }
100:
101: public void processingInstruction(String target, String data)
102: throws SAXException {
103: }
104:
105: public void setDocumentLocator(Locator locator) {
106: }
107:
108: public void skippedEntity(String name) throws SAXException {
109: }
110:
111: public void startDocument() throws SAXException {
112: }
113:
114: public void startElement(String namespaceURI, String localName,
115: String qName, Attributes atts) throws SAXException {
116: }
117:
118: public void startPrefixMapping(String prefix, String uri)
119: throws SAXException {
120: }
121: }
122:
123: private class WelcomePageHandler extends WelcomeContentHandler {
124: public WelcomePageHandler(String newTitle) {
125: title = newTitle;
126: }
127:
128: public void startElement(String namespaceURI, String localName,
129: String qName, Attributes atts) throws SAXException {
130: if (localName.equals(TAG_INTRO)) {
131: ItemHandler h = new IntroItemHandler();
132: h.setParent(WelcomePageHandler.this );
133: parser.getXMLReader().setContentHandler(h);
134: } else if (localName.equals(TAG_ITEM)) {
135: ItemHandler h = new ItemHandler();
136: h.setParent(WelcomePageHandler.this );
137: parser.getXMLReader().setContentHandler(h);
138: }
139: }
140: }
141:
142: private class ItemHandler extends WelcomeContentHandler {
143: private ArrayList boldRanges = new ArrayList();
144:
145: protected ArrayList wrapRanges = new ArrayList();
146:
147: private ArrayList actionRanges = new ArrayList();
148:
149: private ArrayList pluginIds = new ArrayList();
150:
151: private ArrayList classes = new ArrayList();
152:
153: private ArrayList helpRanges = new ArrayList();
154:
155: private ArrayList helpIds = new ArrayList();
156:
157: private ArrayList helpHrefs = new ArrayList();
158:
159: private StringBuffer text = new StringBuffer();
160:
161: protected int offset = 0;
162:
163: protected int textStart;
164:
165: protected int wrapStart;
166:
167: private class BoldHandler extends WelcomeContentHandler {
168: public void characters(char[] ch, int start, int length)
169: throws SAXException {
170: ItemHandler.this .characters(ch, start, length);
171: }
172:
173: public void endElement(String namespaceURI,
174: String localName, String qName) throws SAXException {
175: if (localName.equals(TAG_BOLD)) {
176: boldRanges.add(new int[] { textStart,
177: offset - textStart });
178: parser.getXMLReader().setContentHandler(parent);
179: }
180: }
181: }
182:
183: private class ActionHandler extends WelcomeContentHandler {
184: public ActionHandler(String pluginId, String className) {
185: pluginIds.add(pluginId);
186: classes.add(className);
187: }
188:
189: public void characters(char[] ch, int start, int length)
190: throws SAXException {
191: ItemHandler.this .characters(ch, start, length);
192: }
193:
194: public void endElement(String namespaceURI,
195: String localName, String qName) throws SAXException {
196: if (localName.equals(TAG_ACTION)) {
197: actionRanges.add(new int[] { textStart,
198: offset - textStart });
199: parser.getXMLReader().setContentHandler(parent);
200: }
201: }
202: }
203:
204: private class TopicHandler extends WelcomeContentHandler {
205: public TopicHandler(String helpId, String href) {
206: helpIds.add(helpId);
207: helpHrefs.add(href);
208: }
209:
210: public void characters(char[] ch, int start, int length)
211: throws SAXException {
212: ItemHandler.this .characters(ch, start, length);
213: }
214:
215: public void endElement(String namespaceURI,
216: String localName, String qName) throws SAXException {
217: if (localName.equals(TAG_TOPIC)) {
218: helpRanges.add(new int[] { textStart,
219: offset - textStart });
220: parser.getXMLReader().setContentHandler(parent);
221: }
222: }
223: }
224:
225: protected WelcomeItem constructWelcomeItem() {
226: if (isFormatWrapped()) {
227: // replace all line delimiters with a space
228: for (int i = 0; i < wrapRanges.size(); i++) {
229: int[] range = (int[]) wrapRanges.get(i);
230: int start = range[0];
231: int length = range[1];
232: for (int j = start; j < start + length; j++) {
233: char ch = text.charAt(j);
234: if (ch == DELIMITER) {
235: text.replace(j, j + 1, " "); //$NON-NLS-1$
236: }
237: }
238: }
239: }
240: return new WelcomeItem(text.toString(),
241: (int[][]) boldRanges.toArray(new int[boldRanges
242: .size()][2]), (int[][]) actionRanges
243: .toArray(new int[actionRanges.size()][2]),
244: (String[]) pluginIds.toArray(new String[pluginIds
245: .size()]), (String[]) classes
246: .toArray(new String[classes.size()]),
247: (int[][]) helpRanges.toArray(new int[helpRanges
248: .size()][2]), (String[]) helpIds
249: .toArray(new String[helpIds.size()]),
250: (String[]) helpHrefs.toArray(new String[helpHrefs
251: .size()]));
252: }
253:
254: public void characters(char[] ch, int start, int length)
255: throws SAXException {
256: for (int i = 0; i < length; i++) {
257: text.append(ch[start + i]);
258: }
259: offset += length;
260: }
261:
262: public void startElement(String namespaceURI, String localName,
263: String qName, Attributes atts) throws SAXException {
264: textStart = offset;
265: if (localName.equals(TAG_BOLD)) {
266: BoldHandler h = new BoldHandler();
267: h.setParent(ItemHandler.this );
268: parser.getXMLReader().setContentHandler(h);
269: } else if (localName.equals(TAG_ACTION)) {
270: ActionHandler h = new ActionHandler(atts
271: .getValue(ATT_PLUGIN_ID), atts
272: .getValue(ATT_CLASS));
273: h.setParent(ItemHandler.this );
274: parser.getXMLReader().setContentHandler(h);
275: } else if (localName.equals(TAG_PARAGRAPH)) {
276: wrapStart = textStart;
277: } else if (localName.equals(TAG_TOPIC)) {
278: TopicHandler h = new TopicHandler(
279: atts.getValue(ATT_ID), atts.getValue(ATT_HREF));
280: h.setParent(ItemHandler.this );
281: parser.getXMLReader().setContentHandler(h);
282: }
283: }
284:
285: public void endElement(String namespaceURI, String localName,
286: String qName) throws SAXException {
287: if (localName.equals(TAG_ITEM)) {
288: items.add(constructWelcomeItem());
289: parser.getXMLReader().setContentHandler(parent);
290: } else if (localName.equals(TAG_PARAGRAPH)) {
291: wrapRanges.add(new int[] { wrapStart,
292: offset - wrapStart });
293: }
294: }
295: }
296:
297: private class IntroItemHandler extends ItemHandler {
298: public void endElement(String namespaceURI, String localName,
299: String qName) throws SAXException {
300: if (localName.equals(TAG_INTRO)) {
301: introItem = constructWelcomeItem();
302: parser.getXMLReader().setContentHandler(parent);
303: } else if (localName.equals(TAG_PARAGRAPH)) {
304: wrapRanges.add(new int[] { wrapStart,
305: offset - wrapStart });
306: }
307: }
308: }
309:
310: /**
311: * Creates a new welcome parser.
312: */
313: public WelcomeParser() throws ParserConfigurationException,
314: SAXException, FactoryConfigurationError {
315: super ();
316: SAXParserFactory factory = SAXParserFactory.newInstance();
317: factory.setFeature(
318: "http://xml.org/sax/features/namespaces", true); //$NON-NLS-1$
319: parser = factory.newSAXParser();
320:
321: parser.getXMLReader().setContentHandler(this );
322: parser.getXMLReader().setDTDHandler(this );
323: parser.getXMLReader().setEntityResolver(this );
324: parser.getXMLReader().setErrorHandler(this );
325: }
326:
327: /**
328: * Returns the intro item.
329: */
330: public WelcomeItem getIntroItem() {
331: return introItem;
332: }
333:
334: /**
335: * Returns the items.
336: */
337: public WelcomeItem[] getItems() {
338: return (WelcomeItem[]) items.toArray(new WelcomeItem[items
339: .size()]);
340: }
341:
342: /**
343: * Returns the title
344: */
345: public String getTitle() {
346: return title;
347: }
348:
349: /**
350: * Returns whether or not the welcome editor input should be wrapped.
351: */
352: public boolean isFormatWrapped() {
353: return FORMAT_WRAP.equals(format);
354: }
355:
356: /**
357: * Parse the contents of the input stream
358: */
359: public void parse(InputStream is) {
360: try {
361: parser.parse(new InputSource(is), this );
362: } catch (SAXException e) {
363: IStatus status = new Status(IStatus.ERROR,
364: IDEWorkbenchPlugin.IDE_WORKBENCH, 1,
365: IDEWorkbenchMessages.WelcomeParser_parseException,
366: e);
367: IDEWorkbenchPlugin.log(
368: IDEWorkbenchMessages.WelcomeParser_parseError,
369: status);
370: } catch (IOException e) {
371: IStatus status = new Status(IStatus.ERROR,
372: IDEWorkbenchPlugin.IDE_WORKBENCH, 1,
373: IDEWorkbenchMessages.WelcomeParser_parseException,
374: e);
375: IDEWorkbenchPlugin.log(
376: IDEWorkbenchMessages.WelcomeParser_parseError,
377: status);
378: }
379: }
380:
381: /**
382: * Handles the start element
383: */
384: public void startElement(String namespaceURI, String localName,
385: String qName, Attributes atts) throws SAXException {
386: if (localName.equals(TAG_WELCOME_PAGE)) {
387: WelcomeContentHandler h = new WelcomePageHandler(atts
388: .getValue(ATT_TITLE));
389: format = atts.getValue(ATT_FORMAT);
390: h.setParent(this);
391: parser.getXMLReader().setContentHandler(h);
392: }
393: }
394: }
|