| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package flex2.compiler.util; |
| |
| import flex2.compiler.io.VirtualFile; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| import java.io.BufferedInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| /** |
| * Parses a manifest into a NameMappings. |
| * |
| */ |
| public class ManifestParser |
| { |
| public synchronized static void parse(String namespaceURI, VirtualFile file, NameMappings mappings) |
| { |
| if (file == null) |
| { |
| return; |
| } |
| |
| InputStream in = null; |
| |
| try |
| { |
| in = new BufferedInputStream(file.getInputStream()); |
| } |
| catch (FileNotFoundException ex) |
| { |
| // manifest is not found. |
| return; |
| } |
| catch (IOException ex) |
| { |
| ThreadLocalToolkit.logError(file.getNameForReporting(), ex.getMessage()); |
| return; |
| } |
| |
| try |
| { |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| factory.setNamespaceAware(true); |
| SAXParser parser = factory.newSAXParser(); |
| parser.parse(in, new Parser(file.getName(), mappings, namespaceURI)); |
| } |
| catch (Exception ex) // ParserConfigurationException, SAXException, IOException |
| { |
| ThreadLocalToolkit.logError(file.getNameForReporting(), ex.getMessage()); |
| } |
| finally |
| { |
| if (in != null) |
| { |
| try |
| { |
| in.close(); |
| } |
| catch (IOException ex) |
| { |
| } |
| } |
| } |
| } |
| |
| private static class Parser extends DefaultHandler |
| { |
| Parser(String fileName, NameMappings mappings, String namespaceURI) |
| { |
| this.fileName = fileName; |
| this.mappings = mappings; |
| this.namespaceURI = namespaceURI; |
| } |
| |
| private String fileName; |
| private NameMappings mappings; |
| private String namespaceURI; |
| private Locator locator; |
| |
| public void startElement(String uri, String localName, String qName, Attributes attributes) |
| throws SAXException |
| { |
| if (localName.equals("component")) |
| { |
| String id = attributes.getValue("id"); |
| String className = attributes.getValue("class"); |
| if (className == null) |
| { |
| ThreadLocalToolkit.log(new UndefinedClass(fileName, locator.getLineNumber(), id)); |
| return; |
| } |
| else if ("*".equals(className)) |
| { |
| ThreadLocalToolkit.log(new InvalidClassName(fileName, locator.getLineNumber(), id)); |
| } |
| else |
| { |
| assert className.indexOf(':') == -1 && className.indexOf('/') == -1 : fileName + ": " + className; |
| className = NameFormatter.toColon(className); |
| } |
| |
| if (id == null) |
| { |
| id = NameFormatter.retrieveClassName(className); |
| } |
| |
| String lookupOnlyStr = attributes.getValue("lookupOnly"); |
| boolean lookupOnly = lookupOnlyStr == null ? false : Boolean.valueOf(lookupOnlyStr).booleanValue(); |
| |
| boolean added = mappings.addClass(namespaceURI, id, className); |
| |
| if (! added) |
| { |
| ThreadLocalToolkit.log(new DuplicateComponentDefinition(fileName, locator.getLineNumber(), id)); |
| return; |
| } |
| |
| if (lookupOnly) |
| { |
| mappings.addLookupOnly(namespaceURI, className); |
| } |
| } |
| } |
| |
| public void warning(SAXParseException e) |
| { |
| ThreadLocalToolkit.log(new ManifestError(fileName, e.getLineNumber(), e.getMessage())); |
| } |
| |
| public void error(SAXParseException e) |
| { |
| ThreadLocalToolkit.log(new ManifestError(fileName, e.getLineNumber(), e.getMessage())); |
| } |
| |
| public void fatalError(SAXParseException e) |
| throws SAXParseException |
| { |
| ThreadLocalToolkit.log(new ManifestError(fileName, e.getLineNumber(), e.getMessage())); |
| throw e; |
| } |
| |
| public void setDocumentLocator(Locator locator) |
| { |
| this.locator = locator; |
| } |
| } |
| |
| // error messages |
| |
| public static class UndefinedClass extends CompilerMessage.CompilerError |
| { |
| private static final long serialVersionUID = 982393613817885400L; |
| public UndefinedClass(String fileName, int line, String tag) |
| { |
| super(); |
| this.fileName = fileName; |
| this.line = line; |
| this.tag = tag; |
| } |
| |
| public final String fileName; |
| public final int line; |
| public final String tag; |
| } |
| |
| public static class InvalidClassName extends CompilerMessage.CompilerError |
| { |
| private static final long serialVersionUID = -1805088670961745449L; |
| public InvalidClassName(String fileName, int line, String tag) |
| { |
| super(); |
| this.fileName = fileName; |
| this.line = line; |
| this.tag = tag; |
| } |
| |
| public final String fileName; |
| public final int line; |
| public final String tag; |
| } |
| |
| public static class DuplicateComponentDefinition extends CompilerMessage.CompilerError |
| { |
| private static final long serialVersionUID = -1072579721984054648L; |
| public DuplicateComponentDefinition(String fileName, int line, String tag) |
| { |
| super(); |
| this.fileName = fileName; |
| this.line = line; |
| this.tag = tag; |
| } |
| |
| public final String fileName; |
| public final int line; |
| public final String tag; |
| } |
| |
| public static class ManifestError extends CompilerMessage.CompilerError |
| { |
| private static final long serialVersionUID = 7519143031979293680L; |
| public ManifestError(String fileName, int line, String message) |
| { |
| super(); |
| this.fileName = fileName; |
| this.line = line; |
| this.message = message; |
| } |
| |
| public final String fileName; |
| public final int line; |
| public final String message; |
| } |
| } |