| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal.ide.dialogs; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| |
| import javax.xml.parsers.FactoryConfigurationError; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| /** |
| * A parser for the the welcome page |
| */ |
| public class WelcomeParser extends DefaultHandler { |
| private static final String TAG_WELCOME_PAGE = "welcomePage"; //$NON-NLS-1$ |
| |
| private static final String TAG_INTRO = "intro"; //$NON-NLS-1$ |
| |
| private static final String TAG_ITEM = "item"; //$NON-NLS-1$ |
| |
| private static final String TAG_BOLD = "b"; //$NON-NLS-1$ |
| |
| private static final String TAG_ACTION = "action"; //$NON-NLS-1$ |
| |
| private static final String TAG_PARAGRAPH = "p"; //$NON-NLS-1$ |
| |
| private static final String TAG_TOPIC = "topic"; //$NON-NLS-1$ |
| |
| private static final String ATT_TITLE = "title"; //$NON-NLS-1$ |
| |
| private static final String ATT_FORMAT = "format"; //$NON-NLS-1$ |
| |
| private static final String ATT_PLUGIN_ID = "pluginId"; //$NON-NLS-1$ |
| |
| private static final String ATT_CLASS = "class"; //$NON-NLS-1$ |
| |
| private static final String ATT_ID = "id"; //$NON-NLS-1$ |
| |
| private static final String ATT_HREF = "href"; //$NON-NLS-1$ |
| |
| private static final String FORMAT_WRAP = "wrap"; //$NON-NLS-1$ |
| |
| private static final char DELIMITER = '\n'; // sax parser replaces crlf with lf |
| |
| private SAXParser parser; |
| |
| private String title; |
| |
| private WelcomeItem introItem; |
| |
| private ArrayList items = new ArrayList(); |
| |
| private String format; |
| |
| private class WelcomeContentHandler implements ContentHandler { |
| protected ContentHandler parent; |
| |
| public void setParent(ContentHandler p) { |
| parent = p; |
| } |
| |
| public void characters(char[] ch, int start, int length) |
| throws SAXException { |
| } |
| |
| public void endDocument() throws SAXException { |
| } |
| |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| } |
| |
| public void ignorableWhitespace(char[] ch, int start, int length) |
| throws SAXException { |
| } |
| |
| public void processingInstruction(String target, String data) |
| throws SAXException { |
| } |
| |
| public void setDocumentLocator(Locator locator) { |
| } |
| |
| public void skippedEntity(String name) throws SAXException { |
| } |
| |
| public void startDocument() throws SAXException { |
| } |
| |
| public void startElement(String namespaceURI, String localName, |
| String qName, Attributes atts) throws SAXException { |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) |
| throws SAXException { |
| } |
| } |
| |
| private class WelcomePageHandler extends WelcomeContentHandler { |
| public WelcomePageHandler(String newTitle) { |
| title = newTitle; |
| } |
| |
| public void startElement(String namespaceURI, String localName, |
| String qName, Attributes atts) throws SAXException { |
| if (localName.equals(TAG_INTRO)) { |
| ItemHandler h = new IntroItemHandler(); |
| h.setParent(WelcomePageHandler.this); |
| parser.getXMLReader().setContentHandler(h); |
| } else if (localName.equals(TAG_ITEM)) { |
| ItemHandler h = new ItemHandler(); |
| h.setParent(WelcomePageHandler.this); |
| parser.getXMLReader().setContentHandler(h); |
| } |
| } |
| } |
| |
| private class ItemHandler extends WelcomeContentHandler { |
| private ArrayList boldRanges = new ArrayList(); |
| |
| protected ArrayList wrapRanges = new ArrayList(); |
| |
| private ArrayList actionRanges = new ArrayList(); |
| |
| private ArrayList pluginIds = new ArrayList(); |
| |
| private ArrayList classes = new ArrayList(); |
| |
| private ArrayList helpRanges = new ArrayList(); |
| |
| private ArrayList helpIds = new ArrayList(); |
| |
| private ArrayList helpHrefs = new ArrayList(); |
| |
| private StringBuffer text = new StringBuffer(); |
| |
| protected int offset = 0; |
| |
| protected int textStart; |
| |
| protected int wrapStart; |
| |
| private class BoldHandler extends WelcomeContentHandler { |
| public void characters(char[] ch, int start, int length) |
| throws SAXException { |
| ItemHandler.this.characters(ch, start, length); |
| } |
| |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| if (localName.equals(TAG_BOLD)) { |
| boldRanges.add(new int[] { textStart, offset - textStart }); |
| parser.getXMLReader().setContentHandler(parent); |
| } |
| } |
| } |
| |
| private class ActionHandler extends WelcomeContentHandler { |
| public ActionHandler(String pluginId, String className) { |
| pluginIds.add(pluginId); |
| classes.add(className); |
| } |
| |
| public void characters(char[] ch, int start, int length) |
| throws SAXException { |
| ItemHandler.this.characters(ch, start, length); |
| } |
| |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| if (localName.equals(TAG_ACTION)) { |
| actionRanges |
| .add(new int[] { textStart, offset - textStart }); |
| parser.getXMLReader().setContentHandler(parent); |
| } |
| } |
| } |
| |
| private class TopicHandler extends WelcomeContentHandler { |
| public TopicHandler(String helpId, String href) { |
| helpIds.add(helpId); |
| helpHrefs.add(href); |
| } |
| |
| public void characters(char[] ch, int start, int length) |
| throws SAXException { |
| ItemHandler.this.characters(ch, start, length); |
| } |
| |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| if (localName.equals(TAG_TOPIC)) { |
| helpRanges.add(new int[] { textStart, offset - textStart }); |
| parser.getXMLReader().setContentHandler(parent); |
| } |
| } |
| } |
| |
| protected WelcomeItem constructWelcomeItem() { |
| if (isFormatWrapped()) { |
| // replace all line delimiters with a space |
| for (int i = 0; i < wrapRanges.size(); i++) { |
| int[] range = (int[]) wrapRanges.get(i); |
| int start = range[0]; |
| int length = range[1]; |
| for (int j = start; j < start + length; j++) { |
| char ch = text.charAt(j); |
| if (ch == DELIMITER) { |
| text.replace(j, j + 1, " "); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| return new WelcomeItem( |
| text.toString(), |
| (int[][]) boldRanges.toArray(new int[boldRanges.size()][2]), |
| (int[][]) actionRanges |
| .toArray(new int[actionRanges.size()][2]), |
| (String[]) pluginIds.toArray(new String[pluginIds.size()]), |
| (String[]) classes.toArray(new String[classes.size()]), |
| (int[][]) helpRanges.toArray(new int[helpRanges.size()][2]), |
| (String[]) helpIds.toArray(new String[helpIds.size()]), |
| (String[]) helpHrefs.toArray(new String[helpHrefs.size()])); |
| } |
| |
| public void characters(char[] ch, int start, int length) |
| throws SAXException { |
| for (int i = 0; i < length; i++) { |
| text.append(ch[start + i]); |
| } |
| offset += length; |
| } |
| |
| public void startElement(String namespaceURI, String localName, |
| String qName, Attributes atts) throws SAXException { |
| textStart = offset; |
| if (localName.equals(TAG_BOLD)) { |
| BoldHandler h = new BoldHandler(); |
| h.setParent(ItemHandler.this); |
| parser.getXMLReader().setContentHandler(h); |
| } else if (localName.equals(TAG_ACTION)) { |
| ActionHandler h = new ActionHandler(atts |
| .getValue(ATT_PLUGIN_ID), atts.getValue(ATT_CLASS)); |
| h.setParent(ItemHandler.this); |
| parser.getXMLReader().setContentHandler(h); |
| } else if (localName.equals(TAG_PARAGRAPH)) { |
| wrapStart = textStart; |
| } else if (localName.equals(TAG_TOPIC)) { |
| TopicHandler h = new TopicHandler(atts.getValue(ATT_ID), atts |
| .getValue(ATT_HREF)); |
| h.setParent(ItemHandler.this); |
| parser.getXMLReader().setContentHandler(h); |
| } |
| } |
| |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| if (localName.equals(TAG_ITEM)) { |
| items.add(constructWelcomeItem()); |
| parser.getXMLReader().setContentHandler(parent); |
| } else if (localName.equals(TAG_PARAGRAPH)) { |
| wrapRanges.add(new int[] { wrapStart, offset - wrapStart }); |
| } |
| } |
| } |
| |
| private class IntroItemHandler extends ItemHandler { |
| public void endElement(String namespaceURI, String localName, |
| String qName) throws SAXException { |
| if (localName.equals(TAG_INTRO)) { |
| introItem = constructWelcomeItem(); |
| parser.getXMLReader().setContentHandler(parent); |
| } else if (localName.equals(TAG_PARAGRAPH)) { |
| wrapRanges.add(new int[] { wrapStart, offset - wrapStart }); |
| } |
| } |
| } |
| |
| /** |
| * Creates a new welcome parser. |
| */ |
| public WelcomeParser() throws ParserConfigurationException, SAXException, |
| FactoryConfigurationError { |
| super(); |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| factory.setFeature("http://xml.org/sax/features/namespaces", true); //$NON-NLS-1$ |
| parser = factory.newSAXParser(); |
| |
| parser.getXMLReader().setContentHandler(this); |
| parser.getXMLReader().setDTDHandler(this); |
| parser.getXMLReader().setEntityResolver(this); |
| parser.getXMLReader().setErrorHandler(this); |
| } |
| |
| /** |
| * Returns the intro item. |
| */ |
| public WelcomeItem getIntroItem() { |
| return introItem; |
| } |
| |
| /** |
| * Returns the items. |
| */ |
| public WelcomeItem[] getItems() { |
| return (WelcomeItem[]) items.toArray(new WelcomeItem[items.size()]); |
| } |
| |
| /** |
| * Returns the title |
| */ |
| public String getTitle() { |
| return title; |
| } |
| |
| /** |
| * Returns whether or not the welcome editor input should be wrapped. |
| */ |
| public boolean isFormatWrapped() { |
| return FORMAT_WRAP.equals(format); |
| } |
| |
| /** |
| * Parse the contents of the input stream |
| */ |
| public void parse(InputStream is) { |
| try { |
| parser.parse(new InputSource(is), this); |
| } catch (SAXException e) { |
| IStatus status = new Status(IStatus.ERROR, |
| IDEWorkbenchPlugin.IDE_WORKBENCH, 1, IDEWorkbenchMessages.WelcomeParser_parseException, e); |
| IDEWorkbenchPlugin.log(IDEWorkbenchMessages.WelcomeParser_parseError, status); |
| } catch (IOException e) { |
| IStatus status = new Status(IStatus.ERROR, |
| IDEWorkbenchPlugin.IDE_WORKBENCH, 1, IDEWorkbenchMessages.WelcomeParser_parseException, e); |
| IDEWorkbenchPlugin.log(IDEWorkbenchMessages.WelcomeParser_parseError, status); |
| } |
| } |
| |
| /** |
| * Handles the start element |
| */ |
| public void startElement(String namespaceURI, String localName, |
| String qName, Attributes atts) throws SAXException { |
| if (localName.equals(TAG_WELCOME_PAGE)) { |
| WelcomeContentHandler h = new WelcomePageHandler(atts |
| .getValue(ATT_TITLE)); |
| format = atts.getValue(ATT_FORMAT); |
| h.setParent(this); |
| parser.getXMLReader().setContentHandler(h); |
| } |
| } |
| } |