You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by hb...@apache.org on 2020/02/13 22:11:11 UTC
[maven-filtering] 01/44: [MNG-3374] Create a common component for
files filtering start some jobs for this issue
This is an automated email from the ASF dual-hosted git repository.
hboutemy pushed a commit to annotated tag maven-filtering-1.0-alpha-1
in repository https://gitbox.apache.org/repos/asf/maven-filtering.git
commit 38161027604e0f886cb273e210424c2b2990122f
Author: Oliver Lamy <ol...@apache.org>
AuthorDate: Thu Jan 24 00:28:33 2008 +0000
[MNG-3374] Create a common component for files filtering
start some jobs for this issue
git-svn-id: https://svn.apache.org/repos/asf/maven/sandbox/trunk/shared/maven-filtering@614750 13f79535-47bb-0310-9956-ffa450edef68
---
.classpath | 21 +++
.project | 13 ++
.settings/org.eclipse.jdt.core.prefs | 5 +
pom.xml | 76 ++++++++
.../maven/shared/filtering/CompositeMap.java | 140 +++++++++++++++
.../shared/filtering/DefaultMavenFileFilter.java | 153 ++++++++++++++++
.../maven/shared/filtering/MavenFileFilter.java | 79 ++++++++
.../shared/filtering/MavenFilteringException.java | 63 +++++++
.../maven/shared/filtering/PropertyUtils.java | 199 +++++++++++++++++++++
.../shared/filtering/ReflectionProperties.java | 87 +++++++++
.../shared/filtering/TestReflectionProperties.java | 121 +++++++++++++
src/test/resources/pom.xml | 72 ++++++++
src/test/units-files/reflection-test.properties | 22 +++
13 files changed, 1051 insertions(+)
diff --git a/.classpath b/.classpath
new file mode 100755
index 0000000..c10b3b7
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,21 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="src" path="target/maven-shared-archive-resources" excluding="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-project/2.0.6/maven-project-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-settings/2.0.6/maven-settings-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-model/2.0.6/maven-model-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-utils/1.4.9/plexus-utils-1.4.9.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codehaus/plexus/plexus-container-default/1.0-alpha-9-stable-1/plexus-container-default-1.0-alpha-9-stable-1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
+ <classpathentry kind="var" path="M2_REPO/classworlds/classworlds/1.1-alpha-2/classworlds-1.1-alpha-2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-profile/2.0.6/maven-profile-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-artifact-manager/2.0.6/maven-artifact-manager-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-repository-metadata/2.0.6/maven-repository-metadata-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-artifact/2.0.6/maven-artifact-2.0.6.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/maven/maven-plugin-registry/2.0.6/maven-plugin-registry-2.0.6.jar"/>
+</classpath>
\ No newline at end of file
diff --git a/.project b/.project
new file mode 100755
index 0000000..26aa53c
--- /dev/null
+++ b/.project
@@ -0,0 +1,13 @@
+<projectDescription>
+ <name>maven-filtering</name>
+ <comment>Maven shared components</comment>
+ <projects/>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 0000000..4f8e077
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Sun Jan 20 22:27:40 CET 2008
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.4
+org.eclipse.jdt.core.compiler.compliance=1.4
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 0000000..a5eff30
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-shared-components</artifactId>
+ <version>8</version>
+ </parent>
+
+ <prerequisites>
+ <maven>2.0.6</maven>
+ </prerequisites>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-filtering</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-alpha-1-SNAPSHOT</version>
+
+ <name>Maven Files Filtering</name>
+
+ <scm>
+ <connection>scm:svn:https://svn.apache.org/repos/asf/maven/sandbox/trunk/shared/maven-interpolation</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/sandbox/trunk/shared/maven-interpolation</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/sandbox/trunk/shared/maven-interpolation</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <version>1.3.4</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.4.9</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/maven/shared/filtering/CompositeMap.java b/src/main/java/org/apache/maven/shared/filtering/CompositeMap.java
new file mode 100755
index 0000000..c29a86c
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/CompositeMap.java
@@ -0,0 +1,140 @@
+package org.apache.maven.shared.filtering;
+
+/*
+ * 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 java.io.IOException;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A Map composed with some others (optional adding SystemProperties and envvar)
+ * The get Method look in the Map list to return the corresponding value
+ * @author <a href="mailto:olamy@apache.org">olamy</a>
+ * @since 15 janv. 08
+ * @version $Id$
+ */
+public class CompositeMap
+ extends AbstractMap
+{
+
+ private List /*Map*/maps;
+
+ private boolean systemPropertiesFirst;
+
+ /**
+ * Ca
+ * @param maps
+ * @throws IOException if getting envvars failed
+ */
+ public CompositeMap( List /* Map */maps )
+ {
+ this( maps, false, false );
+ }
+
+ /**
+ * @param maps an orderer {@link List} of {@link Map}
+ * @param useSystemProperties using or not the System Properties
+ * @param systemPropertiesFirst if with get( key ) the systemProperties must wins (the internal ordered {@link List}
+ * will have in first the System Properties)
+ */
+ public CompositeMap( List /*Map*/maps, boolean useSystemProperties, boolean systemPropertiesFirst )
+ {
+ this.systemPropertiesFirst = systemPropertiesFirst;
+ if ( systemPropertiesFirst && !useSystemProperties )
+ {
+ throw new IllegalArgumentException( "systemPropertiesFirst can't be true if useSystemProperties is false" );
+ }
+ this.maps = new ArrayList();
+ if ( useSystemProperties && !systemPropertiesFirst )
+ {
+ if ( maps != null )
+ {
+ this.maps.addAll( maps );
+ }
+ this.maps.add( System.getProperties() );
+ }
+ else if ( useSystemProperties && systemPropertiesFirst )
+ {
+ this.maps.add( System.getProperties() );
+ if ( maps != null )
+ {
+ this.maps.addAll( maps );
+ }
+ }
+ else
+ {
+ if ( maps != null )
+ {
+ this.maps.addAll( maps );
+ }
+ }
+ }
+
+ public Object get( Object key )
+ {
+ if ( this.maps != null )
+ {
+ for ( Iterator iterator = this.maps.iterator(); iterator.hasNext(); )
+ {
+ Map map = (Map) iterator.next();
+ Object value = map.get( key );
+ if ( value != null )
+ {
+ return value;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @see java.util.AbstractMap#entrySet()
+ */
+ public Set entrySet()
+ {
+ throw new UnsupportedOperationException( "Cannot enumerate properties in a composite map" );
+ }
+
+ public List getMaps()
+ {
+ return maps;
+ }
+
+ public void addMap( Map map )
+ {
+ // see constructors internal Map can't be null
+ this.maps.add( map );
+ }
+
+ public boolean isSystemPropertiesFirst()
+ {
+ return systemPropertiesFirst;
+ }
+
+ public void setSystemPropertiesFirst( boolean systemPropertiesFirst )
+ {
+ this.systemPropertiesFirst = systemPropertiesFirst;
+ }
+
+}
diff --git a/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
new file mode 100755
index 0000000..b6551dc
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenFileFilter.java
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.filtering;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.InterpolationFilterReader;
+
+/**
+ * @author <a href="mailto:olamy@apache.org">olamy</a>
+ * @since 22 janv. 08
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.shared.filtering.MavenFileFilter" role-hint="default"
+ */
+public class DefaultMavenFileFilter
+ implements MavenFileFilter
+{
+
+ /**
+ * @see org.apache.maven.shared.filtering.MavenFileFilter#copyFile(java.io.File, java.io.File, boolean, org.apache.maven.project.MavenProject, java.util.List)
+ */
+ public void copyFile( File from, File to, boolean filtering, MavenProject mavenProject, List filters,
+ boolean escapedBackslashesInFilePath, String encoding )
+ throws MavenFilteringException
+ {
+ List filterWrappers = getDefaultFilterWrappers( mavenProject, filters, escapedBackslashesInFilePath );
+ copyFile( from, to, filtering, filterWrappers, encoding );
+ }
+
+ /**
+ * @see org.apache.maven.shared.filtering.MavenFileFilter#copyFile(java.io.File, java.io.File, boolean, java.util.List)
+ */
+ public void copyFile( File from, File to, boolean filtering, List filterWrappers, String encoding )
+ throws MavenFilteringException
+ {
+
+ try
+ {
+ if ( filtering )
+ {
+ FileUtils.FilterWrapper[] wrappers = (FileUtils.FilterWrapper[]) filterWrappers
+ .toArray( new FileUtils.FilterWrapper[filterWrappers.size()] );
+ FileUtils.copyFile( from, to, encoding, wrappers );
+ }
+ else
+ {
+ FileUtils.copyFile( from, to, encoding, new FileUtils.FilterWrapper[0] );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new MavenFilteringException( e.getMessage(), e );
+ }
+
+ }
+
+ /**
+ * @see org.apache.maven.shared.filtering.MavenFileFilter#getDefaultFilterWrappers(org.apache.maven.project.MavenProject, java.util.List)
+ */
+ public List getDefaultFilterWrappers( final MavenProject mavenProject, List filters, final boolean escapedBackslashesInFilePath )
+ throws MavenFilteringException
+ {
+
+ final Properties filterProperties = new Properties();
+
+ // System properties
+ filterProperties.putAll( System.getProperties() );
+
+ // Project properties
+ filterProperties.putAll( mavenProject.getProperties() );
+
+ // Take a copy of filterProperties to ensure that evaluated filterTokens are not propagated
+ // to subsequent filter files. NB this replicates current behaviour and seems to make sense.
+ final Properties baseProps = new Properties();
+ baseProps.putAll( filterProperties );
+
+ if ( filters != null )
+ {
+ for ( Iterator i = filters.iterator(); i.hasNext(); )
+ {
+ String filtersfile = (String) i.next();
+ try
+ {
+
+ Properties properties = PropertyUtils.loadPropertyFile( new File( filtersfile ), baseProps );
+ filterProperties.putAll( properties );
+ }
+ catch ( IOException e )
+ {
+ throw new MavenFilteringException( "Error loading property file '" + filtersfile + "'", e );
+ }
+ }
+ }
+
+ List defaultFilterWrappers = new ArrayList(3);
+
+ // support ${token}
+ FileUtils.FilterWrapper one = new FileUtils.FilterWrapper() {
+ public Reader getReader(Reader reader) {
+ return new InterpolationFilterReader(reader, filterProperties, "${", "}");
+ }
+ };
+ defaultFilterWrappers.add( one );
+
+ // support @token@
+ FileUtils.FilterWrapper second = new FileUtils.FilterWrapper() {
+ public Reader getReader(Reader reader) {
+ return new InterpolationFilterReader(reader, filterProperties, "@", "@");
+ }
+ };
+ defaultFilterWrappers.add( second );
+ // support ${token} with mavenProject reflection
+ FileUtils.FilterWrapper third = new FileUtils.FilterWrapper()
+ {
+ public Reader getReader( Reader reader )
+ {
+ ReflectionProperties reflectionProperties = new ReflectionProperties( mavenProject,
+ escapedBackslashesInFilePath );
+ return new InterpolationFilterReader( reader, reflectionProperties, "${", "}" );
+ }
+ };
+ defaultFilterWrappers.add( third );
+
+
+ return defaultFilterWrappers;
+ }
+
+}
diff --git a/src/main/java/org/apache/maven/shared/filtering/MavenFileFilter.java b/src/main/java/org/apache/maven/shared/filtering/MavenFileFilter.java
new file mode 100755
index 0000000..e8f32ff
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/MavenFileFilter.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.filtering;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @author <a href="mailto:olamy@apache.org">olamy</a>
+ * @since 22 janv. 08
+ * @version $Id$
+ */
+public interface MavenFileFilter
+{
+
+ /**
+ * Will copy a file with some filtering using defaultFilterWrappers
+ * @see #getDefaultFilterWrappers(MavenProject, List)
+ *
+ * @param from file to copy/filter
+ * @param to destination file
+ * @param filtering enable or not filering
+ * @param mavenProject the mavenproject
+ * @param filters {@link List} of properties file
+ * @throws IOException
+ */
+ public void copyFile( File from, final File to, boolean filtering, MavenProject mavenProject,
+ List/* File */filters, boolean escapedBackslashesInFilePath, String encoding )
+ throws MavenFilteringException;
+
+ /**
+ * @param from
+ * @param to
+ * @param filtering
+ * @param filterWrappers
+ * @throws MavenFilteringException
+ */
+ public void copyFile( File from, final File to, boolean filtering, List /*FileUtils.FilterWrapper*/filterWrappers, String encoding )
+ throws MavenFilteringException;
+
+ /**
+ *
+ * Will return the default FileUtils.FilterWrappers
+ *
+ * <ul>
+ * <li>interpolation with token ${ } and values from System.getProperties, project.getProperties and from filters.</li>
+ * <li>interpolation with token @ @ and values from System.getProperties, project.getProperties and from filters.</li>
+ * <li>interpolation with token ${ } and values from mavenProject interpolation.</li>
+ * </ul>
+ *
+ * @param mavenProject
+ * @param filters {@link List} of properties file
+ *
+ * @return {@link List} of FileUtils.FilterWrapper
+ *
+ */
+ public List/*FileUtils.FilterWrapper*/getDefaultFilterWrappers( MavenProject mavenProject, List/* File */filters,
+ boolean escapedBackslashesInFilePath )
+ throws MavenFilteringException;
+}
diff --git a/src/main/java/org/apache/maven/shared/filtering/MavenFilteringException.java b/src/main/java/org/apache/maven/shared/filtering/MavenFilteringException.java
new file mode 100755
index 0000000..25cb808
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/MavenFilteringException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.filtering;
+
+/**
+ * @author <a href="mailto:olamy@apache.org">olamy</a>
+ * @since 22 janv. 08
+ * @version $Id$
+ */
+public class MavenFilteringException
+ extends Exception
+{
+
+ /**
+ *
+ */
+ public MavenFilteringException()
+ {
+ // nothing
+ }
+
+ /**
+ * @param message
+ */
+ public MavenFilteringException( String message )
+ {
+ super( message );
+ }
+
+ /**
+ * @param cause
+ */
+ public MavenFilteringException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MavenFilteringException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/src/main/java/org/apache/maven/shared/filtering/PropertyUtils.java b/src/main/java/org/apache/maven/shared/filtering/PropertyUtils.java
new file mode 100755
index 0000000..424d689
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/PropertyUtils.java
@@ -0,0 +1,199 @@
+package org.apache.maven.shared.filtering;
+
+/*
+ * 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.codehaus.plexus.util.IOUtil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Properties;
+
+
+/**
+ * @author <a href="mailto:kenney@neonics.com">Kenney Westerhof</a>
+ * @author William Ferguson
+ * @version $Id$
+ */
+public final class PropertyUtils
+{
+ private PropertyUtils()
+ {
+ // prevent instantiation
+ }
+
+ /**
+ * Reads a property file, resolving all internal variables, using the supplied base properties.
+ * <p>
+ * The properties are resolved iteratively, so if the value of property A refers to property B, then after resolution
+ * the value of property B will contain the value of property B.
+ * </p>
+ *
+ * @param propFile The property file to load.
+ * @param baseProps Properties containing the initial values to subsitute into the properties file.
+ * @return Properties object containing the properties in the file with their values fully resolved.
+ * @throws IOException if profile does not exist, or cannot be read.
+ */
+ public static Properties loadPropertyFile( File propFile, Properties baseProps )
+ throws IOException
+ {
+ if ( !propFile.exists() )
+ {
+ throw new FileNotFoundException( propFile.toString() );
+ }
+
+ final Properties fileProps = new Properties();
+ final FileInputStream inStream = new FileInputStream( propFile );
+ try
+ {
+ fileProps.load( inStream );
+ }
+ finally
+ {
+ IOUtil.close( inStream );
+ }
+
+ final Properties combinedProps = new Properties();
+ combinedProps.putAll( baseProps );
+ combinedProps.putAll( fileProps );
+
+ // The algorithm iterates only over the fileProps which is all that is required to resolve
+ // the properties defined within the file. This is slighlty different to current, however
+ // I suspect that this was the actual original intent.
+ //
+ // The difference is that #loadPropertyFile(File, boolean, boolean) also resolves System properties
+ // whose values contain expressions. I believe this is unexpected and is not validated by the test cases,
+ // as can be verified by replacing the implementation of #loadPropertyFile(File, boolean, boolean)
+ // with the commented variant I have provided that reuses this method.
+
+ for ( Iterator iter = fileProps.keySet().iterator(); iter.hasNext(); )
+ {
+ final String k = (String) iter.next();
+ final String propValue = getPropertyValue( k, combinedProps );
+ fileProps.setProperty( k, propValue );
+ }
+
+ return fileProps;
+ }
+
+ /**
+ * Reads a property file, resolving all internal variables.
+ *
+ * @param propfile The property file to load
+ * @param fail wheter to throw an exception when the file cannot be loaded or to return null
+ * @param useSystemProps wheter to incorporate System.getProperties settings into the returned Properties object.
+ * @return the loaded and fully resolved Properties object
+ */
+ public static Properties loadPropertyFile( File propfile, boolean fail, boolean useSystemProps )
+ throws IOException
+ {
+
+ final Properties baseProps = new Properties();
+
+ if (useSystemProps)
+ {
+ baseProps.putAll(System.getProperties());
+ }
+
+ final Properties resolvedProps = new Properties();
+ try
+ {
+ resolvedProps.putAll(loadPropertyFile(propfile, baseProps));
+ } catch (FileNotFoundException e)
+ {
+ if (fail)
+ {
+ throw new FileNotFoundException(propfile.toString());
+ }
+ }
+
+ if (useSystemProps)
+ {
+ resolvedProps.putAll(baseProps);
+ }
+
+ return resolvedProps;
+ }
+
+
+ /**
+ * Retrieves a property value, replacing values like ${token}
+ * using the Properties to look them up.
+ *
+ * It will leave unresolved properties alone, trying for System
+ * properties, and implements reparsing (in the case that
+ * the value of a property contains a key), and will
+ * not loop endlessly on a pair like
+ * test = ${test}.
+ */
+ private static String getPropertyValue( String k, Properties p )
+ {
+ // This can also be done using InterpolationFilterReader,
+ // but it requires reparsing the file over and over until
+ // it doesn't change.
+
+ String v = p.getProperty( k );
+ String ret = "";
+ int idx, idx2;
+
+ while ( ( idx = v.indexOf( "${" ) ) >= 0 )
+ {
+ // append prefix to result
+ ret += v.substring( 0, idx );
+
+ // strip prefix from original
+ v = v.substring( idx + 2 );
+
+ // if no matching } then bail
+ if ( ( idx2 = v.indexOf( '}' ) ) < 0 )
+ {
+ break;
+ }
+
+ // strip out the key and resolve it
+ // resolve the key/value for the ${statement}
+ String nk = v.substring( 0, idx2 );
+ v = v.substring( idx2 + 1 );
+ String nv = p.getProperty( nk );
+
+ // try global environment..
+ if ( nv == null )
+ {
+ nv = System.getProperty( nk );
+ }
+
+ // if the key cannot be resolved,
+ // leave it alone ( and don't parse again )
+ // else prefix the original string with the
+ // resolved property ( so it can be parsed further )
+ // taking recursion into account.
+ if ( nv == null || nv.equals( k ) )
+ {
+ ret += "${" + nk + "}";
+ }
+ else
+ {
+ v = nv + v;
+ }
+ }
+ return ret + v;
+ }
+}
diff --git a/src/main/java/org/apache/maven/shared/filtering/ReflectionProperties.java b/src/main/java/org/apache/maven/shared/filtering/ReflectionProperties.java
new file mode 100755
index 0000000..a6d9ef9
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/filtering/ReflectionProperties.java
@@ -0,0 +1,87 @@
+package org.apache.maven.shared.filtering;
+
+/*
+ * 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 java.util.AbstractMap;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
+
+
+/**
+ * @author Andreas Hoheneder (ahoh_at_inode.at)
+ * @version $Id$
+ */
+public class ReflectionProperties
+ extends AbstractMap
+{
+
+ private MavenProject project;
+
+ boolean escapedBackslashesInFilePath;
+
+ public ReflectionProperties( MavenProject mavenProject )
+ {
+ this(mavenProject, false);
+ }
+
+ public ReflectionProperties( MavenProject mavenProject, boolean escapedBackslashesInFilePath )
+ {
+ super();
+
+ project = mavenProject;
+
+ this.escapedBackslashesInFilePath = escapedBackslashesInFilePath;
+ }
+
+ public Object get( Object key )
+ {
+ Object value = null;
+ try
+ {
+ value = ReflectionValueExtractor.evaluate( "" + key , project );
+
+ if ( escapedBackslashesInFilePath && value != null &&
+ "java.lang.String".equals( value.getClass().getName() ) )
+ {
+ String val = (String) value;
+
+ // Check if it's a windows path
+ if ( val.indexOf( ":\\" ) == 1 )
+ {
+ value = StringUtils.replace( (String)value, "\\", "\\\\" );
+ value = StringUtils.replace( (String)value, ":", "\\:" );
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ //TODO: remove the try-catch block when ReflectionValueExtractor.evaluate() throws no more exceptions
+ }
+ return value;
+ }
+
+ public Set entrySet()
+ {
+ throw new UnsupportedOperationException( "Cannot enumerate properties in a project" );
+ }
+}
diff --git a/src/test/java/org/apache/maven/shared/filtering/TestReflectionProperties.java b/src/test/java/org/apache/maven/shared/filtering/TestReflectionProperties.java
new file mode 100755
index 0000000..e0a7077
--- /dev/null
+++ b/src/test/java/org/apache/maven/shared/filtering/TestReflectionProperties.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+package org.apache.maven.shared.filtering;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * @author <a href="mailto:olamy@apache.org">olamy</a>
+ * @since 22 janv. 08
+ * @version $Id$
+ */
+public class TestReflectionProperties
+ extends PlexusTestCase
+{
+
+ public void testSimpleFiltering()
+ throws Exception
+ {
+ Properties allProperties = System.getProperties();
+ FileInputStream readFileInputStream = null;
+ try
+ {
+ MavenProject mavenProject = new MavenProject();
+ mavenProject.setVersion( "1.0" );
+ mavenProject.setGroupId( "org.apache" );
+ System.setProperty( "foo", "bar" );
+ MavenFileFilter mavenFileFilter = (MavenFileFilter) lookup( MavenFileFilter.class.getName(), "default" );
+
+ File from = new File( getBasedir() + "/src/test/units-files/reflection-test.properties" );
+ File to = new File( getBasedir() + "/target/reflection-test.properties" );
+
+ if (to.exists())
+ {
+ to.delete();
+ }
+
+ mavenFileFilter.copyFile( from, to, true, mavenProject, null, false, null );
+
+ Properties reading = new Properties();
+ readFileInputStream = new FileInputStream( to );
+ reading.load( readFileInputStream );
+ assertEquals( "1.0", reading.get( "version" ) );
+ assertEquals( "org.apache", reading.get( "groupId" ) );
+ assertEquals( "bar", reading.get( "foo" ) );
+ assertEquals( "none filtered", reading.get( "none" ) );
+ }
+ finally
+ {
+ if ( readFileInputStream != null )
+ {
+ readFileInputStream.close();
+ }
+ System.setProperties( allProperties );
+ }
+
+ }
+
+ public void testSimpleNonFiltering()
+ throws Exception
+ {
+ Properties allProperties = System.getProperties();
+ FileInputStream readFileInputStream = null;
+ try
+ {
+ MavenProject mavenProject = new MavenProject();
+ mavenProject.setVersion( "1.0" );
+ mavenProject.setGroupId( "org.apache" );
+ System.setProperty( "foo", "bar" );
+ MavenFileFilter mavenFileFilter = (MavenFileFilter) lookup( MavenFileFilter.class.getName(), "default" );
+
+ File from = new File( getBasedir() + "/src/test/units-files/reflection-test.properties" );
+ File to = new File( getBasedir() + "/target/reflection-test.properties" );
+
+ if (to.exists())
+ {
+ to.delete();
+ }
+
+ mavenFileFilter.copyFile( from, to, false, mavenProject, null, false, null );
+
+ Properties reading = new Properties();
+ readFileInputStream = new FileInputStream( to );
+ reading.load( readFileInputStream );
+ assertEquals( "${pom.version}", reading.get( "version" ) );
+ assertEquals( "${pom.groupId}", reading.get( "groupId" ) );
+ assertEquals( "${foo}", reading.get( "foo" ) );
+ assertEquals( "none filtered", reading.get( "none" ) );
+ }
+ finally
+ {
+ if ( readFileInputStream != null )
+ {
+ readFileInputStream.close();
+ }
+ System.setProperties( allProperties );
+ }
+
+ }
+
+}
diff --git a/src/test/resources/pom.xml b/src/test/resources/pom.xml
new file mode 100755
index 0000000..12f0265
--- /dev/null
+++ b/src/test/resources/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-shared-components</artifactId>
+ <version>8</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-filtering</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-alpha-1-SNAPSHOT</version>
+
+ <name>Maven Files Filtering</name>
+
+ <scm>
+ <connection>scm:svn:https://svn.apache.org/repos/asf/maven/sandbox/trunk/shared/maven-interpolation</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/sandbox/trunk/shared/maven-interpolation</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/sandbox/trunk/shared/maven-interpolation</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <version>1.3.4</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.4.9</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/src/test/units-files/reflection-test.properties b/src/test/units-files/reflection-test.properties
new file mode 100755
index 0000000..022a0a0
--- /dev/null
+++ b/src/test/units-files/reflection-test.properties
@@ -0,0 +1,22 @@
+#/*
+# * 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.
+# */
+version=${pom.version}
+groupId=${pom.groupId}
+foo=${foo}
+none=none filtered
\ No newline at end of file