Path: blob/master/sourcetools/com.ibm.jpp.preprocessor/com/ibm/jpp/om/ConfigurationRegistry.java
6004 views
/*******************************************************************************1* Copyright (c) 1999, 2019 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.jpp.om;2223import java.io.File;24import java.io.FileNotFoundException;25import java.util.ArrayList;26import java.util.Collection;27import java.util.HashMap;28import java.util.HashSet;29import java.util.List;30import java.util.Map;31import java.util.Set;3233import com.ibm.jpp.xml.XMLException;3435public class ConfigurationRegistry {3637/**38* The default configuration XML for a registry.39*/40public static final String DEFAULT_XML = "jpp_configuration.xml";4142private int configVersion;4344private final String name;45private final Map<String, ConfigObject> configsByName;46private final List<ConfigObject> configs;47private final List<ConfigObject> localConfigs;48private final Set<String> validFlags;49private String baseDir;50private String srcRoot;51private final Map<String, String> incompleteConfigs;5253// Automated Test Metadata54private String testsProject;55private final List<ClassPathEntry> testsClassPaths;56private final List<Src> testsSources;5758/**59* Constructor60*61* @param baseDir the registry's base directory62* @param srcRoot the registry's source root path63*/64public ConfigurationRegistry(String baseDir, String srcRoot) {65testsClassPaths = new ArrayList<>();66testsSources = new ArrayList<>();6768configsByName = new HashMap<>();69configs = new ArrayList<>();70localConfigs = new ArrayList<>();71validFlags = new HashSet<>();72incompleteConfigs = new HashMap<>();7374this.name = srcRoot;7576if (baseDir.endsWith(File.separator)) {77this.baseDir = baseDir;78} else {79StringBuffer buffer = new StringBuffer(baseDir);80buffer.append(File.separator);81this.baseDir = buffer.toString();82}8384if (srcRoot.endsWith(File.separator)) {85this.srcRoot = srcRoot;86} else {87StringBuffer buffer = new StringBuffer(srcRoot);88buffer.append(File.separator);89this.srcRoot = buffer.toString();90}91}9293/**94* Returns the name of the registry.95*96* @return Returns the configuration registry name.97*/98public String getName() {99return name;100}101102/**103* Returns the name of the automated tests project associated with this104* registry (and all of its configurations).105*106* @return the automated tests project name107*/108public String getTestsProject() {109return testsProject;110}111112/**113* Returns the {@link ConfigObject} specified by name.114*115* @param name the name of the desired configuration116* @return the configuration117*/118public ConfigObject getConfiguration(String name) {119return (name == null) ? null : configsByName.get(name);120}121122/**123* Returns a {@link Set} of the registered configurations.124*125* @return the registered configurations as a Set126*/127public Collection<ConfigObject> getConfigurationsAsCollection() {128return configs;129}130131/**132* Returns a {@link Set} of the names of the registered configurations.133*134* @return the registered configuration names as a Set135*/136public Set<String> getConfigurationNamesAsSet() {137return configsByName.keySet();138}139140/**141* Returns an array of all configurations in this registry. This includes all142* configurations inherited from required XML files.143*144* @return the configurations145*/146public ConfigObject[] getConfigurations() {147return configs.toArray(new ConfigObject[configs.size()]);148}149150/**151* Returns an array of the configurations defined in the parent XML file. This152* <b>does not include</b> the configurations inherited from the required XML files.153*154* @return the local configurations155*/156public ConfigObject[] getLocalConfigurations() {157return localConfigs.toArray(new ConfigObject[localConfigs.size()]);158}159160/**161* Checks to see if the specified flag is valid.162*163* @param name the name of the flag to be check164* @return <code>true</code> for a valid flag, <code>false</code> otherwise165*/166public boolean isValidFlag(String name) {167return validFlags.contains(name);168}169170/**171* Returns a HashSet of the Valid flags.172*173* @return the HashSet of the valid flags.174*/175public Set<String> getValidFlags() {176return validFlags;177}178179/**180* Returns a list of all the configurations that are invalid as a result of181* improper or invalid tags in the XML file.182*183* @return the list of the incomplete configurations184*/185public Map<String, String> getIncompleteConfigs() {186return incompleteConfigs;187}188189/**190* Sets the new base directory for all the configurations to be added to this191* registry.192*193* @param newBaseDir the new base dir path194*/195public void setBaseDir(String newBaseDir) {196this.baseDir = (newBaseDir != null) ? newBaseDir : "";197}198199/**200* Returns the base directory for all the configurations.201*202* @return the base directory203*/204public String getBaseDir() {205return baseDir;206}207208/**209* Sets the new source root for all the configurations to be added to this210* registry.211*212* @param newSrcRoot the new source root path213*/214public void setSourceRoot(String newSrcRoot) {215this.srcRoot = (newSrcRoot == null) ? "" : File.pathSeparator + newSrcRoot + File.separator;216}217218/**219* Returns the source root for all the configurations220*221* @return the source root path222*/223public String getSourceRoot() {224return srcRoot;225}226227/**228* Registers a configuration with this configuration registry.229* <p>230* NOTE: A configuration can be defined as local if it was defined in the registry's231* own XML file as opposed to one of the registry's required XMLs.232*233* @param config the new configuration234* @param local <code>true</code> if the config was declared in this registry's XML, <code>false</code> otherwise235* @return <code>true</code> if the registration was successful, <code>false</code> otherwise236*/237public boolean registerConfiguration(ConfigObject config, boolean local) {238config.setRegistry(this);239if (config.checkDependencies()) {240config.updateWithDependencies();241242if (local) {243localConfigs.add(config);244}245configs.add(config);246configsByName.put(config.getName(), config);247validFlags.addAll(config.getFlags());248return true;249} else {250return false;251}252}253254/**255* Used if a configuration is added with the same name as a previous one.256* It is not a recommended practice to override the an existing configuration257* as it may produce unexpected results.258* <p>259* A configuration can be also defined as local if it was defined in the registry's260* own XML file as opposed to one of the registry's required XMLs.261*262* @param config the new configuration263* @param local <code>true</code> if the config was declared in this registry's XML, <code>false</code> otherwise264* @return <code>true</code> if the registration was successful, <code>false</code> otherwise265*/266public boolean overrideConfiguration(ConfigObject config, boolean local) {267config.setRegistry(this);268if (config.checkDependencies()) {269config.updateWithDependencies();270271if (local) {272localConfigs.remove(config);273localConfigs.add(config);274}275configs.remove(config);276configs.add(config);277configsByName.put(config.getName(), config);278validFlags.addAll(config.getFlags());279return true;280} else {281return false;282}283}284285/**286* Method to load registry configurations from the specified XML file287*288* @param filename the location of the jpp_configuration.xml289*290* @throws FileNotFoundException if the file specified by filename cannot be found.291* @throws XMLException if there are errors in the XML file292*/293public void registerXMLSet(String filename) throws FileNotFoundException, XMLException {294if (!filename.startsWith(File.separator) && !filename.startsWith(":", 1)) {295StringBuffer buffer = new StringBuffer(baseDir);296// buffer.append(File.separator);297buffer.append(srcRoot);298// buffer.append(File.separator);299buffer.append(filename);300filename = buffer.toString();301}302303ConfigXMLHandler xmlHandler = new ConfigXMLHandler(filename);304xmlHandler.setBaseDir(baseDir);305xmlHandler.setSourceRoot(srcRoot);306xmlHandler.parseInput();307308// Gets the automated tests variables309testsProject = xmlHandler.getTestsProject();310testsClassPaths.addAll(xmlHandler.getTestsClassPaths());311testsSources.addAll(xmlHandler.getTestsSources());312313setConfigVersion(xmlHandler.getConfigVersion());314315List<ConfigObject> tempLocalConfigs = xmlHandler.getLocalConfigs();316List<ConfigObject> tempConfigs = xmlHandler.getAllConfigs();317318for (ConfigObject currentConfig : tempConfigs) {319boolean failed = false;320321if (currentConfig.isSet() || (currentConfig.getSourceCount() > 0 && currentConfig.getOutputPath() != null)) {322if (getConfiguration(currentConfig.getName()) != null) {323//Note that overriding is being done324StringBuffer buffer = new StringBuffer("Warning: Multiple definitions of ");325buffer.append(currentConfig.getName());326buffer.append(" possible errors in dependencies");327System.err.println(buffer.toString());328failed = !overrideConfiguration(currentConfig, tempLocalConfigs.contains(currentConfig));329} else {330failed = !registerConfiguration(currentConfig, tempLocalConfigs.contains(currentConfig));331}332333if (failed) {334StringBuffer buffer = new StringBuffer("Warning dependencies could not be resolved: ");335buffer.append(currentConfig.getName());336System.err.println(buffer.toString());337// unresolvedDependencies.add(currentConfig.getName());338}339} else {340StringBuffer buffer = new StringBuffer();341342if (currentConfig.getSourceCount() == 0) {343buffer.append("Warning ");344buffer.append(currentConfig.getName());345buffer.append(" does not have sources");346}347348if (currentConfig.getSourceCount() == 0 && currentConfig.getOutputPath() == null) {349buffer.append("\n");350}351352if (currentConfig.getOutputPath() == null) {353buffer.append("Warning ");354buffer.append(currentConfig.getName());355buffer.append(" does not have an output path");356}357358System.err.println(buffer.toString());359incompleteConfigs.put(currentConfig.getName(), buffer.toString());360}361}362}363364/**365* Adds a classpath entry to this registry. This classpath entry will be366* used by the eclipse plugin to generate an automated test project classpath.367*368* @param path the classpath369* @param type the type of classpath370* @param isExported <code>true</code> if this entry is contributed to dependent projects, <code>false</code> otherwise371*/372public void addClassPathEntry(String path, String type, boolean isExported) {373testsClassPaths.add(new ClassPathEntry(path, type, isExported));374}375376/**377* Adds a classpath entry to this registry. This classpath entry will be378* used by the eclipse plugin to generate an automated test project classpath.379*380* @param path the classpath381* @param type the type of classpath382* @param sourcePath the classpath's source path383* @param isExported <code>true</code> if this entry is contributed to dependent projects, <code>false</code> otherwise384*/385public void addClassPathEntry(String path, String type, String sourcePath, boolean isExported) {386testsClassPaths.add(new ClassPathEntry(path, type, sourcePath, isExported));387}388389/**390* Returns this registry's automated tests' classpath entries.391*392* @return the classpath entries393*/394public ClassPathEntry[] getClassPathEntries() {395return (!testsClassPaths.isEmpty()) ? (ClassPathEntry[]) testsClassPaths.toArray(new ClassPathEntry[testsClassPaths.size()]) : new ClassPathEntry[0];396}397398/**399* Returns this registry's automated tests' source entries.400*401* @return the source entries402*/403public List<Src> getTestsSources() {404return testsSources;405}406407/**408* @see java.lang.Object#toString()409*/410@Override411public String toString() {412StringBuffer buffer = new StringBuffer("\nName: ");413buffer.append(name);414415buffer.append("\nConfigurations: ");416buffer.append(getConfigurationNamesAsSet().toString());417return buffer.toString();418}419420/**421* @see java.lang.Object#equals(java.lang.Object)422*/423@Override424public boolean equals(Object obj) {425if (obj instanceof ConfigurationRegistry) {426ConfigurationRegistry objReg = (ConfigurationRegistry) obj;427return (name.equals(objReg.getName()) && baseDir.equals(objReg.getBaseDir()) && srcRoot.equals(objReg.getSourceRoot()));428} else {429return false;430}431}432433/**434* @see java.lang.Object#hashCode()435*/436@Override437public int hashCode() {438return name.hashCode() + baseDir.hashCode() + srcRoot.hashCode();439}440441private void setConfigVersion(int ver) {442this.configVersion = ver;443}444445public int getConfigVersion() {446return configVersion;447}448449}450451452