001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 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.pde.internal.core.plugin;
011:
012: import java.io.StringReader;
013: import java.util.Stack;
014:
015: import javax.xml.parsers.DocumentBuilderFactory;
016: import javax.xml.parsers.ParserConfigurationException;
017:
018: import org.eclipse.pde.internal.core.util.IdUtil;
019: import org.w3c.dom.DOMException;
020: import org.w3c.dom.Document;
021: import org.w3c.dom.Element;
022: import org.w3c.dom.Node;
023: import org.w3c.dom.Text;
024: import org.xml.sax.Attributes;
025: import org.xml.sax.InputSource;
026: import org.xml.sax.Locator;
027: import org.xml.sax.SAXException;
028: import org.xml.sax.helpers.DefaultHandler;
029:
030: public class PluginHandler extends DefaultHandler {
031: private Document fDocument;
032: private Element fRootElement;
033: private Stack fOpenElements = new Stack();
034:
035: private String fSchemaVersion;
036: private boolean fAbbreviated;
037: private Locator fLocator;
038: private boolean fPop;
039:
040: public PluginHandler(boolean abbreviated) {
041: fAbbreviated = abbreviated;
042: }
043:
044: public void startElement(String uri, String localName,
045: String qName, Attributes attributes) throws SAXException {
046:
047: fPop = true;
048:
049: if (fAbbreviated && fOpenElements.size() == 2) {
050: Element parent = (Element) fOpenElements.peek();
051: if (parent.getNodeName().equals("extension") && !isInterestingExtension((Element) fOpenElements.peek())) { //$NON-NLS-1$
052: fPop = false;
053: return;
054: }
055: }
056:
057: Element element = fDocument.createElement(qName);
058: for (int i = 0; i < attributes.getLength(); i++) {
059: element.setAttribute(attributes.getQName(i), attributes
060: .getValue(i));
061: if ("extension".equals(qName) || "extension-point".equals(qName)) { //$NON-NLS-1$ //$NON-NLS-2$
062: element
063: .setAttribute(
064: "line", Integer.toString(fLocator.getLineNumber())); //$NON-NLS-1$
065: }
066: }
067:
068: if (fRootElement == null)
069: fRootElement = element;
070: else
071: ((Element) fOpenElements.peek()).appendChild(element);
072:
073: fOpenElements.push(element);
074: }
075:
076: protected boolean isInterestingExtension(Element element) {
077: String point = element.getAttribute("point"); //$NON-NLS-1$
078: return IdUtil.isInterestingExtensionPoint(point);
079: }
080:
081: public void endElement(String uri, String localName, String qName)
082: throws SAXException {
083: if (fPop
084: || (qName.equals("extension") && fOpenElements.size() == 2)) { //$NON-NLS-1$
085: fOpenElements.pop();
086: }
087: }
088:
089: /* (non-Javadoc)
090: * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
091: */
092: public void setDocumentLocator(Locator locator) {
093: fLocator = locator;
094: }
095:
096: /* (non-Javadoc)
097: * @see org.xml.sax.helpers.DefaultHandler#startDocument()
098: */
099: public void startDocument() throws SAXException {
100: DocumentBuilderFactory factory = DocumentBuilderFactory
101: .newInstance();
102: try {
103: fDocument = factory.newDocumentBuilder().newDocument();
104: } catch (ParserConfigurationException e) {
105: }
106: }
107:
108: /* (non-Javadoc)
109: * @see org.xml.sax.helpers.DefaultHandler#endDocument()
110: */
111: public void endDocument() throws SAXException {
112: fDocument.appendChild(fRootElement);
113: }
114:
115: /* (non-Javadoc)
116: * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, java.lang.String)
117: */
118: public void processingInstruction(String target, String data)
119: throws SAXException {
120: if ("eclipse".equals(target)) { //$NON-NLS-1$
121: fSchemaVersion = "version=\"3.0\"".equals(data) ? "3.0" : "3.2"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
122: }
123: }
124:
125: /* (non-Javadoc)
126: * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
127: */
128: public void characters(char[] characters, int start, int length)
129: throws SAXException {
130: if (fAbbreviated)
131: return;
132:
133: processCharacters(characters, start, length);
134: }
135:
136: /**
137: * @param characters
138: * @param start
139: * @param length
140: * @throws DOMException
141: */
142: protected void processCharacters(char[] characters, int start,
143: int length) throws DOMException {
144: StringBuffer buff = new StringBuffer();
145: for (int i = 0; i < length; i++) {
146: buff.append(characters[start + i]);
147: }
148: Text text = fDocument.createTextNode(buff.toString());
149: if (fRootElement == null)
150: fDocument.appendChild(text);
151: else
152: ((Element) fOpenElements.peek()).appendChild(text);
153: }
154:
155: public Node getDocumentElement() {
156: if (fRootElement != null) {
157: fRootElement.normalize();
158: }
159: return fRootElement;
160: }
161:
162: public String getSchemaVersion() {
163: return fSchemaVersion;
164: }
165:
166: public InputSource resolveEntity(String publicId, String systemId)
167: throws SAXException {
168: // Prevent the resolution of external entities in order to
169: // prevent the parser from accessing the Internet
170: // This will prevent huge workbench performance degradations and hangs
171: return new InputSource(new StringReader("")); //$NON-NLS-1$
172: }
173:
174: }
|