Author: jdcasey
Date: Fri Mar  3 20:23:52 2006
New Revision: 383022

URL: http://svn.apache.org/viewcvs?rev=383022&view=rev
Log:
(Merged from 382881.) This is a more robust solution to MNG-2006. Unit test 
addition to follow.

Modified:
    
maven/components/branches/maven-2.0.x/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java

Modified: 
maven/components/branches/maven-2.0.x/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java
URL: 
http://svn.apache.org/viewcvs/maven/components/branches/maven-2.0.x/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java?rev=383022&r1=383021&r2=383022&view=diff
==============================================================================
--- 
maven/components/branches/maven-2.0.x/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java
 (original)
+++ 
maven/components/branches/maven-2.0.x/maven-project/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java
 Fri Mar  3 20:23:52 2006
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -485,98 +486,75 @@
     // TODO: This should eventually be migrated to DefaultPathTranslator.
     protected String appendPath( String parentPath, String childPath, String 
pathAdjustment, boolean appendPaths )
     {
-        List pathFragments = new ArrayList();
-
-        String rootPath = parentPath;
-
-        String protocol = null;
-        int protocolIdx = rootPath.indexOf( "://" );
-
-        if ( protocolIdx > -1 )
-        {
-            protocol = rootPath.substring( 0, protocolIdx + 3 );
-            rootPath = rootPath.substring( protocolIdx + 3 );
-        }
-
-        pathFragments.add( rootPath );
+        String uncleanPath = parentPath;
 
         if ( appendPaths )
         {
             if ( pathAdjustment != null )
-            {
-                pathFragments.add( pathAdjustment );
-            }
+                uncleanPath += "/" + pathAdjustment;
 
             if ( childPath != null )
-            {
-                pathFragments.add( childPath );
-            }            
+                uncleanPath += "/" + childPath;
         }
 
-        StringBuffer cleanedPath = new StringBuffer();
+        String cleanedPath = "";
 
-        if ( protocol != null )
-        {
-            cleanedPath.append( protocol );
-        }
+        int protocolIdx = uncleanPath.indexOf( "://" );
 
-        if ( rootPath.startsWith( "/" ) )
+        if ( protocolIdx > -1 )
         {
-            cleanedPath.append( '/' );
+            cleanedPath = uncleanPath.substring( 0, protocolIdx + 3 );
+            uncleanPath = uncleanPath.substring( protocolIdx + 3 );
         }
 
-        String lastToken = null;
-        String currentToken = null;
+        if ( uncleanPath.startsWith( "/" ) )
+            cleanedPath += "/";
 
-        for ( Iterator it = pathFragments.iterator(); it.hasNext(); )
-        {
-            String pathFragment = (String) it.next();
+        return cleanedPath + resolvePath( uncleanPath );
+    }
 
-            StringTokenizer tokens = new StringTokenizer( pathFragment, "/" );
+    // TODO: Move this to plexus-utils' PathTool.
+    private static String resolvePath( String uncleanPath )
+    {
+        LinkedList pathElements = new LinkedList();
 
-            while ( tokens.hasMoreTokens() )
-            {
-                lastToken = currentToken;
-                currentToken = tokens.nextToken();
+        StringTokenizer tokenizer = new StringTokenizer( uncleanPath, "/" );
 
-                if ( "..".equals( currentToken ) && lastToken != null )
+        while ( tokenizer.hasMoreTokens() )
+        {
+            String token = (String) tokenizer.nextToken();
+
+            if ( token.equals( "" ) )
+            {
+                // Empty path entry ("...//.."), remove.
+            }
+            else if ( token.equals( ".." ) )
+            {
+                if ( pathElements.isEmpty() )
                 {
-                    int cleanedPathLen = cleanedPath.length();
-                    int lastTokenLen = lastToken.length();
-                    
-                    if ( cleanedPathLen > lastTokenLen )
-                    {
-                        // trim the previous path part off...
-                        cleanedPath.setLength( cleanedPath.length() - ( 
lastToken.length() + 1 ) );
-                    }
+                    // FIXME: somehow report to the user
+                    // that there are too many '..' elements.
+                    // For now, ignore the extra '..'.
                 }
-                else if ( !".".equals( currentToken ) )
+                else
                 {
-                    // don't worry about /./ self-references.
-                    cleanedPath.append( currentToken ).append( '/' );
+                    pathElements.removeLast();
                 }
             }
+            else
+            {
+                pathElements.addLast( token );
+            }
         }
 
-        String lastPathPart = childPath;
-        if ( lastPathPart == null )
-        {
-            lastPathPart = pathAdjustment;
-        }
-        
-        if ( lastPathPart == null )
-        {
-            lastPathPart = parentPath;
-        }
-        
-        if ( appendPaths && lastPathPart != null && !lastPathPart.endsWith( 
"/" ) )
+
+        StringBuffer cleanedPath = new StringBuffer();
+
+        while ( !pathElements.isEmpty() )
         {
-            int cleanedPathLen = cleanedPath.length();
-            
-            if ( cleanedPathLen > 0 )
-            {
-                cleanedPath.setLength( cleanedPathLen - 1 );
-            }            
+            cleanedPath.append( pathElements.removeFirst() );
+            if ( !pathElements.isEmpty() )
+                cleanedPath.append( '/' );
         }
 
         return cleanedPath.toString();


Reply via email to