001/* 002 * Portions of this software was developed by employees of the National Institute 003 * of Standards and Technology (NIST), an agency of the Federal Government and is 004 * being made available as a public service. Pursuant to title 17 United States 005 * Code Section 105, works of NIST employees are not subject to copyright 006 * protection in the United States. This software may be subject to foreign 007 * copyright. Permission in the United States and in foreign countries, to the 008 * extent that NIST may hold copyright, to use, copy, modify, create derivative 009 * works, and distribute this software and its documentation without fee is hereby 010 * granted on a non-exclusive basis, provided that this notice and disclaimer 011 * of warranty appears in all copies. 012 * 013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 025 */ 026 027package gov.nist.secauto.metaschema.core.configuration; 028 029import gov.nist.secauto.metaschema.core.util.CollectionUtil; 030 031import java.util.HashMap; 032import java.util.Map; 033 034import edu.umd.cs.findbugs.annotations.NonNull; 035 036/** 037 * Provides a basic configuration management implementation that allows mutable 038 * access to configuration state. 039 * 040 * @param <T> 041 * the type of managed features 042 */ 043public class DefaultConfiguration<T extends IConfigurationFeature<?>> 044 implements IMutableConfiguration<T> { 045 @NonNull 046 private Map<T, Object> featureValues; 047 048 /** 049 * Create a new configuration. 050 * 051 */ 052 public DefaultConfiguration() { 053 this.featureValues = new HashMap<>(); 054 } 055 056 /** 057 * Create a new configuration based on the provided feature value map. 058 * 059 * @param featureValues 060 * the set of enabled features 061 */ 062 public DefaultConfiguration(@NonNull Map<T, Object> featureValues) { 063 this.featureValues = new HashMap<>(featureValues); 064 } 065 066 /** 067 * Create a new configuration based on the provided configuration. 068 * 069 * @param original 070 * the original configuration 071 */ 072 public DefaultConfiguration(@NonNull DefaultConfiguration<T> original) { 073 this(original.getFeatureValues()); 074 } 075 076 @Override 077 public Map<T, Object> getFeatureValues() { 078 return CollectionUtil.unmodifiableMap(featureValues); 079 } 080 081 private void ensureBooleanValue(@NonNull T feature) { 082 Class<?> valueClass = feature.getValueClass(); 083 if (!Boolean.class.isAssignableFrom(valueClass)) { 084 throw new UnsupportedOperationException( 085 String.format("Feature value class '%s' is boolean valued.", valueClass.getName())); 086 } 087 } 088 089 @Override 090 public boolean isFeatureEnabled(@NonNull T feature) { 091 ensureBooleanValue(feature); 092 return get(feature); 093 } 094 095 @Override 096 public IMutableConfiguration<T> enableFeature(@NonNull T feature) { 097 ensureBooleanValue(feature); 098 featureValues.put(feature, true); 099 return this; 100 } 101 102 @Override 103 public IMutableConfiguration<T> disableFeature(@NonNull T feature) { 104 ensureBooleanValue(feature); 105 featureValues.put(feature, false); 106 return this; 107 } 108 109 @Override 110 public IMutableConfiguration<T> applyConfiguration(@NonNull IConfiguration<T> original) { 111 this.featureValues.putAll(original.getFeatureValues()); 112 return this; 113 } 114 115 @Override 116 public IMutableConfiguration<T> set(T feature, Object value) { 117 Class<?> featureValueClass = feature.getValueClass(); 118 Class<?> valueClass = value.getClass(); 119 if (!featureValueClass.isAssignableFrom(valueClass)) { 120 throw new UnsupportedOperationException( 121 String.format("Provided value of class '%s' is not assignment compatible with feature value class '%s'.", 122 valueClass.getName(), 123 featureValueClass.getName())); 124 } 125 featureValues.put(feature, value); 126 return this; 127 } 128}