Path: blob/master/sourcetools/objectmodel/com/ibm/j9tools/om/FeatureDefinition.java
6004 views
/*******************************************************************************1* Copyright (c) 2007, 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.j9tools.om;2223import java.io.PrintStream;24import java.util.Collection;25import java.util.Collections;26import java.util.HashSet;27import java.util.Map;28import java.util.Set;29import java.util.TreeMap;3031/**32* The Feature class defines the elements of a J9 Build Spec Feature. It encompasses flags and sources33* which are common among multiple build specifications and should be re-used.34*35* @author Gabriel Castro36*/37public class FeatureDefinition extends OMObject implements IFlagContainer, ISourceContainer {38protected String id;39protected String name;40protected String description;41private String runtime;4243protected Map<String, Property> properties;44protected Map<String, Flag> flags;45protected Map<String, Source> sources;4647protected boolean complete = false;4849/**50* Retrieves the specification ID from the given file name. The file name must have the51* specification file extension {@link ConfigDirectory#BUILD_SPEC_FILE_EXTENSION}.52*53* @param filename the specification file54* @return the spec ID or <code>null</code> if the filename is not identified as a spec file55*/56public static String getIDFromFileName(String filename) {57if (filename != null && filename.endsWith(ConfigDirectory.FEATURE_FILE_EXTENSION)) {58return filename.substring(0, filename.length() - (ConfigDirectory.FEATURE_FILE_EXTENSION.length()));59}6061return null;62}6364/**65* Default constructor66*/67public FeatureDefinition() {68this.properties = new TreeMap<String, Property>();69this.flags = new TreeMap<String, Flag>();70this.sources = new TreeMap<String, Source>();71}7273/**74* Constructor75*76* @param featureId the feature ID77*/78public FeatureDefinition(String featureId) {79this();80this.id = featureId;81}8283/**84* Retrieves this feature's ID.85*86* @return the feature ID87*/88public String getId() {89return id;90}9192/**93* Sets this feature's ID.94*95* @param id the feature ID96*/97public void setId(String id) {98this.id = id;99}100101/**102* Retrieves this feature's description.103*104* @return the feature description105*/106public String getDescription() {107return description;108}109110/**111* Sets this feature's description.112*113* @param description the description114*/115public void setDescription(String description) {116this.description = description;117}118119/**120* Retrieves this feature's name.121*122* @return the feature name123*/124public String getName() {125return name;126}127128/**129* Sets this feature's name.130*131* @param name the feature name132*/133public void setName(String name) {134this.name = name;135complete = true;136}137138/**139* Sets the runtime to which this feature definition belongs.140*141* @param runtime the parent runtime142*/143public void setRuntime(String runtime) {144this.runtime = runtime;145}146147/**148* Returns the runtime to which this feature definition belongs.149*150* @return the runtime151*/152public String getRuntime() {153return runtime;154}155156/**157* Adds the given {@link Property} to this {@link FeatureDefinition}.158*159* @param property new property.160*/161public void addProperty(Property property) {162properties.put(property.getName(), property);163}164165/**166* Adds the given properties to this {@link FeatureDefinition}.167*168* @param propertyNames new property names169*/170public void addAllProperties(Set<String> propertyNames) {171for (String name : propertyNames) {172properties.put(name, new Property(name, null));173}174}175176/**177* Removes the given property from this {@link FeatureDefinition}.178*179* @param property the property to be removed180*/181public void removeProperty(Property property) {182properties.remove(property.getName());183}184185/**186* Removes the property with the given name from this {@link FeatureDefinition}.187*188* @param propertyName the name of the property to be removed.189*/190public void removeProperty(String propertyName) {191properties.remove(propertyName);192}193194/**195* Determines if this {@link FeatureDefinition} has a property with the given name.196*197* @param propertyName the name of the property to check for198* @return <code>true</code> if this definitions has a property with the given name, <code>false</code> otherwise199*/200public boolean hasProperty(String propertyName) {201return properties.containsKey(propertyName);202}203204/**205* Retrieves the property with the given name.206*207* @param propertyName the name of the property to be retrieved208* @return the property retrieves or null if no property with that name exists209*/210public Property getProperty(String propertyName) {211return properties.get(propertyName);212}213214/**215* Retrieves all the properties from this {@link FeatureDefinition}.216*217* @return the properties218*/219public Map<String, Property> getProperties() {220return Collections.unmodifiableMap(properties);221}222223/**224* @see com.ibm.j9tools.om.IFlagContainer#addFlag(com.ibm.j9tools.om.Flag)225*/226public void addFlag(Flag flag) {227flags.put(flag.getId(), flag);228}229230/**231* Adds the given {@link Flag} map to this {@link FeatureDefinition}.232*233* @param flags the flags to be added234*/235public void addAllFlags(Map<String, Flag> flags) {236this.flags.putAll(flags);237}238239/**240* @see com.ibm.j9tools.om.IFlagContainer#removeFlag(com.ibm.j9tools.om.Flag)241*/242public void removeFlag(Flag flag) {243flags.remove(flag.getId());244}245246/**247* @see com.ibm.j9tools.om.IFlagContainer#removeFlag(java.lang.String)248*/249public void removeFlag(String flagId) {250flags.remove(flagId);251}252253/**254* @see com.ibm.j9tools.om.IFlagContainer#hasFlag(java.lang.String)255*/256public boolean hasFlag(String flagId) {257return hasLocalFlag(flagId);258}259260/**261* @see com.ibm.j9tools.om.IFlagContainer#hasFlag(java.lang.String)262*/263public boolean hasLocalFlag(String flagId) {264return flags.containsKey(flagId);265}266267/**268* @see com.ibm.j9tools.om.IFlagContainer#getFlag(java.lang.String)269*/270public Flag getFlag(String flagId) {271return getLocalFlag(flagId);272}273274/**275* @see com.ibm.j9tools.om.IFlagContainer#getFlag(java.lang.String)276*/277public Flag getLocalFlag(String flagId) {278return flags.get(flagId);279}280281/**282* @see com.ibm.j9tools.om.IFlagContainer#getFlags()283*/284public Map<String, Flag> getFlags() {285return getLocalFlags();286}287288/**289* @see com.ibm.j9tools.om.IFlagContainer#getFlags(java.lang.String)290*/291public Map<String, Flag> getFlags(String category) {292Map<String, Flag> allFlags = new TreeMap<String, Flag>();293294for (Flag flag : getFlags().values()) {295if (flag.getCategory().equals(category)) {296allFlags.put(flag.getId(), flag);297}298}299300return Collections.unmodifiableMap(allFlags);301}302303/**304* @see com.ibm.j9tools.om.IFlagContainer#getFlags()305*/306public Map<String, Flag> getLocalFlags() {307return Collections.unmodifiableMap(flags);308}309310/**311* @see com.ibm.j9tools.om.IFlagContainer#getLocalFlags(java.lang.String)312*/313public Map<String, Flag> getLocalFlags(String category) {314Map<String, Flag> allFlags = new TreeMap<String, Flag>();315316for (Flag flag : flags.values()) {317if (flag.getCategory().equals(category)) {318allFlags.put(flag.getId(), flag);319}320}321322return Collections.unmodifiableMap(allFlags);323}324325/**326* Adds the given source to this feature.327*328* @param source the source to be added329*/330public void addSource(Source source) {331sources.put(source.getId(), source);332}333334/**335* Adds the given sources to this {@link FeatureDefinition}.336*337* @param sourceNames new source names338*/339public void addAllSources(Set<String> sourceNames) {340for (String name : sourceNames) {341sources.put(name, new Source(name));342}343}344345/**346* Removes the given source from this feature.347*348* @param source the source to be removed349*/350public void removeSource(Source source) {351sources.remove(source.getId());352}353354/**355* Removes the source with the given ID from this feature.356*357* @param sourceId the source ID358*/359public void removeSource(String sourceId) {360sources.remove(sourceId);361}362363/**364* Determines if the given source is defined in this feature.365*366* @param sourceId the source ID367* @return <code>true</code> if this feature contains the source, <code>false</code> otherwise368*/369public boolean hasSource(String sourceId) {370return hasLocalSource(sourceId);371}372373/**374* Checks for existence of a local source.375*376* @param sourceId ID of the source to check for377* @return <code>true</code> if the source is included for this container, <code>false</code> otherwise378*/379public boolean hasLocalSource(String sourceId) {380return sources.containsKey(sourceId);381}382383/**384* @see com.ibm.j9tools.om.ISourceContainer#getSource(java.lang.String)385*/386public Source getSource(String sourceId) {387return getLocalSource(sourceId);388}389390/**391* Retrieves the sources with the given ID.392*393* @param sourceId the source ID394* @return the source with the given ID or null if the source in not part of this feature395*/396public Source getLocalSource(String sourceId) {397return sources.get(sourceId);398}399400/**401* Retrieves all the sources for this feature.402*403* @return the {@link Map} of sources404*/405public Map<String, Source> getSources() {406return getLocalSources();407}408409/**410* @see com.ibm.j9tools.om.ISourceContainer#getLocalSources()411*/412public Map<String, Source> getLocalSources() {413return Collections.unmodifiableMap(sources);414}415416/**417* Determines if this {@link FeatureDefinition} is fully defined.418*419* @return returns true if all elements are defined420*/421public boolean isComplete() {422return complete;423}424425/**426* Verifies the validity of this feature by checking its sources and flags. Sources are verified by a427* {@link SourceVerifier} and flags by a {@link FlagVerifier}.428*429* @throws InvalidFeatureDefinitionException thrown when source of flag errors are found430*/431public void verify(FlagDefinitions flagDefinitions, Set<String> sources) throws InvalidFeatureDefinitionException {432Collection<Throwable> errors = new HashSet<Throwable>();433434SourceVerifier sourceVerifier = new SourceVerifier(this, sources);435errors.addAll(sourceVerifier.verify());436437FlagVerifier flagVerifier = new FlagVerifier(this, flagDefinitions);438errors.addAll(flagVerifier.verify());439440if (errors.size() > 0) {441throw new InvalidFeatureDefinitionException(errors, this);442}443}444445/**446* Debug helper used to dump this feature's member variables and lists447*448* @param out output stream to print to449* @param prefix prefix to prepend to each line450* @param indentLevel number of spaces to append to the prefix451*/452public void dump(PrintStream out, String prefix, int indentLevel) {453StringBuffer indent = new StringBuffer(prefix);454for (int i = 0; i < indentLevel; i++) {455indent.append(' ');456}457458out.println(indent + "Feature "); //$NON-NLS-1$459out.println(indent + " +--- id: " + this.getId()); //$NON-NLS-1$460out.println(indent + " |--- name: " + this.getName()); //$NON-NLS-1$461out.println(indent + " |--- description: " + this.getDescription()); //$NON-NLS-1$462463out.println(indent + " |"); //$NON-NLS-1$464out.println(indent + " |--- Flags "); //$NON-NLS-1$465for (String flagId : flags.keySet()) {466Flag f = flags.get(flagId);467out.println(indent + " | |-- Flag"); //$NON-NLS-1$468out.println(indent + " | | +-- id: " + f.getId()); //$NON-NLS-1$469out.println(indent + " | | +-- state: " + f.getState()); //$NON-NLS-1$470}471472out.println(indent + " |"); //$NON-NLS-1$473out.println(indent + " |--- Sources "); //$NON-NLS-1$474for (String sourceId : sources.keySet()) {475Source s = sources.get(sourceId);476out.println(indent + " | |-- Source"); //$NON-NLS-1$477out.println(indent + " | | +-- id: " + s.getId()); //$NON-NLS-1$478}479}480481}482483484