Path: blob/master/sourcetools/objectmodel/com/ibm/j9tools/om/FlagDefinitions.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.text.MessageFormat;24import java.util.Collection;25import java.util.Collections;26import java.util.HashMap;27import java.util.HashSet;28import java.util.Map;29import java.util.Set;30import java.util.TreeMap;31import java.util.TreeSet;3233/**34*35* @author Maciek Klimkowski36* @author Gabriel Castro37*/38public class FlagDefinitions extends OMObject {39private String runtime;40private final Map<String, FlagDefinition> _flagDefinitions = new TreeMap<String, FlagDefinition>();41private final Map<String, Set<FlagDefinition>> _flagCategories = new HashMap<String, Set<FlagDefinition>>();4243/**44* Defaults FlagDefinitions constructor45*/46public FlagDefinitions() {47}4849/**50* Sets the runtime to which this flag definitions list belongs.51*52* @param runtime the parent runtime53*/54public void setRuntime(String runtime) {55this.runtime = runtime;56}5758/**59* Returns the runtime to which this flag definition belongs to, or <code>null</code> if none.60*61* @return the runtime62*/63public String getRuntime() {64return runtime;65}6667public boolean contains(String flagDefinitionId) {68return _flagDefinitions.containsKey(flagDefinitionId);69}7071public boolean contains(FlagDefinition flagDefinition) {72return _flagDefinitions.containsValue(flagDefinition);73}7475/**76* @param flagDefinition Flag Definition to be added to this flag definition list77*/78public void addFlagDefinition(FlagDefinition flagDefinition) {79_flagDefinitions.put(flagDefinition.getId(), flagDefinition);8081Set<FlagDefinition> definitions = _flagCategories.get(flagDefinition.getCategory());8283if (definitions == null) {84definitions = new HashSet<FlagDefinition>();85_flagCategories.put(flagDefinition.getCategory(), definitions);86}8788definitions.add(flagDefinition);89}9091/**92* Remove a flag definition93*94* @param flagDefinitionId ID of the flag definition95*/96public FlagDefinition removeFlagDefinition(String flagDefinitionId) {97FlagDefinition flagDefinition = _flagDefinitions.get(flagDefinitionId);9899return (flagDefinition != null) ? removeFlagDefinition(flagDefinition) : null;100}101102/**103* Remove a flag definition104*105* @param flagDefinition The FlagDefinition to remove (based on its ID)106*/107public FlagDefinition removeFlagDefinition(FlagDefinition flagDefinition) {108if (_flagDefinitions.containsValue(flagDefinition)) {109// Remove from category list110Set<FlagDefinition> categoryDefinitions = _flagCategories.get(flagDefinition.getCategory());111categoryDefinitions.remove(flagDefinition);112113// Remove category if this was the last flag definition114if (categoryDefinitions.size() == 0) {115_flagCategories.remove(flagDefinition.getCategory());116}117118// Remove any require/preclude reference to this category119for (FlagDefinition def : _flagDefinitions.values()) {120if (def.getRequires().containsKey(flagDefinition.getId())) {121def.removeRequires(flagDefinition.getId());122}123124if (def.getPrecludes().containsKey(flagDefinition.getId())) {125def.removePrecludes(flagDefinition.getId());126}127}128129return _flagDefinitions.remove(flagDefinition.getId());130}131132return null;133}134135/**136* Retrieve a FlagDefinition.137*138* @param flagDefinitionId The ID of FlagDefinition to be retrieved139* @return A FlagDefinition identified by flagDefinitionId argument140*/141public FlagDefinition getFlagDefinition(String flagDefinitionId) {142return _flagDefinitions.get(flagDefinitionId);143}144145/**146* Retrieve the HashMap containing all flag definitions contained by this FlagDefinitions object.147*148* @return A HashMap with all the flag definitions that this FlagDefinitions object holds.149*/150public Map<String, FlagDefinition> getFlagDefinitions() {151return Collections.unmodifiableMap(_flagDefinitions);152}153154/**155* Retrieves the list of {@link FlagDefinition} for the given category.156*157* @param category the category for which to retrieve flag definitions158* @return the list of {@link FlagDefinition}159*/160public Set<FlagDefinition> getFlagDefinitions(String category) {161return _flagCategories.containsKey(category) ? _flagCategories.get(category) : new HashSet<FlagDefinition>();162}163164/**165* Retrieves the list of flag definitions categories.166*167* @return the list of categories168*/169public Set<String> getCategories() {170return _flagCategories.keySet();171}172173/**174* Retrieves the list of {@link FlagDefinition} IDs that preclude the given flag ID.175*176* @param flagId the ID of the flag definition for which preclusions should be computed177* @return the list of precluded by flag definitions IDs178*/179public Set<String> getPrecludedBy(String flagId) {180Set<String> precludedBys = new TreeSet<String>();181182for (FlagDefinition flagDefinition : _flagDefinitions.values()) {183for (FlagDefinition preclude : flagDefinition.getPrecludes().values()) {184if (flagId.equals(preclude.getId())) {185precludedBys.add(flagDefinition.getId());186}187}188}189190return precludedBys;191}192193/**194* Retrieves the list of {@link FlagDefinition} IDs that preclude the given flag.195*196* @param flag the flag definition for which preclusions should be computed197* @return the list of flag definitions IDs198*/199public Set<String> getPrecludedBy(FlagDefinition flag) {200return getPrecludedBy(flag.getId());201}202203/**204* Retrieves the list of {@link FlagDefinition} IDs that require the given flag ID.205*206* @param flagId the ID of the flag definition for which dependencies should be computed207* @return the list of dependent flag definitions IDs208*/209public Set<String> getDependents(String flagId) {210Set<String> requiredBys = new TreeSet<String>();211212for (FlagDefinition flagDefinition : _flagDefinitions.values()) {213for (FlagDefinition require : flagDefinition.getRequires().values()) {214if (flagId.equals(require.getId())) {215requiredBys.add(flagDefinition.getId());216}217}218}219220return requiredBys;221}222223/**224* Retrieves the list of {@link FlagDefinition} IDs that required the given flag.225*226* @param flag the flag definition for which dependencies should be computed227* @return the list of dependent flag definitions IDs228*/229public Set<String> getDependents(FlagDefinition flag) {230return getDependents(flag.getId());231}232233/**234* Verify that the requires and precludes flag lists of each FlagDefinition refer to flag235* definitions that exist in _flagDefinitions.236*/237public void verify() throws InvalidFlagDefinitionsException {238Collection<Throwable> errors = new HashSet<Throwable>();239240for (FlagDefinition flagDef : _flagDefinitions.values()) {241errors.addAll(verifyDefinition(flagDef));242}243244if (errors.size() > 0) {245throw new InvalidFlagDefinitionsException(errors, this);246}247}248249public Collection<OMException> verifyDefinition(FlagDefinition flagDef) {250Collection<OMException> errors = new HashSet<OMException>();251252for (FlagDefinition req : flagDef.getLocalRequires().values()) {253if (!_flagDefinitions.containsKey(req.getId())) {254errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.invalidRequires"), new Object[] { req.getId() }), flagDef)); //$NON-NLS-1$255}256}257258for (FlagDefinition prec : flagDef.getLocalPrecludes().values()) {259if (!_flagDefinitions.containsKey(prec.getId())) {260errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.invalidPrecludes"), new Object[] { prec.getId() }), flagDef)); //$NON-NLS-1$261}262}263264if (flagDef.getLocalRequires().containsKey(flagDef.getId())) {265errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.requireSelf"), new Object[] { flagDef.getId() }), flagDef)); //$NON-NLS-1$266}267268if (flagDef.getLocalPrecludes().containsKey(flagDef.getId())) {269errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.precludeSelf"), new Object[] { flagDef.getId() }), flagDef)); //$NON-NLS-1$270}271272Map<String, FlagDefinition> allRequires = flagDef.getRequires();273Map<String, FlagDefinition> allPrecludes = flagDef.getPrecludes();274275if (allPrecludes.containsKey(flagDef.getId())) {276errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.precludeCycle"), new Object[] { flagDef.getId() }), flagDef)); //$NON-NLS-1$277}278279for (FlagDefinition req : allRequires.values()) {280if (allPrecludes.containsKey(req.getId())) {281errors.add(new InvalidFlagException(MessageFormat.format(Messages.getString("FlagDefinitions.requireAndPreclude"), new Object[] { flagDef.getId(), req.getId() }), flagDef)); //$NON-NLS-1$282}283}284285return errors;286}287}288289290