Index: maven-project/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java =================================================================== --- maven-project/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java (revision 640217) +++ maven-project/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java (working copy) @@ -21,6 +21,7 @@ import org.apache.maven.model.Build; import org.apache.maven.model.Model; +import org.apache.maven.model.Reporting; import org.apache.maven.model.Resource; import java.io.File; @@ -28,11 +29,18 @@ import java.util.Iterator; import java.util.List; +/** + * The default implementation of {@link PathTranslator}. + * + * @version $Id$ + */ public class DefaultPathTranslator implements PathTranslator { - private String FILE_SEPARATOR = "/"; + /** + * {@inheritDoc} + */ public void alignToBaseDirectory( Model model, File basedir ) { Build build = model.getBuild(); @@ -45,6 +53,8 @@ build.setTestSourceDirectory( alignToBaseDirectory( build.getTestSourceDirectory(), basedir ) ); + build.setScriptSourceDirectory( alignToBaseDirectory( build.getScriptSourceDirectory(), basedir ) ); + for ( Iterator i = build.getResources().iterator(); i.hasNext(); ) { Resource resource = (Resource) i.next(); @@ -75,55 +85,42 @@ build.setTestOutputDirectory( alignToBaseDirectory( build.getTestOutputDirectory(), basedir ) ); } - } - public String alignToBaseDirectory( String path, File basedir ) - { - String s = stripBasedirToken( path ); + Reporting reporting = model.getReporting(); - if ( requiresBaseDirectoryAlignment( s ) ) + if ( reporting != null ) { - s = new File( basedir, s ).getAbsolutePath(); + reporting.setOutputDirectory( alignToBaseDirectory( reporting.getOutputDirectory(), basedir ) ); } - - return s; } - private String stripBasedirToken( String s ) + /** + * {@inheritDoc} + */ + public String alignToBaseDirectory( String path, File basedir ) { - if ( s != null ) + if ( path != null ) { - s = s.trim(); + path = path.trim(); - if ( s.startsWith( "${basedir}" ) ) + String base = "${basedir}"; + if ( path.startsWith( base ) ) { - // Take out ${basedir} and the leading slash - s = s.substring( 11 ); + path = chopLeadingFileSeparator( path.substring( base.length() ) ); } - } - return s; - } - - private boolean requiresBaseDirectoryAlignment( String s ) - { - if ( s != null ) - { - File f = new File( s ); - - if ( s.startsWith( FILE_SEPARATOR ) || f.isAbsolute() ) + if ( !path.startsWith( "/" ) && !new File( path ).isAbsolute() ) { - return false; + path = new File( basedir.getAbsolutePath(), path ).getAbsolutePath(); } - else - { - return true; - } } - return false; + return path; } + /** + * {@inheritDoc} + */ public void unalignFromBaseDirectory( Model model, File basedir ) { Build build = model.getBuild(); @@ -136,6 +133,8 @@ build.setTestSourceDirectory( unalignFromBaseDirectory( build.getTestSourceDirectory(), basedir ) ); + build.setScriptSourceDirectory( unalignFromBaseDirectory( build.getScriptSourceDirectory(), basedir ) ); + for ( Iterator i = build.getResources().iterator(); i.hasNext(); ) { Resource resource = (Resource) i.next(); @@ -166,17 +165,55 @@ build.setTestOutputDirectory( unalignFromBaseDirectory( build.getTestOutputDirectory(), basedir ) ); } + + Reporting reporting = model.getReporting(); + + if ( reporting != null ) + { + reporting.setOutputDirectory( unalignFromBaseDirectory( reporting.getOutputDirectory(), basedir ) ); + } } - public String unalignFromBaseDirectory( String directory, File basedir ) + /** + * {@inheritDoc} + */ + public String unalignFromBaseDirectory( String path, File basedir ) { - String path = basedir.getPath(); - if ( directory.startsWith( path ) ) + if ( path != null ) { - directory = directory.substring( path.length() + 1 ).replace( '\\', '/' ); + path = path.trim(); + + String base = basedir.getAbsolutePath(); + if ( path.startsWith( base ) ) + { + path = chopLeadingFileSeparator( path.substring( base.length() ) ); + } + + if ( !new File( path ).isAbsolute() ) + { + path = path.replace( '\\', '/' ); + } } - return directory; + return path; } + /** + * Removes the leading directory separator from the specified filesystem path (if any). For platform-independent + * behavior, this method accepts both the forward slash and the backward slash as separator. + * + * @param path The filesystem path, may be null. + * @return The altered filesystem path or null if the input path was null. + */ + private String chopLeadingFileSeparator( String path ) + { + if ( path != null ) + { + if ( path.startsWith( "/" ) || path.startsWith( "\\" ) ) + { + path = path.substring( 1 ); + } + } + return path; + } + } - Index: maven-project/src/main/java/org/apache/maven/project/path/PathTranslator.java =================================================================== --- maven-project/src/main/java/org/apache/maven/project/path/PathTranslator.java (revision 640217) +++ maven-project/src/main/java/org/apache/maven/project/path/PathTranslator.java (working copy) @@ -24,18 +24,62 @@ import java.io.File; /** + * Provides resolution and relativization for filesystem paths against an arbitrary base directory. + * * @author Jason van Zyl * @version $Id$ */ public interface PathTranslator { + + /** + * The role name for this component, used by the Plexus container to lookup implementations. + */ String ROLE = PathTranslator.class.getName(); + /** + * Resolves all well-known filesystem paths in the specified project model against the given base directory if + * necessary to enforce absolute paths. + * + * @param model The project model whose paths should be aligned to the base directory, must not be null. + * @param basedir The absolute path to the base directory used to resolve a relative path against, must not be + * null. + */ void alignToBaseDirectory( Model model, File basedir ); + /** + * Resolves the specified filesystem path against the given base directory if necessary. + * + * @param path The path to resolve, may be null. + * @param basedir The absolute path to the base directory used to resolve the input path against, must not be + * null. + * @return The absolute filesystem path corresponding to the input path or null if the input path was + * null. The returned path will always use the system-dependent file separator as reported + * by {@link java.io.File#separatorChar}. + */ String alignToBaseDirectory( String path, File basedir ); + /** + * Relativizes all well-known filesystem paths in the specified project model to the given base directory if + * possible. + * + * @param model The project model whose paths should be unaligned from the base directory, must not be + * null. + * @param basedir The absolute path to the base directory used to relativize an absolute path to, must not be + * null. + */ void unalignFromBaseDirectory( Model model, File basedir ); - String unalignFromBaseDirectory( String directory, File basedir ); + /** + * Relativizes the specified filesystem path to the given base directory if possible. + * + * @param path The path to relativize, may be null. + * @param basedir The absolute path to the base directory used to relativize the input path to, must not be + * null. + * @return The relative filesystem path corresponding to the input path if relativization was possible, the absolute + * path if it was not and null if the input path was null. The relative paths + * returned will always use the forward slash as file separator. + */ + String unalignFromBaseDirectory( String path, File basedir ); + } Index: maven-project/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java =================================================================== --- maven-project/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java (revision 0) +++ maven-project/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java (revision 0) @@ -0,0 +1,324 @@ +package org.apache.maven.project.path; + +/* + * 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.File; +import java.util.Collections; + +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Resource; + +import junit.framework.TestCase; + +/** + * Tests {@link DefaultPathTranslator}. + * + * @version $Id$ + */ +public class DefaultPathTranslatorTest + extends TestCase +{ + + private PathTranslator pathTranslator; + + private File baseDir; + + public void setUp() + throws Exception + { + super.setUp(); + + this.pathTranslator = new DefaultPathTranslator(); + this.baseDir = new File( System.getProperty( "java.io.tmpdir" ), "path-translator" ).getAbsoluteFile(); + } + + private String absolute( String path ) + { + return new File( this.baseDir, path ).getAbsolutePath(); + } + + private String align( String path ) + { + return this.pathTranslator.alignToBaseDirectory( path, this.baseDir ); + } + + private String unalign( String path ) + { + return this.pathTranslator.unalignFromBaseDirectory( path, this.baseDir ); + } + + public void testAlignToBaseDirectoryNullBaseDir() + { + try + { + this.pathTranslator.alignToBaseDirectory( "path", null ); + fail( "path translation did not fail" ); + } + catch ( Exception e ) + { + // expected + } + } + + public void testAlignToBaseDirectoryNullPath() + { + try + { + assertNull( align( null ) ); + } + catch ( Exception e ) + { + fail( "null path was not accepted" ); + } + } + + public void testAlignToBaseDirectoryRelativePath() + { + String expectedPath = absolute( "target" ); + assertEquals( expectedPath, align( "target" ) ); + + expectedPath = this.baseDir.getAbsolutePath(); + assertEquals( expectedPath, align( "" ) ); + } + + public void testAlignToBaseDirectoryAbsolutePath() + { + String expectedPath = new File( "somedir" ).getAbsolutePath(); + assertEquals( expectedPath, align( expectedPath ) ); + } + + public void testAlignToBaseDirectoryAbsolutePathWithBasedirExpression() + { + String expectedPath = absolute( "target" ); + assertEquals( expectedPath, align( "${basedir}" + File.separatorChar + "target" ) ); + } + + public void testAlignToBaseDirectoryBasedirExpression() + { + String expectedPath = this.baseDir.getAbsolutePath(); + assertEquals( expectedPath, align( "${basedir}" ) ); + } + + public void testAlignToBaseDirectoryFileSeparatorNormalization() + { + String expectedPath = absolute( "target/classes" ); + assertEquals( expectedPath, align( "target/classes" ) ); + } + + public void testAlignToBaseDirectoryNullModel() + { + try + { + this.pathTranslator.alignToBaseDirectory( (Model) null, this.baseDir ); + fail( "path translation did not fail" ); + } + catch ( Exception e ) + { + // expected + } + } + + public void testAlignToBaseDirectoryModel() + { + Resource mainResource = new Resource(); + mainResource.setDirectory( "src/main/resources" ); + + Resource testResource = new Resource(); + testResource.setDirectory( "src/test/resources" ); + + Build build = new Build(); + build.setDirectory( "target" ); + build.setOutputDirectory( "target/classes" ); + build.setTestOutputDirectory( "target/test-classes" ); + build.setSourceDirectory( "src/main/java" ); + build.setTestSourceDirectory( "src/test/java" ); + build.setScriptSourceDirectory( "src/main/scripts" ); + build.setResources( Collections.singletonList( mainResource ) ); + build.setTestResources( Collections.singletonList( testResource ) ); + + Reporting reporting = new Reporting(); + reporting.setOutputDirectory( "target/site" ); + + Model model = new Model(); + model.setBuild( build ); + model.setReporting( reporting ); + + this.pathTranslator.alignToBaseDirectory( model, this.baseDir ); + + assertEquals( absolute( "target" ), build.getDirectory() ); + assertEquals( absolute( "target/classes" ), build.getOutputDirectory() ); + assertEquals( absolute( "target/test-classes" ), build.getTestOutputDirectory() ); + assertEquals( absolute( "src/main/java" ), build.getSourceDirectory() ); + assertEquals( absolute( "src/test/java" ), build.getTestSourceDirectory() ); + assertEquals( absolute( "src/main/scripts" ), build.getScriptSourceDirectory() ); + assertEquals( absolute( "src/main/resources" ), ( (Resource) build.getResources().get( 0 ) ).getDirectory() ); + assertEquals( absolute( "src/test/resources" ), ( (Resource) build.getTestResources().get( 0 ) ).getDirectory() ); + assertEquals( absolute( "target/site" ), reporting.getOutputDirectory() ); + } + + public void testUnalignFromBaseDirectoryNullBaseDir() + { + try + { + this.pathTranslator.unalignFromBaseDirectory( "path", null ); + fail( "path translation did not fail" ); + } + catch ( Exception e ) + { + // expected + } + } + + public void testUnalignFromBaseDirectoryNullPath() + { + try + { + assertNull( unalign( null ) ); + } + catch ( Exception e ) + { + fail( "null path was not accepted" ); + } + } + + public void testUnalignFromBaseDirectoryRelativePath() + { + String expectedPath = "target"; + assertEquals( expectedPath, unalign( "target" ) ); + } + + public void testUnalignFromBaseDirectoryAbsolutePath() + { + String expectedPath = new File( "somedir" ).getAbsolutePath(); + assertEquals( expectedPath, unalign( expectedPath ) ); + + expectedPath = "target"; + assertEquals( expectedPath, unalign( absolute( "target" ) ) ); + + expectedPath = ""; + assertEquals( expectedPath, unalign( this.baseDir.getAbsolutePath() ) ); + } + + public void testUnalignFromBaseDirectoryAbsolutePathWithBasedirExpression() + { + String expectedPath = "${basedir}/target"; + assertEquals( expectedPath, unalign( "${basedir}/target" ) ); + } + + public void testUnalignFromBaseDirectoryBasedirExpression() + { + String expectedPath = "${basedir}"; + assertEquals( expectedPath, unalign( "${basedir}" ) ); + } + + public void testUnalignFromBaseDirectoryFileSeparatorNormalization() + { + String expectedPath = "target/classes"; + assertEquals( expectedPath, unalign( absolute( "target" + File.separator + "classes" ) ) ); + } + + public void testUnalignFromBaseDirectoryNullModel() + { + try + { + this.pathTranslator.unalignFromBaseDirectory( (Model) null, this.baseDir ); + fail( "path translation did not fail" ); + } + catch ( Exception e ) + { + // expected + } + } + + public void testUnalignFromBaseDirectoryModel() + { + Resource mainResource = new Resource(); + mainResource.setDirectory( absolute( "src/main/resources" ) ); + + Resource testResource = new Resource(); + testResource.setDirectory( absolute( "src/test/resources" ) ); + + Build build = new Build(); + build.setDirectory( absolute( "target" ) ); + build.setOutputDirectory( absolute( "target/classes" ) ); + build.setTestOutputDirectory( absolute( "target/test-classes" ) ); + build.setSourceDirectory( absolute( "src/main/java" ) ); + build.setTestSourceDirectory( absolute( "src/test/java" ) ); + build.setScriptSourceDirectory( absolute( "src/main/scripts" ) ); + build.setResources( Collections.singletonList( mainResource ) ); + build.setTestResources( Collections.singletonList( testResource ) ); + + Reporting reporting = new Reporting(); + reporting.setOutputDirectory( absolute( "target/site" ) ); + + Model model = new Model(); + model.setBuild( build ); + model.setReporting( reporting ); + + this.pathTranslator.unalignFromBaseDirectory( model, this.baseDir ); + + assertEquals( "target", build.getDirectory() ); + assertEquals( "target/classes", build.getOutputDirectory() ); + assertEquals( "target/test-classes", build.getTestOutputDirectory() ); + assertEquals( "src/main/java", build.getSourceDirectory() ); + assertEquals( "src/test/java", build.getTestSourceDirectory() ); + assertEquals( "src/main/scripts", build.getScriptSourceDirectory() ); + assertEquals( "src/main/resources", ( (Resource) build.getResources().get( 0 ) ).getDirectory() ); + assertEquals( "src/test/resources", ( (Resource) build.getTestResources().get( 0 ) ).getDirectory() ); + assertEquals( "target/site", reporting.getOutputDirectory() ); + } + + public void testAlignUnalign() + { + assertNull( unalign( align( null ) ) ); + + String expectedPath = ""; + assertEquals( expectedPath, unalign( align( expectedPath ) ) ); + + expectedPath = "target"; + assertEquals( expectedPath, unalign( align( expectedPath ) ) ); + + expectedPath = "src/main/java"; + assertEquals( expectedPath, unalign( align( expectedPath ) ) ); + + expectedPath = "."; + assertEquals( expectedPath, unalign( align( expectedPath ) ) ); + } + + public void testUnalignAlign() + { + assertNull( align( unalign( null ) ) ); + + String expectedPath = this.baseDir.getAbsolutePath(); + assertEquals( expectedPath, align( unalign( expectedPath ) ) ); + + expectedPath = new File( this.baseDir, "target" ).getAbsolutePath(); + assertEquals( expectedPath, align( unalign( expectedPath ) ) ); + + expectedPath = new File( this.baseDir, "src/main/java" ).getAbsolutePath(); + assertEquals( expectedPath, align( unalign( expectedPath ) ) ); + + expectedPath = new File( this.baseDir, "." ).getAbsolutePath(); + assertEquals( expectedPath, align( unalign( expectedPath ) ) ); + } + +} Property changes on: maven-project\src\test\java\org\apache\maven\project\path\DefaultPathTranslatorTest.java ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native