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-2006 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.IOException;
045: import java.io.StringReader;
046: import java.util.HashMap;
047: import java.util.Map;
048: import java.util.logging.Logger;
049: import org.netbeans.modules.projectimport.LoggerFactory;
050: import org.openide.ErrorManager;
051: import org.xml.sax.Attributes;
052: import org.xml.sax.InputSource;
053: import org.xml.sax.SAXException;
054: import org.xml.sax.SAXParseException;
055: import org.xml.sax.helpers.DefaultHandler;
056: import org.netbeans.modules.projectimport.ProjectImporterException;
057: import org.openide.xml.XMLUtil;
058: import org.xml.sax.XMLReader;
059:
060: /**
061: * Parses default JRE containers from Eclipse workspace.
062: *
063: * @author mkrauskopf
064: */
065: final class PreferredVMParser extends DefaultHandler {
066:
067: /** Logger for this class. */
068: private static final Logger logger = LoggerFactory.getDefault()
069: .createLogger(PreferredVMParser.class);
070:
071: // elements names
072: private static final String VM_SETTINGS = "vmSettings"; // NOI18N
073: private static final String VM_TYPE = "vmType"; // NOI18N
074: private static final String VM = "vm"; // NOI18N
075: private static final String LIBRARY_LOCATIONS = "libraryLocations"; // NOI18N
076: private static final String LIBRARY_LOCATION = "libraryLocation"; // NOI18N
077:
078: // attributes names
079: private static final String DEFAULT_VM_ATTR = "defaultVM"; // NOI18N
080: private static final String ID_ATTR = "id"; // NOI18N
081: private static final String NAME_ATTR = "name"; // NOI18N
082: private static final String PATH_ATTR = "path"; // NOI18N
083:
084: // indicates current position in a xml document
085: private static final int POSITION_NONE = 0;
086: private static final int POSITION_VM_SETTINGS = 1;
087: private static final int POSITION_VM_TYPE = 2;
088: private static final int POSITION_VM = 3;
089: private static final int POSITION_LIBRARY_LOCATIONS = 4;
090: private static final int POSITION_LIBRARY_LOCATION = 5;
091:
092: private int position = POSITION_NONE;
093: private StringBuffer chars;
094: private String defaultId;
095:
096: private Map jdks;
097:
098: private PreferredVMParser() {/* emtpy constructor */
099: }
100:
101: /** Returns vmMap of JDKs */
102: static Map parse(String vmXML) throws ProjectImporterException {
103: PreferredVMParser parser = new PreferredVMParser();
104: parser.load(new InputSource(new StringReader(vmXML)));
105: return parser.jdks;
106: }
107:
108: /** Parses a given InputSource and fills up jdk vmMap */
109: private void load(InputSource vmXMLIS)
110: throws ProjectImporterException {
111: try {
112: XMLReader reader = XMLUtil.createXMLReader(false, true);
113: reader.setContentHandler(this );
114: reader.setErrorHandler(this );
115: chars = new StringBuffer(); // initialization
116: reader.parse(vmXMLIS); // start parsing
117: } catch (IOException e) {
118: throw new ProjectImporterException(e);
119: } catch (SAXException e) {
120: throw new ProjectImporterException(e);
121: }
122: }
123:
124: public void characters(char ch[], int offset, int length)
125: throws SAXException {
126: chars.append(ch, offset, length);
127: }
128:
129: public void startElement(String uri, String localName,
130: String qName, Attributes attributes) throws SAXException {
131:
132: chars.setLength(0);
133: switch (position) {
134: case POSITION_NONE:
135: if (localName.equals(VM_SETTINGS)) {
136: position = POSITION_VM_SETTINGS;
137: // default vm id seems to be after the last comma
138: String defaultVMAttr = attributes
139: .getValue(DEFAULT_VM_ATTR);
140: defaultId = defaultVMAttr.substring(defaultVMAttr
141: .lastIndexOf(',') + 1);
142: jdks = new HashMap();
143: } else {
144: throw (new SAXException("First element has to be " // NOI18N
145: + VM_SETTINGS + ", but is " + localName)); // NOI18N
146: }
147: break;
148: case POSITION_VM_SETTINGS:
149: if (localName.equals(VM_TYPE)) {
150: position = POSITION_VM_TYPE;
151: }
152: break;
153: case POSITION_VM_TYPE:
154: if (localName.equals(VM)) {
155: position = POSITION_VM;
156: addJDK(attributes.getValue(ID_ATTR), attributes
157: .getValue(NAME_ATTR), attributes
158: .getValue(PATH_ATTR));
159: }
160: break;
161: case POSITION_VM:
162: if (localName.equals(LIBRARY_LOCATIONS)) {
163: position = POSITION_LIBRARY_LOCATIONS;
164: logger
165: .info("JRE used by your project presuambly contains additional jars. This is not supported (imported) yet. "
166: + // NOI18N
167: "CC yourself to issue http://www.netbeans.org/issues/show_bug.cgi?id=70733 to watch a progress."); // NOI18N
168: // XXX this means that additional jars were added to the
169: // JDK used by a project.
170: // See Preferences --> Java --> Installed JREs --> Choose
171: // JDK --> Edit --> Uncheck "Use default system libraries"
172: // --> Add External Jar
173: // Than take a look at .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs
174: }
175: break;
176: case POSITION_LIBRARY_LOCATIONS:
177: if (localName.equals(LIBRARY_LOCATION)) {
178: position = POSITION_LIBRARY_LOCATION;
179: // XXX See comment above - "case POSITION_VM"
180: }
181: break;
182: default:
183: throw (new SAXException("Unknown position reached: " // NOI18N
184: + position + " (element: " + localName + ")")); // NOI18N
185: }
186: }
187:
188: // XXX use array[x] array[x-1] or 1.5 enumerations(?) here and for similar
189: // cases or consider DOM
190: public void endElement(String uri, String localName, String qName)
191: throws SAXException {
192: switch (position) {
193: case POSITION_VM_SETTINGS:
194: // parsing ends
195: position = POSITION_NONE;
196: break;
197: case POSITION_VM_TYPE:
198: position = POSITION_VM_SETTINGS;
199: break;
200: case POSITION_VM:
201: position = POSITION_VM_TYPE;
202: break;
203: case POSITION_LIBRARY_LOCATIONS:
204: position = POSITION_VM;
205: break;
206: case POSITION_LIBRARY_LOCATION:
207: position = POSITION_LIBRARY_LOCATIONS;
208: break;
209: default:
210: ErrorManager.getDefault().log(ErrorManager.WARNING,
211: "Unknown state reached in ClassPathParser, " + // NOI18N
212: "position: " + position); // NOI18N
213: }
214: chars.setLength(0);
215: }
216:
217: public void error(SAXParseException e) throws SAXException {
218: ErrorManager.getDefault().log(ErrorManager.WARNING,
219: "Error occurres: " + e); // NOI18N
220: throw e;
221: }
222:
223: public void fatalError(SAXParseException e) throws SAXException {
224: ErrorManager.getDefault().log(ErrorManager.WARNING,
225: "Fatal error occurres: " + e); // NOI18N
226: throw e;
227: }
228:
229: private void addJDK(String id, String name, String value) {
230: if (id.equals(defaultId)) {
231: // put the default twice under two names. It seems that under some
232: // circumstances there is full name in .classpath con entry even
233: // if the currently used container is default one.
234: jdks.put(Workspace.DEFAULT_JRE_CONTAINER, value);
235: }
236: jdks.put(name, value);
237: }
238: }
|