diff options
Diffstat (limited to 'framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java')
-rw-r--r-- | framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java new file mode 100644 index 00000000..864f57f0 --- /dev/null +++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java @@ -0,0 +1,410 @@ +package org.apache.maven.project.interpolation; + +/* + * 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.model.Model; +import org.apache.maven.project.ProjectBuilderConfiguration; +import org.apache.maven.project.path.PathTranslator; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.interpolation.InterpolationPostProcessor; +import org.codehaus.plexus.interpolation.Interpolator; +import org.codehaus.plexus.interpolation.StringSearchInterpolator; +import org.codehaus.plexus.interpolation.ValueSource; +import org.codehaus.plexus.logging.Logger; + +import java.io.File; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +@Deprecated +@Component( role = ModelInterpolator.class ) +public class StringSearchModelInterpolator + extends AbstractStringBasedModelInterpolator +{ + + private static final Map<Class<?>, Field[]> fieldsByClass = new WeakHashMap<Class<?>, Field[]>(); + private static final Map<Class<?>, Boolean> fieldIsPrimitiveByClass = new WeakHashMap<Class<?>, Boolean>(); + + public StringSearchModelInterpolator() + { + } + + public StringSearchModelInterpolator( PathTranslator pathTranslator ) + { + super( pathTranslator ); + } + + public Model interpolate( Model model, File projectDir, ProjectBuilderConfiguration config, boolean debugEnabled ) + throws ModelInterpolationException + { + interpolateObject( model, model, projectDir, config, debugEnabled ); + + return model; + } + + protected void interpolateObject( Object obj, Model model, File projectDir, ProjectBuilderConfiguration config, + boolean debugEnabled ) + throws ModelInterpolationException + { + try + { + List<ValueSource> valueSources = createValueSources( model, projectDir, config ); + List<InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir, config ); + + InterpolateObjectAction action = + new InterpolateObjectAction( obj, valueSources, postProcessors, debugEnabled, + this, getLogger() ); + + ModelInterpolationException error = AccessController.doPrivileged( action ); + + if ( error != null ) + { + throw error; + } + } + finally + { + getInterpolator().clearAnswers(); + } + } + + protected Interpolator createInterpolator() + { + StringSearchInterpolator interpolator = new StringSearchInterpolator(); + interpolator.setCacheAnswers( true ); + + return interpolator; + } + + private static final class InterpolateObjectAction implements PrivilegedAction<ModelInterpolationException> + { + + private final boolean debugEnabled; + private final LinkedList<Object> interpolationTargets; + private final StringSearchModelInterpolator modelInterpolator; + private final Logger logger; + private final List<ValueSource> valueSources; + private final List<InterpolationPostProcessor> postProcessors; + + public InterpolateObjectAction( Object target, List<ValueSource> valueSources, + List<InterpolationPostProcessor> postProcessors, boolean debugEnabled, + StringSearchModelInterpolator modelInterpolator, Logger logger ) + { + this.valueSources = valueSources; + this.postProcessors = postProcessors; + this.debugEnabled = debugEnabled; + + this.interpolationTargets = new LinkedList<Object>(); + interpolationTargets.add( target ); + + this.modelInterpolator = modelInterpolator; + this.logger = logger; + } + + public ModelInterpolationException run() + { + while ( !interpolationTargets.isEmpty() ) + { + Object obj = interpolationTargets.removeFirst(); + + try + { + traverseObjectWithParents( obj.getClass(), obj ); + } + catch ( ModelInterpolationException e ) + { + return e; + } + } + + return null; + } + + @SuppressWarnings( "unchecked" ) + private void traverseObjectWithParents( Class<?> cls, Object target ) + throws ModelInterpolationException + { + if ( cls == null ) + { + return; + } + + + if ( cls.isArray() ) + { + evaluateArray( target ); + } + else if ( isQualifiedForInterpolation( cls ) ) + { + Field[] fields = fieldsByClass.get( cls ); + if ( fields == null ) + { + fields = cls.getDeclaredFields(); + fieldsByClass.put( cls, fields ); + } + + for ( Field field : fields ) + { + Class<?> type = field.getType(); + if ( isQualifiedForInterpolation( field, type ) ) + { + boolean isAccessible = field.isAccessible(); + field.setAccessible( true ); + try + { + try + { + if ( String.class == type ) + { + String value = (String) field.get( target ); + if ( value != null ) + { + String interpolated = + modelInterpolator.interpolateInternal( value, valueSources, postProcessors, + debugEnabled ); + + if ( !interpolated.equals( value ) ) + { + field.set( target, interpolated ); + } + } + } + else if ( Collection.class.isAssignableFrom( type ) ) + { + Collection<Object> c = (Collection<Object>) field.get( target ); + if ( c != null && !c.isEmpty() ) + { + List<Object> originalValues = new ArrayList<Object>( c ); + try + { + c.clear(); + } + catch ( UnsupportedOperationException e ) + { + if ( debugEnabled && logger != null ) + { + logger.debug( "Skipping interpolation of field: " + field + " in: " + + cls.getName() + + "; it is an unmodifiable collection." ); + } + continue; + } + + for ( Object value : originalValues ) + { + if ( value != null ) + { + if ( String.class == value.getClass() ) + { + String interpolated = + modelInterpolator.interpolateInternal( (String) value, + valueSources, + postProcessors, + debugEnabled ); + + if ( !interpolated.equals( value ) ) + { + c.add( interpolated ); + } + else + { + c.add( value ); + } + } + else + { + c.add( value ); + if ( value.getClass().isArray() ) + { + evaluateArray( value ); + } + else + { + interpolationTargets.add( value ); + } + } + } + else + { + // add the null back in...not sure what else to do... + c.add( value ); + } + } + } + } + else if ( Map.class.isAssignableFrom( type ) ) + { + Map<Object, Object> m = (Map<Object, Object>) field.get( target ); + if ( m != null && !m.isEmpty() ) + { + for ( Map.Entry<Object, Object> entry : m.entrySet() ) + { + Object value = entry.getValue(); + + if ( value != null ) + { + if ( String.class == value.getClass() ) + { + String interpolated = + modelInterpolator.interpolateInternal( (String) value, + valueSources, + postProcessors, + debugEnabled ); + + if ( !interpolated.equals( value ) ) + { + try + { + entry.setValue( interpolated ); + } + catch ( UnsupportedOperationException e ) + { + if ( debugEnabled && logger != null ) + { + logger.debug( + "Skipping interpolation of field: " + field + + " (key: " + entry.getKey() + ") in: " + + cls.getName() + + "; it is an unmodifiable collection." ); + } + } + } + } + else + { + if ( value.getClass().isArray() ) + { + evaluateArray( value ); + } + else + { + interpolationTargets.add( value ); + } + } + } + } + } + } + else + { + Object value = field.get( target ); + if ( value != null ) + { + if ( field.getType().isArray() ) + { + evaluateArray( value ); + } + else + { + interpolationTargets.add( value ); + } + } + } + } + catch ( IllegalArgumentException e ) + { + throw new ModelInterpolationException( + "Failed to interpolate field: " + field + " on class: " + cls.getName(), e ); + } + catch ( IllegalAccessException e ) + { + throw new ModelInterpolationException( + "Failed to interpolate field: " + field + " on class: " + cls.getName(), e ); + } + } + finally + { + field.setAccessible( isAccessible ); + } + } + } + + traverseObjectWithParents( cls.getSuperclass(), target ); + } + } + + private boolean isQualifiedForInterpolation( Class<?> cls ) + { + return !cls.getPackage().getName().startsWith( "java" ); + } + + private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType ) + { + if ( !fieldIsPrimitiveByClass.containsKey( fieldType ) ) + { + fieldIsPrimitiveByClass.put( fieldType, fieldType.isPrimitive() ); + } + + if ( fieldIsPrimitiveByClass.get( fieldType ) ) + { + return false; + } + +// if ( fieldType.isPrimitive() ) +// { +// return false; +// } + + if ( "parent".equals( field.getName() ) ) + { + return false; + } + + return true; + } + + private void evaluateArray( Object target ) + throws ModelInterpolationException + { + int len = Array.getLength( target ); + for ( int i = 0; i < len; i++ ) + { + Object value = Array.get( target, i ); + if ( value != null ) + { + if ( String.class == value.getClass() ) + { + String interpolated = + modelInterpolator.interpolateInternal( (String) value, valueSources, postProcessors, + debugEnabled ); + + if ( !interpolated.equals( value ) ) + { + Array.set( target, i, interpolated ); + } + } + else + { + interpolationTargets.add( value ); + } + } + } + } + } + +} |