package org.codehaus.mojo.jaxb2.shared.environment.sysprops; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.maven.plugin.logging.Log; import org.codehaus.mojo.jaxb2.AbstractJaxbMojo; import org.codehaus.mojo.jaxb2.shared.Validate; import org.codehaus.mojo.jaxb2.shared.environment.AbstractLogAwareFacet; import java.util.ArrayList; import java.util.List; /** * EnvironmentFacet which changes the value of a system property for the duration * of executing a tool. This is required for tools (such as the JDK SchemaGen) which * relies on environment or system properties being set for their execution. * This faced accepts one key and two values (original/new values). * * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB * @since 2.1 */ public final class SystemPropertyChangeEnvironmentFacet extends AbstractLogAwareFacet { /** * Operation definitions indicating how a System property should be changed by this EnvironmentFacet. */ public enum ChangeType { /** * Indicates that a System property should be added during {@code setup()} * and removed during {@code restore()}. If the property was already present, * this behaves like {@code #CHANGE}. */ ADD, /** * Indicates that a System property should be removed during {@code setup()} * and restored/re-added during {@code restore()} */ REMOVE, /** * Indicates that a System property should be altered during {@code setup()} * and restored during {@code restore()} */ CHANGE } // Internal state private ChangeType type; private String key; private String newValue; private String originalValue; /** * Creates a SystemPropertyChange which will remove the supplied system property for the * duration of this SystemPropertyChange. No exception will be thrown if the supplied System property * key is not found in the present System.properties. * * @param log The active Maven Log. * @param key A non-null key. * @see SystemPropertyChangeEnvironmentFacet.ChangeType#REMOVE */ private SystemPropertyChangeEnvironmentFacet(final Log log, final String key) { // Delegate super(log); // Assign internal state this.key = key; this.type = ChangeType.REMOVE; } /** * Creates a SystemPropertyChange which stores the current * * @param log The active Maven Log. * @param key The key of the System property managed by this SystemPropertyChange. * @param newValue The new value of this SystemPropertyChange. */ private SystemPropertyChangeEnvironmentFacet(final Log log, final String key, final String newValue) { // Delegate super(log); // Assign internal state this.key = key; this.originalValue = System.getProperty(key); this.newValue = newValue; this.type = existsAsSystemProperty(key) ? ChangeType.CHANGE : ChangeType.ADD; } /** * {@inheritDoc} */ @Override public void setup() { if (type == ChangeType.REMOVE) { System.clearProperty(key); } else { System.setProperty(key, newValue); } if (log.isDebugEnabled()) { log.debug("Setup " + toString()); } } /** * {@inheritDoc} */ @Override public void restore() { if (type == ChangeType.ADD) { System.clearProperty(key); } else { System.setProperty(key, originalValue); } if (log.isDebugEnabled()) { log.debug("Restored " + toString()); } } /** * @return A Debug string representation of this SystemPropertyChangeEnvironmentFacet. */ @Override public String toString() { final String toReturn = "SysProp key [" + key + "]\n" + " ... Original value: [" + originalValue + "]\n" + " ... Changed value : [" + newValue + "]"; return toReturn.replace("\n", AbstractJaxbMojo.NEWLINE); } /** * Creates a SystemPropertyChangesBuilder which uses the supplied active Maven Log. * * @param mavenLog The active Maven Log to be used by all SystemPropertyChange objects created * by this SystemPropertyChangesBuilder. * @return A SystemPropertyChangesBuilder ready for use. */ public static SystemPropertyChangesBuilder getBuilder(final Log mavenLog) { return new SystemPropertyChangesBuilder(mavenLog); } /** * Builder class intended to simplify creating SystemPropertyChange EnvironmentFacets. */ public static class SystemPropertyChangesBuilder { // Internal state private List<SystemPropertyChangeEnvironmentFacet> toReturn; private Log mavenLog; private SystemPropertyChangesBuilder(final Log mavenLog) { // Check sanity Validate.notNull(mavenLog, "mavenLog"); // Assign internal state this.toReturn = new ArrayList<SystemPropertyChangeEnvironmentFacet>(); this.mavenLog = mavenLog; } /** * Adds a SystemPropertyChange which removes the named System property. * * @param propertyName The name of the system property for which to create a REMOVE-type SystemPropertyChange. * @return This builder, for chaining. * @see SystemPropertyChangeEnvironmentFacet.ChangeType#REMOVE */ public SystemPropertyChangesBuilder remove(final String propertyName) { // Check sanity checkSanity(propertyName); // Add the SystemPropertyChange. toReturn.add(new SystemPropertyChangeEnvironmentFacet(mavenLog, propertyName)); // All done. return this; } /** * Adds a SystemPropertyChange which adds or changes the named System property. * * @param propertyName The name of the system property for which to create an * ADD- or CREATE-type SystemPropertyChange. * @param value The new value of the system property to set. * @return This builder, for chaining. * @see SystemPropertyChangeEnvironmentFacet.ChangeType#ADD * @see SystemPropertyChangeEnvironmentFacet.ChangeType#CHANGE */ public SystemPropertyChangesBuilder addOrChange(final String propertyName, final String value) { // Check sanity checkSanity(propertyName); // Add the SystemPropertyChange. toReturn.add(new SystemPropertyChangeEnvironmentFacet(mavenLog, propertyName, value)); // All done. return this; } /** * @return A List of SystemPropertyChange EnvironmentFacets which can be included as required into the * ToolExecutionEnvironment. */ public List<SystemPropertyChangeEnvironmentFacet> build() { return toReturn; } // // Private helpers // private void checkSanity(final String propertyName) { // Check sanity Validate.notEmpty(propertyName, "propertyName"); // Validate that the property name is not already present as a SystemPropertyChange. for (SystemPropertyChangeEnvironmentFacet current : toReturn) { if (current.key.equals(propertyName)) { throw new IllegalArgumentException("A SystemPropertyChange for propertyName '" + propertyName + "' is already present. Only one SystemPropertyChange per propertyName " + "should be supplied."); } } } } // // Private helpers // private boolean existsAsSystemProperty(final String key) { return System.getProperties().keySet().contains(key); } }