001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.projectimport.eclipse;
043:
044: import java.io.BufferedInputStream;
045: import java.io.File;
046: import java.io.FileInputStream;
047: import java.io.FileNotFoundException;
048: import java.io.IOException;
049: import java.io.InputStream;
050: import java.io.StringReader;
051: import org.netbeans.modules.projectimport.ProjectImporterException;
052: import org.openide.ErrorManager;
053: import org.openide.xml.XMLUtil;
054: import org.xml.sax.Attributes;
055: import org.xml.sax.InputSource;
056: import org.xml.sax.SAXException;
057: import org.xml.sax.SAXParseException;
058: import org.xml.sax.XMLReader;
059: import org.xml.sax.helpers.DefaultHandler;
060:
061: /**
062: * Parses a content of the .classpath file.
063: *
064: * @author mkrauskopf
065: */
066: final class ClassPathParser extends DefaultHandler {
067:
068: // elements names
069: private static final String CLASSPATH = "classpath"; // NOI18N
070: private static final String CLASSPATH_ENTRY = "classpathentry"; // NOI18N
071: private static final String ATTRIBUTES = "attributes"; // NOI18N
072: private static final String ATTRIBUTE = "attribute"; // NOI18N
073: private static final String ACCESSRULES = "accessrules"; // NOI18N
074: private static final String ACCESSRULE = "accessrule"; // NOI18N
075:
076: // attributes names
077: private static final String KIND_ATTR = "kind"; // NOI18N
078: private static final String PATH_ATTR = "path"; // NOI18N
079:
080: // indicates current position in a xml document
081: private static final int POSITION_NONE = 0;
082: private static final int POSITION_CLASSPATH = 1;
083: private static final int POSITION_CLASSPATH_ENTRY = 2;
084: private static final int POSITION_ATTRIBUTES = 3;
085: private static final int POSITION_ATTRIBUTE = 4;
086: private static final int POSITION_ACCESSRULES = 5;
087: private static final int POSITION_ACCESSRULE = 6;
088:
089: private int position = POSITION_NONE;
090: private StringBuffer chars;
091:
092: private ClassPath classPath;
093:
094: private ClassPathParser() {/* emtpy constructor */
095: }
096:
097: /**
098: * Returns classpath content from a project's .classpath file.
099: *
100: * @param classPathFile the .classpath file
101: */
102: static ClassPath parse(File classPathFile)
103: throws ProjectImporterException {
104:
105: ClassPathParser parser = new ClassPathParser();
106: InputStream classPathIS = null;
107: try {
108: classPathIS = new BufferedInputStream(new FileInputStream(
109: classPathFile));
110: parser.load(new InputSource(classPathIS));
111: } catch (FileNotFoundException e) {
112: throw new ProjectImporterException(e);
113: } finally {
114: if (classPathIS != null) {
115: try {
116: classPathIS.close();
117: } catch (IOException e) {
118: ErrorManager.getDefault().log(ErrorManager.WARNING,
119: "Unable to close classPathStream: " + e); // NOI18N
120: }
121: }
122: }
123: return parser.classPath;
124: }
125:
126: /**
127: * Returns classpath content as it is represented in the project's
128: * .classpath file.
129: *
130: * @param classPath string as it is in the .classpath file
131: */
132: static ClassPath parse(String classPath)
133: throws ProjectImporterException {
134: ClassPathParser parser = new ClassPathParser();
135: parser.load(new InputSource(new StringReader(classPath)));
136: return parser.classPath;
137: }
138:
139: /** Parses a given InputSource and fills up a EclipseProject */
140: private void load(InputSource projectIS)
141: throws ProjectImporterException {
142: try {
143: /* parser creation */
144: XMLReader reader = XMLUtil.createXMLReader(false, true);
145: reader.setContentHandler(this );
146: reader.setErrorHandler(this );
147: chars = new StringBuffer(); // initialization
148: reader.parse(projectIS); // start parsing
149: } catch (IOException e) {
150: throw new ProjectImporterException(e);
151: } catch (SAXException e) {
152: throw new ProjectImporterException(e);
153: }
154: }
155:
156: public void characters(char ch[], int offset, int length)
157: throws SAXException {
158: chars.append(ch, offset, length);
159: }
160:
161: public void startElement(String uri, String localName,
162: String qName, Attributes attributes) throws SAXException {
163:
164: chars.setLength(0);
165: switch (position) {
166: case POSITION_NONE:
167: if (localName.equals(CLASSPATH)) {
168: position = POSITION_CLASSPATH;
169: classPath = new ClassPath();
170: } else {
171: unknownElementReached(position, localName);
172: }
173: break;
174: case POSITION_CLASSPATH:
175: if (localName.equals(CLASSPATH_ENTRY)) {
176: ClassPathEntry entry = new ClassPathEntry(attributes
177: .getValue(KIND_ATTR), attributes
178: .getValue(PATH_ATTR));
179: classPath.addEntry(entry);
180: position = POSITION_CLASSPATH_ENTRY;
181: } else {
182: unknownElementReached(position, localName);
183: }
184: break;
185: case POSITION_CLASSPATH_ENTRY:
186: if (localName.equals(ATTRIBUTES)) {
187: // ignored in the meantime - prepared for future
188: // (probably since elicpse 3.1M6 - see #57661)
189: position = POSITION_ATTRIBUTES;
190: } else if (localName.equals(ACCESSRULES)) {
191: // ignored in the meantime - prepared for future
192: position = POSITION_ACCESSRULES;
193: } else {
194: unknownElementReached(position, localName);
195: }
196: break;
197: case POSITION_ATTRIBUTES:
198: if (localName.equals(ATTRIBUTE)) {
199: // ignored in the meantime - prepared for future
200: // (probably since elicpse 3.1M6 - see #57661)
201: position = POSITION_ATTRIBUTE;
202: } else {
203: unknownElementReached(position, localName);
204: }
205: break;
206: case POSITION_ACCESSRULES:
207: if (localName.equals(ACCESSRULE)) {
208: // ignored in the meantime - prepared for future
209: position = POSITION_ACCESSRULE;
210: } else {
211: unknownElementReached(position, localName);
212: }
213: break;
214: default:
215: unknownElementReached(position, localName);
216: }
217: }
218:
219: private void unknownElementReached(int position, String localName)
220: throws SAXException {
221: throw new SAXException("Unknown element reached: " + // NOI18N
222: "position: " + position + ", element: " + localName); // NOI18N
223: }
224:
225: public void endElement(String uri, String localName, String qName)
226: throws SAXException {
227: switch (position) {
228: case POSITION_CLASSPATH:
229: // parsing ends
230: position = POSITION_NONE;
231: break;
232: case POSITION_CLASSPATH_ENTRY:
233: position = POSITION_CLASSPATH;
234: break;
235: case POSITION_ATTRIBUTES:
236: position = POSITION_CLASSPATH_ENTRY;
237: break;
238: case POSITION_ATTRIBUTE:
239: position = POSITION_ATTRIBUTES;
240: break;
241: case POSITION_ACCESSRULES:
242: position = POSITION_CLASSPATH_ENTRY;
243: break;
244: case POSITION_ACCESSRULE:
245: position = POSITION_ACCESSRULES;
246: break;
247: default:
248: ErrorManager.getDefault().log(
249: ErrorManager.WARNING,
250: "Unknown state reached in ClassPathParser, "
251: + // NOI18N
252: "position: " + position + ", element: "
253: + localName); // NOI18N
254: }
255: chars.setLength(0);
256: }
257:
258: public void warning(SAXParseException e) throws SAXException {
259: ErrorManager.getDefault().log(ErrorManager.WARNING,
260: "Warning occurred: " + e);
261: }
262:
263: public void error(SAXParseException e) throws SAXException {
264: ErrorManager.getDefault().log(ErrorManager.WARNING,
265: "Error occurred: " + e);
266: throw e;
267: }
268:
269: public void fatalError(SAXParseException e) throws SAXException {
270: ErrorManager.getDefault().log(ErrorManager.WARNING,
271: "Fatal error occurred: " + e);
272: throw e;
273: }
274:
275: }
|