/* * Copyright (c) 2009-2015 * IT-Consulting Stephan Schloepke (http://www.schloepke.de/) * klemm software consulting Mirko Klemm (http://www.klemm-scs.com/) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jbasics.configuration.properties; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.util.Locale; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import org.jbasics.checker.ContractCheck; import org.jbasics.pattern.delegation.Delegate; import org.jbasics.pattern.factory.ParameterFactory; import org.jbasics.pattern.resolver.Resolver; import org.jbasics.pattern.strategy.SubstitutionStrategy; import org.jbasics.utilities.DataUtilities; public class SystemProperty<ValueType> implements Delegate<ValueType> { public static final Resolver<String, String> DEFAULT_SYSTEM_PROPERTY_RESOLVER = new Resolver<String, String>() { @Override public String resolve(final String request, final String defaultResult) { return System.getProperty(request, defaultResult); } }; public static final ParameterFactory<String, String> STRING_PASS_THRU = new PassThruValueTypeFactory<String>(); private final String name; private final ValueType defaultValue; private final String defaultSubstitutableValue; private final ParameterFactory<ValueType, String> valueTypeFactory; private final SubstitutionStrategy<String, String> substitutionStrategy; private final Resolver<String, String> systemPropertyResolver; public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final ValueType defaultValue) { this(name, valueTypeFactory, defaultValue, null, null); } public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final ValueType defaultValue, final Resolver<String, String> systemPropertyResolver) { this(name, valueTypeFactory, defaultValue, null, systemPropertyResolver); } public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final ValueType defaultValue, final SubstitutionStrategy<String, String> substitutionStrategy) { this(name, valueTypeFactory, defaultValue, substitutionStrategy, null); } public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final ValueType defaultValue, final SubstitutionStrategy<String, String> substitutionStrategy, final Resolver<String, String> systemPropertyResolver) { this.name = ContractCheck.mustNotBeNull(name, "name"); //$NON-NLS-1$ this.valueTypeFactory = ContractCheck.mustNotBeNull(valueTypeFactory, "valueTypeFactory"); //$NON-NLS-1$ this.defaultValue = defaultValue; this.defaultSubstitutableValue = null; this.substitutionStrategy = DataUtilities.coalesce(substitutionStrategy, SubstitutionStrategy.STRING_PASS_THRU); this.systemPropertyResolver = DataUtilities.coalesce(systemPropertyResolver, DEFAULT_SYSTEM_PROPERTY_RESOLVER); } public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final SubstitutionStrategy<String, String> substitutionStrategy, final String defaultSubstitutableValue) { this(name, valueTypeFactory, substitutionStrategy, defaultSubstitutableValue, null); } public SystemProperty(final String name, final ParameterFactory<ValueType, String> valueTypeFactory, final SubstitutionStrategy<String, String> substitutionStrategy, final String defaultSubstitutableValue, final Resolver<String, String> systemPropertyResolver) { this.name = ContractCheck.mustNotBeNull(name, "name"); //$NON-NLS-1$ this.valueTypeFactory = ContractCheck.mustNotBeNull(valueTypeFactory, "valueTypeFactory"); //$NON-NLS-1$ this.defaultValue = null; this.defaultSubstitutableValue = defaultSubstitutableValue; this.substitutionStrategy = DataUtilities.coalesce(substitutionStrategy, SubstitutionStrategy.STRING_PASS_THRU); this.systemPropertyResolver = DataUtilities.coalesce(systemPropertyResolver, DEFAULT_SYSTEM_PROPERTY_RESOLVER); } public static SystemProperty<String> stringProperty(final String name, final String defaultValue) { return new SystemProperty<String>(name, SystemProperty.STRING_PASS_THRU, defaultValue); } public static SystemProperty<Boolean> booleanProperty(final String name, final Boolean defaultValue) { return new SystemProperty<Boolean>(name, BooleanValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<BigInteger> integerProperty(final String name, final BigInteger defaultValue) { return new SystemProperty<BigInteger>(name, BigIntegerValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<BigDecimal> decimalProperty(final String name, final BigDecimal defaultValue) { return new SystemProperty<BigDecimal>(name, BigDecimalValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<XMLGregorianCalendar> dateProperty(final String name, final XMLGregorianCalendar defaultValue) { return new SystemProperty<XMLGregorianCalendar>(name, DateValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<Duration> durationProperty(final String name, final Duration defaultValue) { return new SystemProperty<Duration>(name, DurationValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<URI> uriProperty(final String name, final URI defaultValue) { return new SystemProperty<URI>(name, URIValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<Locale> localeProperty(final String name, final Locale defaultValue) { return new SystemProperty<Locale>(name, LocaleValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static SystemProperty<Class<?>> classProperty(final String name, final Class<?> defaultValue) { return new SystemProperty<Class<?>>(name, ClassValueTypeFactory.SHARED_INSTANCE, defaultValue); } public static <E extends Enum<E>> SystemProperty<E> enumProperty(final Class<E> enumClazz, final String name, final E defaultValue) { return new SystemProperty<E>(name, new EnumValueTypeFactory<E>(enumClazz), defaultValue); } public final boolean isPropertySet() { return System.getProperty(this.name) != null; } public final boolean isPropertyDefault() { return System.getProperty(this.name) == null; } @Override public ValueType delegate() { return value(); } public final ValueType value() { final String temp = this.systemPropertyResolver.resolve(this.name, this.defaultSubstitutableValue); if (temp == null) { return this.defaultValue; } else { return this.valueTypeFactory.create(substitutionStrategy.substitute(temp)); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (this.defaultValue == null ? 0 : this.defaultValue.hashCode()); result = prime * result + (this.name == null ? 0 : this.name.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final SystemProperty<?> other = (SystemProperty<?>) obj; if (this.defaultValue == null) { if (other.defaultValue != null) { return false; } } else if (!this.defaultValue.equals(other.defaultValue)) { return false; } if (this.name == null) { if (other.name != null) { return false; } } else if (!this.name.equals(other.name)) { return false; } return true; } @Override public String toString() { final ValueType temp = value(); return temp != null ? temp.toString() : "#NULL#"; //$NON-NLS-1$ } }