Author: brett
Date: Wed Apr  5 23:14:10 2006
New Revision: 391910

URL: http://svn.apache.org/viewcvs?rev=391910&view=rev
Log:
[MSITE-72, MSITE-110] improve module parameter location, fix parent 
interpolation in the reactor due to a Maven bug, and improve relative path 
calculation

Modified:
    
maven/plugins/trunk/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/AbstractSiteRenderingMojo.java

Modified: 
maven/plugins/trunk/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/AbstractSiteRenderingMojo.java
URL: 
http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/AbstractSiteRenderingMojo.java?rev=391910&r1=391909&r2=391910&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/AbstractSiteRenderingMojo.java
 (original)
+++ 
maven/plugins/trunk/maven-site-plugin/src/main/java/org/apache/maven/plugins/site/AbstractSiteRenderingMojo.java
 Wed Apr  5 23:14:10 2006
@@ -36,10 +36,11 @@
 import org.apache.maven.doxia.siterenderer.RendererException;
 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
 import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
 import org.apache.maven.reporting.MavenReport;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.IOUtil;
@@ -47,9 +48,10 @@
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -58,6 +60,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.StringTokenizer;
 
 /**
  * Base class for site rendering mojos.
@@ -206,6 +209,13 @@
      */
     protected List reactorProjects;
 
+    /**
+     * Project builder
+     *
+     * @component
+     */
+    private MavenProjectBuilder mavenProjectBuilder;
+
     protected DecorationModel getDecorationModel( MavenProject project, Locale 
locale, Map origProps )
         throws MojoExecutionException
     {
@@ -351,9 +361,11 @@
     private void populateProjectParentMenu( DecorationModel decorationModel, 
Locale locale )
     {
         Menu menu = decorationModel.getMenuRef( "parentProject" );
+
         if ( menu != null )
         {
-            String parentUrl = project.getParent().getUrl();
+            String parentUrl = getParentUrl();
+
             if ( parentUrl != null )
             {
                 if ( parentUrl.endsWith( "/" ) )
@@ -365,6 +377,8 @@
                     parentUrl += "/index.html";
                 }
 
+                parentUrl = getRelativePath( parentUrl, project.getUrl() );
+
                 menu.setName( i18n.getString( "site-plugin", locale, 
"report.menu.parentproject" ) );
 
                 MenuItem item = new MenuItem();
@@ -375,6 +389,51 @@
         }
     }
 
+    /**
+     * Returns the parent POM URL. Attempts to source this value from the 
reactor env
+     * if available (reactor env model attributes are interpolated), or if the
+     * reactor is unavailable (-N) resorts to the project.getParent().getUrl() 
value
+     * which will NOT have be interpolated.
+     *
+     * @return parent project URL.
+     */
+    private String getParentUrl()
+    {
+        String url = null;
+
+        if ( project.getParent() != null )
+        {
+            if ( project.getParent().getArtifactId() != null )
+            {
+                String parentArtifactId = project.getParent().getArtifactId();
+
+                Iterator reactorItr = reactorProjects.iterator();
+
+                while ( reactorItr.hasNext() )
+                {
+                    MavenProject reactorProject = (MavenProject) 
reactorItr.next();
+
+                    String reactorArtifactId = reactorProject.getArtifactId();
+
+                    if ( parentArtifactId.equals( reactorArtifactId ) )
+                    {
+                        url = reactorProject.getUrl();
+                        break;
+                    }
+                }
+            }
+
+            if ( url == null )
+            {
+                // fallback to uninterpolated value
+
+                url = project.getParent().getUrl();
+            }
+        }
+
+        return url;
+    }
+
     private File getSkinArtifactFile( DecorationModel decoration )
         throws MojoFailureException, MojoExecutionException
     {
@@ -554,6 +613,8 @@
 
                 if ( projects.size() == 1 )
                 {
+                    getLog().debug( "Attempting to source module information 
from local filesystem" );
+
                     // Not running reactor - search for the projects manually
                     List models = new ArrayList( project.getModules().size() );
                     for ( Iterator i = project.getModules().iterator(); 
i.hasNext(); )
@@ -563,28 +624,19 @@
                         File f = new File( project.getBasedir(), module + 
"/pom.xml" );
                         if ( f.exists() )
                         {
-                            MavenXpp3Reader reader = new MavenXpp3Reader();
-                            FileReader fileReader = null;
                             try
                             {
-                                fileReader = new FileReader( f );
-                                model = reader.read( fileReader );
-                            }
-                            catch ( IOException e )
-                            {
-                                throw new MojoExecutionException( "Unable to 
read POM", e );
+                                model = mavenProjectBuilder.build( f, 
localRepository, null ).getModel();
                             }
-                            catch ( XmlPullParserException e )
+                            catch ( ProjectBuildingException e )
                             {
-                                throw new MojoExecutionException( "Unable to 
read POM", e );
-                            }
-                            finally
-                            {
-                                IOUtil.close( fileReader );
+                                throw new MojoExecutionException( "Unable to 
read local module-POM", e );
                             }
                         }
                         else
                         {
+                            getLog().warn( "No filesystem module-POM 
available" );
+
                             model = new Model();
                             model.setName( module );
                             model.setUrl( module );
@@ -645,12 +697,16 @@
         }
     }
 
-    private static void appendMenuItem( Menu menu, String name, String href )
+    private void appendMenuItem( Menu menu, String name, String href )
     {
         if ( href != null )
         {
             MenuItem item = new MenuItem();
             item.setName( name );
+
+            String baseUrl = project.getUrl();
+            href = getRelativePath( href, baseUrl );
+
             if ( href.endsWith( "/" ) )
             {
                 item.setHref( href + "index.html" );
@@ -873,4 +929,189 @@
     {
         return list == null || list.isEmpty();
     }
+
+    private String getRelativePath( String to, String from )
+    {
+        URL toUrl = null;
+        URL fromUrl = null;
+
+        String toPath = to;
+        String fromPath = from;
+
+        try
+        {
+            toUrl = new URL( to );
+        }
+        catch ( MalformedURLException e )
+        {
+        }
+
+        try
+        {
+            fromUrl = new URL( from );
+        }
+        catch ( MalformedURLException e )
+        {
+        }
+
+        if ( toUrl != null && fromUrl != null )
+        {
+            // URLs, determine if they share protocol and domain info
+
+            if ( ( toUrl.getProtocol().equalsIgnoreCase( fromUrl.getProtocol() 
) ) &&
+                ( toUrl.getHost().equalsIgnoreCase( fromUrl.getHost() ) ) && ( 
toUrl.getPort() == fromUrl.getPort() ) )
+            {
+                // shared URL domain details, use URI to determine relative 
path
+
+                toPath = toUrl.getFile();
+                fromPath = fromUrl.getFile();
+            }
+            else
+            {
+                // dont share basic URL infomation, no relative available
+
+                return to;
+            }
+        }
+        else if ( ( toUrl != null && fromUrl == null ) || ( toUrl == null && 
fromUrl != null ) )
+        {
+            // one is a URL and the other isnt, no relative available.
+
+            return to;
+        }
+
+        // either the two locations are not URLs or if they are they
+        // share the common protocol and domain info and we are left
+        // with their URI information
+
+        // normalise the path delimters
+
+        toPath = new File( toPath ).getPath();
+        fromPath = new File( fromPath ).getPath();
+
+        // strip any leading slashes if its a windows path
+        if ( toPath.matches( "^\\[a-zA-Z]:" ) )
+        {
+            toPath = toPath.substring( 1 );
+        }
+        if ( fromPath.matches( "^\\[a-zA-Z]:" ) )
+        {
+            fromPath = fromPath.substring( 1 );
+        }
+
+        // lowercase windows drive letters.
+
+        if ( toPath.startsWith( ":", 1 ) )
+        {
+            toPath = toPath.substring( 0, 1 ).toLowerCase() + 
toPath.substring( 1 );
+        }
+        if ( fromPath.startsWith( ":", 1 ) )
+        {
+            fromPath = fromPath.substring( 0, 1 ).toLowerCase() + 
fromPath.substring( 1 );
+        }
+
+        // check for the presence of windows drives. No relative way of
+        // traversing from one to the other.
+
+        if ( ( toPath.startsWith( ":", 1 ) && fromPath.startsWith( ":", 1 ) ) 
&&
+            ( !toPath.substring( 0, 1 ).equals( fromPath.substring( 0, 1 ) ) ) 
)
+        {
+            // they both have drive path element but they dont match, no
+            // relative path
+
+            return to;
+        }
+
+        if ( ( toPath.startsWith( ":", 1 ) && !fromPath.startsWith( ":", 1 ) ) 
||
+            ( !toPath.startsWith( ":", 1 ) && fromPath.startsWith( ":", 1 ) ) )
+        {
+
+            // one has a drive path element and the other doesnt, no relative
+            // path.
+
+            return to;
+
+        }
+
+        // use tokeniser to traverse paths and for lazy checking
+        StringTokenizer toTokeniser = new StringTokenizer( toPath, 
File.separator );
+        StringTokenizer fromTokeniser = new StringTokenizer( fromPath, 
File.separator );
+
+        int count = 0;
+
+        // walk along the to path looking for divergence from the from path
+        while ( toTokeniser.hasMoreTokens() && fromTokeniser.hasMoreTokens() )
+        {
+            if ( File.separatorChar == '\\' )
+            {
+                if ( !fromTokeniser.nextToken().equalsIgnoreCase( 
toTokeniser.nextToken() ) )
+                {
+                    break;
+                }
+            }
+            else
+            {
+                if ( !fromTokeniser.nextToken().equals( 
toTokeniser.nextToken() ) )
+                {
+                    break;
+                }
+            }
+
+            count++;
+        }
+
+        // reinitialise the tokenisers to count positions to retrieve the
+        // gobbled token
+
+        toTokeniser = new StringTokenizer( toPath, File.separator );
+        fromTokeniser = new StringTokenizer( fromPath, File.separator );
+
+        while ( count-- > 0 )
+        {
+            fromTokeniser.nextToken();
+            toTokeniser.nextToken();
+        }
+
+        String relativePath = "";
+
+        // add back refs for the rest of from location.
+        while ( fromTokeniser.hasMoreTokens() )
+        {
+            fromTokeniser.nextToken();
+
+            relativePath += "..";
+
+            if ( fromTokeniser.hasMoreTokens() )
+            {
+                relativePath += File.separatorChar;
+            }
+        }
+
+        if ( relativePath.length() != 0 && toTokeniser.hasMoreTokens() )
+        {
+            relativePath += File.separatorChar;
+        }
+
+        // add fwd fills for whatevers left of to.
+        while ( toTokeniser.hasMoreTokens() )
+        {
+            relativePath += toTokeniser.nextToken();
+
+            if ( toTokeniser.hasMoreTokens() )
+            {
+                relativePath += File.separatorChar;
+            }
+        }
+
+        if ( !relativePath.equals( to ) )
+        {
+            getLog().debug( "Mapped url: " + to + " to relative path: " + 
relativePath );
+        }
+
+        return relativePath;
+    }
+
+
 }
+
+


Reply via email to