Path: blob/master/sourcetools/objectmodel/com/ibm/j9tools/om/io/BuildSpecParser.java
6005 views
/*******************************************************************************1* Copyright (c) 2007, 2011 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package com.ibm.j9tools.om.io;2223import java.io.File;24import java.io.FileInputStream;25import java.io.IOException;26import java.io.InputStream;27import java.util.HashMap;28import java.util.Map;29import java.util.Vector;3031import org.xml.sax.Attributes;32import org.xml.sax.InputSource;33import org.xml.sax.SAXException;34import org.xml.sax.SAXParseException;3536import com.ibm.j9tools.om.AsmBuilder;37import com.ibm.j9tools.om.BuildSpec;38import com.ibm.j9tools.om.ConfigDirectory;39import com.ibm.j9tools.om.DefaultSizes;40import com.ibm.j9tools.om.Feature;41import com.ibm.j9tools.om.FeatureDefinition;42import com.ibm.j9tools.om.Flag;43import com.ibm.j9tools.om.FlagDefinition;44import com.ibm.j9tools.om.FlagDefinitions;45import com.ibm.j9tools.om.InvalidBuildSpecException;46import com.ibm.j9tools.om.JclConfiguration;47import com.ibm.j9tools.om.ObjectFactory;48import com.ibm.j9tools.om.Owner;49import com.ibm.j9tools.om.Property;50import com.ibm.j9tools.om.Source;5152/**53* Parses a build spec XML definition into a Java object.54*55* @author Maciek Klimkowski56* @author Gabriel Castro57*/58public class BuildSpecParser extends AbstractParser {59private final Map<String, FeatureDefinition> featureDefinitions = new HashMap<String, FeatureDefinition>();60private FlagDefinitions flagDefinitions;6162/** BuildSpec instance to be returned once parsed and initialized */63private BuildSpec _buildSpec = null;6465private Vector<Owner> _owners;66/** List of owners */67private Vector<Feature> _features;68/** List of features */69private Vector<Flag> _flags;70/** List of flags */71private Vector<Source> _sources;72/** List of sources */73private Vector<Property> _properties;7475/** List of properties */7677/**78* Parse passed input stream. Expects well formed XML adhering to the specified79* schema. This method should not be called directly but rather via {@link ObjectFactory#loadBuildSpec(File)}.80*81* @param input InputStream containing build spec XML to be parsed82* @return initialized instance of a BuildSpec83*84* @throws InvalidBuildSpecException85*/86public BuildSpec parse(InputStream input, String objectId, FlagDefinitions flagDefinitions, Map<String, FeatureDefinition> featureDefinitions) throws InvalidBuildSpecException, IOException {87this.featureDefinitions.putAll(featureDefinitions);88this.flagDefinitions = flagDefinitions;89_buildSpec = new BuildSpec();9091try {92_parser.getXMLReader().parse(new InputSource(input));93} catch (SAXException e) {94error(new SAXParseException(e.getMessage(), "", "", 0, 0)); //$NON-NLS-1$ //$NON-NLS-2$95} finally {96if (hasErrors() || hasWarnings()) {97throw new InvalidBuildSpecException(getErrors(), getWarnings(), objectId);98}99}100101return _buildSpec;102}103104/**105* Parses the specified file. This method should not be called directly but rather via106* {@link ObjectFactory#loadBuildSpec(File)}.107*108* @param file the file to be loaded109* @return A new instance of a BuildSpec110*111* @throws InvalidBuildSpecException if an error occured while parsing the build spec contained in <code>file</code>112*/113public BuildSpec parse(File file, FlagDefinitions flagDefinitions, Map<String, FeatureDefinition> featureDefinitions) throws InvalidBuildSpecException, IOException {114setDocumentLocatorFile(file);115116FileInputStream fis = new FileInputStream(file);117BuildSpec result = parse(fis, file.getName().substring(0, file.getName().length() - ConfigDirectory.BUILD_SPEC_FILE_EXTENSION.length()), flagDefinitions, featureDefinitions);118fis.close();119120return result;121}122123/**124* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)125*/126@Override127public void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes) {128/* We are starting to parse a new element, reset the parsed value */129_parsedValue = ""; //$NON-NLS-1$130131if (qName.equalsIgnoreCase("spec")) { //$NON-NLS-1$132/* Reset all lists */133_owners = new Vector<Owner>();134_features = new Vector<Feature>();135_flags = new Vector<Flag>();136_sources = new Vector<Source>();137_properties = new Vector<Property>();138139/* Set the build spec id */140_buildSpec.setId(attributes.getValue("id")); //$NON-NLS-1$141142/* Remember where this build spec was defined */143_buildSpec.setLocation(_documentLocatorFile, _documentLocator);144}145146/* Parse owners of the build spec */147else if (qName.equalsIgnoreCase("owners")) { //$NON-NLS-1$148_owners = new Vector<Owner>();149}150151/* Parse flags of the build spec */152else if (qName.equalsIgnoreCase("flags")) { //$NON-NLS-1$153_flags = new Vector<Flag>();154} else if (qName.equalsIgnoreCase("flag") && _flags != null) { //$NON-NLS-1$155String flagName = attributes.getValue("id"); //$NON-NLS-1$156Boolean flagState = Boolean.valueOf(attributes.getValue("value")); //$NON-NLS-1$157FlagDefinition flagDefinition = flagDefinitions.getFlagDefinition(flagName);158159Flag flag = new Flag(flagName, flagState);160flag.setLocation(_documentLocatorFile, _documentLocator);161162if (flagDefinition != null) {163flag.setDefinition(flagDefinition);164}165166_flags.add(flag);167}168169/* Parse features of the build spec */170else if (qName.equalsIgnoreCase("features")) { //$NON-NLS-1$171_features = new Vector<Feature>();172} else if (qName.equalsIgnoreCase("feature") && _features != null) { //$NON-NLS-1$173String featureId = attributes.getValue("id"); //$NON-NLS-1$174FeatureDefinition featureDefinition = featureDefinitions.get(featureId);175176Feature feature = new Feature(featureId);177feature.setLocation(_documentLocatorFile, _documentLocator);178179if (featureDefinition != null) {180feature.setDefinition(featureDefinition);181}182183_features.add(feature);184}185186/* Parse sources of the build spec */187else if (qName.equalsIgnoreCase("source")) { //$NON-NLS-1$188_sources = new Vector<Source>();189} else if (qName.equalsIgnoreCase("project") && _sources != null) { //$NON-NLS-1$190Source source = new Source(attributes.getValue("id")); //$NON-NLS-1$191source.setLocation(_documentLocatorFile, _documentLocator);192193_sources.add(source);194}195196/* Parse properties of the build spec */197else if (qName.equalsIgnoreCase("properties")) { //$NON-NLS-1$198_properties = new Vector<Property>();199} else if (qName.equalsIgnoreCase("property") && _properties != null) { //$NON-NLS-1$200Property property = new Property(attributes.getValue("name"), attributes.getValue("value")); //$NON-NLS-1$ //$NON-NLS-2$201property.setLocation(_documentLocatorFile, _documentLocator);202203_properties.add(property);204}205206}207208/**209* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)210*/211@Override212public void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName) {213if (qName.equalsIgnoreCase("name")) { //$NON-NLS-1$214_buildSpec.setName(_parsedValue);215} else if (qName.equalsIgnoreCase("asmBuilderName")) { //$NON-NLS-1$216AsmBuilder asmBuilder = new AsmBuilder(_parsedValue);217asmBuilder.setLocation(_documentLocatorFile, _documentLocator);218219_buildSpec.setAsmBuilder(asmBuilder);220} else if (qName.equalsIgnoreCase("cpuArchitecture")) { //$NON-NLS-1$221_buildSpec.setCpuArchitecture(_parsedValue);222} else if (qName.equalsIgnoreCase("os")) { //$NON-NLS-1$223_buildSpec.setOs(_parsedValue);224} else if (qName.equalsIgnoreCase("defaultJCL")) { //$NON-NLS-1$225JclConfiguration jclConfiguration = new JclConfiguration(_parsedValue);226jclConfiguration.setLocation(_documentLocatorFile, _documentLocator);227228_buildSpec.setDefaultJCL(jclConfiguration);229} else if (qName.equalsIgnoreCase("defaultSizes")) { //$NON-NLS-1$230DefaultSizes defaultSizes = new DefaultSizes(_parsedValue);231defaultSizes.setLocation(_documentLocatorFile, _documentLocator);232233_buildSpec.setDefaultSizes(defaultSizes);234} else if (qName.equalsIgnoreCase("priority")) { //$NON-NLS-1$235try {236_buildSpec.setPriority(Integer.parseInt(_parsedValue));237} catch (NumberFormatException e) {238error(new SAXParseException("Invalid priority value, not a valid integer.", _documentLocator)); //$NON-NLS-1$239}240}241242else if (qName.equalsIgnoreCase("owner")) { //$NON-NLS-1$243/* Parsed a single owner, add it to the list of Owners */244Owner owner = new Owner(_parsedValue);245owner.setLocation(_documentLocatorFile, _documentLocator);246247_buildSpec.addOwner(owner);248} else if (qName.equalsIgnoreCase("owners")) { //$NON-NLS-1$249/* Parsed all owners, add it to the BuildSpec */250_owners.add(new Owner(_parsedValue));251}252253/* The <flags> element is being closed. Add all parsed flags to the buildSpec */254else if (qName.equalsIgnoreCase("flags")) { //$NON-NLS-1$255for (Flag f : _flags) {256_buildSpec.addFlag(f);257}258259// Once all the flags and features have been added fill the list with the remaining260// flags set to a default value of FALSE261for (FlagDefinition flagDefinition : flagDefinitions.getFlagDefinitions().values()) {262if (!_buildSpec.hasFlag(flagDefinition.getId())) {263_buildSpec.addFlag(new Flag(flagDefinition));264}265}266}267268/* The <features> element is being closed. Add all parsed features to the buildSpec */269else if (qName.equalsIgnoreCase("features")) { //$NON-NLS-1$270for (Feature f : _features) {271/* Save the feature id, it is not our responsibility to load the actual feature here */272_buildSpec.addFeature(f);273}274}275276/* The <sources> element is being closed. Add all parsed sources to the buildSpec */277else if (qName.equalsIgnoreCase("source")) { //$NON-NLS-1$278for (Source s : _sources) {279_buildSpec.addSource(s);280}281}282283/* The <properties> element is being closed. Add all parsed properties to the buildSpec */284else if (qName.equalsIgnoreCase("properties")) { //$NON-NLS-1$285for (Property p : _properties) {286_buildSpec.addProperty(p);287}288}289290}291292/**293* Returns the name of the schema expected from this parser.294*295* @return The name of the schema expected by this parser.296*/297@Override298public String getSchemaName() {299return "spec-v1.xsd"; //$NON-NLS-1$300}301}302303304