I've been looking at Maven for same time, and finally last month I've adopted it as
comprehensive build tool for my team (migrating from ant).
I joined the mailing list because I'd like to get involved in this project.


While studying the source code of the project I developed a couple of ideas:

1 The mapping between an artifact type and its extension should be a 1 to many relation
for example:
type jar extensions jar,zip
type distribution extensions zip,gz,tar.gz


Regarding this I found an interesting issue
http://jira.codehaus.org/ViewIssue.jspa?key=MAVEN-670

the actual mapping may be resolved runtime looking up the various repositories
and picking up the first match. This would solve the above issue and open up a
lot of other possibilities:  dependencies from images or documents of various
kind, etc.

For this thing I wrote a patch from the MAVEN_RC1_STABLE branch (attached)


2 I think that a Dependency object should really be able to download itself
Index: .classpath
===================================================================
RCS file: .classpath
diff -N .classpath
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ .classpath  16 Aug 2003 14:07:51 -0000
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path=""/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="output" path=""/>
+</classpath>
Index: .project
===================================================================
RCS file: .project
diff -N .project
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ .project    16 Aug 2003 14:07:51 -0000
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>maven</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
Index: org/apache/maven/project/ArtifactType.java
===================================================================
RCS file: 
/home/cvspublic/maven/src/java/org/apache/maven/project/Attic/ArtifactType.java,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 ArtifactType.java
--- org/apache/maven/project/ArtifactType.java  14 Aug 2003 06:32:32 -0000      1.1.2.1
+++ org/apache/maven/project/ArtifactType.java  16 Aug 2003 14:07:51 -0000
@@ -69,13 +69,24 @@
         * EJB artifact mapping.
         */
        public static final ArtifactType EJB = new ArtifactType("ejb", "jar");
+       
+       /**
+        * Plugin artifact mapping.
+        */
+       public static final ArtifactType PLUGIN = new ArtifactType("plugin", "jar");   
 
 
-    /**
-     * Plugin artifact mapping.
-     */
-    public static final ArtifactType PLUGIN = new ArtifactType("plugin", "jar");
+       /**
+        * JAr artifact mapping: jar and zip (legacy)
+        */
+       public static final ArtifactType JAR = new ArtifactType("jar", "jar,zip");
+       
+       /** Example */
+       public static final ArtifactType IMAGE = new ArtifactType("image", 
"jpeg,jpg,gif");
        
-    /**
+       /** Distribution type mapping */
+       public static final ArtifactType DISTRIB = new ArtifactType("distribution", 
"zip,gz,tar.gz");
+       
+       /**
         * Artifact type.
         */
        private String type;
@@ -129,10 +140,22 @@
                {
                        result = EJB;   
                }
-        else if (type.equalsIgnoreCase("plugin"))
-        {
-            result = PLUGIN;   
-        }
+               else if (type.equalsIgnoreCase("plugin"))
+               {
+                       result = PLUGIN;   
+               }
+               else if (type.equalsIgnoreCase("jar"))
+               {
+                       result = JAR;   
+               }
+               else if (type.equalsIgnoreCase("image"))
+               {
+                       result = IMAGE; 
+               }
+               else if (type.equalsIgnoreCase("distribution"))
+               {
+                       result = DISTRIB;   
+               }
                else
                {
                        result = new ArtifactType(type, type);
Index: org/apache/maven/project/Dependency.java
===================================================================
RCS file: /home/cvspublic/maven/src/java/org/apache/maven/project/Dependency.java,v
retrieving revision 1.34.2.1
diff -u -r1.34.2.1 Dependency.java
--- org/apache/maven/project/Dependency.java    14 Aug 2003 00:51:12 -0000      
1.34.2.1
+++ org/apache/maven/project/Dependency.java    16 Aug 2003 14:07:52 -0000
@@ -56,6 +56,17 @@
  * ====================================================================
  */
 
+import java.io.File;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.lang.StringUtils;
+
+import org.apache.maven.util.HttpUtils;
+
+
 /**
  * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
  * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Massol</a>
@@ -64,6 +75,9 @@
 public class Dependency
     extends BaseObject
 {
+       /** Platform specific file separator used for file system operations. */
+       private static final String ps = File.separator;
+       
     /** Version associated with this dependency */
     private String version;
 
@@ -82,6 +96,15 @@
     /** The dependency type */
     private ArtifactType type;
 
+       /** Whether the extension has been determined or not*/
+       private boolean extensionResolved = false;
+
+       /** The actual extension of this Dependency */
+       private String actualExtension;
+
+       /** The project which contains this Dependency */
+       private Project project;                
+       
     /** Flag to indicate the artifact is poorly named. */
     //private boolean isPoorlyNamed = false;
 
@@ -90,6 +113,8 @@
      */
     public Dependency()
     {
+       // Default type
+               setType( "jar");
     }
 
     /**
@@ -263,6 +288,7 @@
         }
 
         this.jar = jar;
+               extensionResolved = true;        
     }
 
     /**
@@ -316,13 +342,11 @@
         */
        public String getExtension()
        {
-               String result = null;
-               
-               if (this.type != null)
+               if (!extensionResolved) 
                {
-                       result = this.type.getExtension(); 
+                       resolveExtension();
                }
-               return result;
+               return actualExtension;
        }
        
     /**
@@ -333,6 +357,22 @@
     public void setType( String type )
     {
         this.type = ArtifactType.findType(type);
+        
+        if (this.type == null)
+        {
+                       actualExtension = null;
+                       extensionResolved = true;
+               return;
+        }
+        
+               // ArtifactType.getExtension() may return a csv list of extensions; if 
this is not the case
+               // extension is already determined
+               if (this.type.getExtension().indexOf(",") < 0) 
+               {
+                       actualExtension = this.type.getExtension();
+                       extensionResolved = true;
+               }
+               
     }
 
     /**
@@ -346,6 +386,113 @@
             + " ver:" + getVersion() + " ar:" + getArtifact() + " jar:"
             + getJar() + " ]";
     }
+
+       /**
+        * Determines the actual extension of the present Dependency looking up local
+        * and remote repositories for a file with the same base name and the various
+        * extensions returnes by ArtifacType.getExtension()
+        *
+        */    
+    private void resolveExtension () 
+    {
+       
+       String extensions = this.type.getExtension();
+       StringTokenizer st = new StringTokenizer(extensions, ",");
+               boolean found = false;
+               String candidateExt=null;
+               
+               // For every extension available look up locally
+               while (st.hasMoreTokens() && !found )
+               {
+                       candidateExt = st.nextToken();
+                       
+                       String filePath = getPathWithoutExt() + "." + candidateExt;
+                                       
+                       File f = new File(filePath);
+                       found = f.exists();
+               }
+                                       
+               // For every extension available look up in remote repositories
+               st = new StringTokenizer(extensions, ",");
+       while (st.hasMoreTokens() && !found )
+       {
+               candidateExt = st.nextToken();
+                       
+                       String URLpath = getUrlPathWithoutExt() + "." + candidateExt;
+                       
+                       // Check every repository
+                       for ( Iterator i = 
getProject().getContext().getMavenRepoRemote().iterator(); i.hasNext(); )
+                       {            
+                               String remoteRepo = (String) i.next();
+
+                               // The username and password parameters are not being
+                               // used here. Those are the "" parameters you see 
below.
+                               String url = remoteRepo + "/" + URLpath;
+                               url = StringUtils.replace( url, "//", "/" );
+                               url = StringUtils.replace( url, "http:/", "http://"; );
+ 
+                               try 
+                               {
+                                       found = HttpUtils.checkFile(url,
+                                                                                      
         getProject().getContext().getProxyHost(),
+                                                                                      
         getProject().getContext().getProxyPort(),
+                                                                                      
         getProject().getContext().getProxyUserName(),
+                                                                                      
         getProject().getContext().getProxyPassword());                                
                                                          
+                               } 
+                               catch (Exception e) 
+                               {
+                                       // exception means not found
+                               }
+                               
+                               if (found) 
+                               {
+                                       break;
+                               } 
+                               
+                       }
+                
+       }
+       if (found)
+       {
+               this.actualExtension = candidateExt;
+       }
+               extensionResolved = true;       
+    }
+    
+    
+    /**
+     * Set the project
+        * @param p the project
+        */
+       public void setProject(Project p) 
+       {
+       this.project = p;
+    }
+    
+       /**
+        * Set the project
+        * @param p the project
+        */
+       public Project getProject() 
+       {
+               return this.project;
+       }
+
+       
+       private String getPathWithoutExt()
+       {
+               return project.getContext().getMavenRepoLocal() + ps + 
getArtifactDirectory()
+                               + ps + getType() + "s" + ps + getArtifactId() + "-" + 
getVersion();
+                                       
+       }
+
+       
+       private String getUrlPathWithoutExt()
+       {
+               return  "/" + getArtifactDirectory() + "/" + getType() + "s" +
+                               "/" + getArtifactId() + "-" + getVersion();
+       }
+    
 
     /**
      * Usually only jars and ejbs are added to the classpath
Index: org/apache/maven/project/Project.java
===================================================================
RCS file: /home/cvspublic/maven/src/java/org/apache/maven/project/Project.java,v
retrieving revision 1.83.2.4
diff -u -r1.83.2.4 Project.java
--- org/apache/maven/project/Project.java       14 Aug 2003 09:54:05 -0000      
1.83.2.4
+++ org/apache/maven/project/Project.java       16 Aug 2003 14:07:54 -0000
@@ -1300,6 +1300,7 @@
 
         setAntProject( AntProjectBuilder.build( this ) );
         getContext().setAntProject( getAntProject() );
+        initializeDependencies();
         buildArtifactList();
         buildDependencyClasspath();
         setDependencyVerifier( new DependencyVerifier( this ) );
@@ -1309,6 +1310,15 @@
         initialized = true;
     }
 
+       private void initializeDependencies(){
+
+               for ( Iterator i = getDependencies().iterator(); i.hasNext(); )
+               {
+                       Dependency d = (Dependency) i.next();
+                       d.setProject(this);
+               }               
+       }
+       
     /**
      * Set the grantProject attribute.
      *
Index: org/apache/maven/util/HttpUtils.java
===================================================================
RCS file: /home/cvspublic/maven/src/java/org/apache/maven/util/HttpUtils.java,v
retrieving revision 1.26
diff -u -r1.26 HttpUtils.java
--- org/apache/maven/util/HttpUtils.java        17 May 2003 23:30:33 -0000      1.26
+++ org/apache/maven/util/HttpUtils.java        16 Aug 2003 14:07:55 -0000
@@ -330,6 +330,96 @@
         }
     }
 
+       /**
+        * Check the existence of a remote file.  Returns true if the file was found
+        *
+        * @param url the of the file to retrieve
+     * @param proxyHost Proxy Host (if proxy is required), or null
+     * @param proxyPort Proxy Port (if proxy is required), or null
+     * @param proxyUserName Proxy Username (if authentification is required),
+     *        or null
+     * @param proxyPassword Proxy Password (if authentification is required),
+     *        or null
+        */
+       public static boolean checkFile( String url,
+                                                                       String 
proxyHost,
+                                                                       String 
proxyPort,
+                                                                       String 
proxyUserName,
+                                                                       String 
proxyPassword )
+               throws Exception
+       {
+               String[] s = parseUrl( url );
+               String username = s[0];
+               String password = s[1];
+               String parsedUrl = s[2];
+
+               URL source = new URL( parsedUrl );
+
+               //set proxy connection
+               useProxyUser( proxyHost, proxyPort, proxyUserName, proxyPassword );
+
+               //set up the URL connection
+               URLConnection connection = source.openConnection();
+
+               //NB: things like user authentication could go in here too.
+               // prepare Java 1.1 style credentials   
+               if ( username != null || password != null )
+               {
+                       String up = username + ":" + password;
+                       String encoding = null;
+                       // check to see if sun's Base64 encoder is available.
+                       try
+                       {
+                               sun.misc.BASE64Encoder encoder =
+                                       (sun.misc.BASE64Encoder) Class.forName(
+                                               "sun.misc.BASE64Encoder" 
).newInstance();
+
+                               encoding = encoder.encode( up.getBytes() );
+                       }
+                       catch ( Exception ex )
+                       {
+                               // Do nothing, as for MavenSession we will never use
+                               // auth and we will eventually move over httpclient
+                               // in the commons.
+                       }
+                       connection.setRequestProperty( "Authorization", "Basic " + 
encoding );
+               }
+
+               // If it is an HTTP connection then just use the HEAD method since we 
don't need
+               // the content here. 
+               if ( connection instanceof HttpURLConnection )
+               {
+                       HttpURLConnection httpConnection = (HttpURLConnection) 
connection;
+                       httpConnection.setRequestMethod("HEAD");
+               }               
+               
+               //connect to the remote site (may take some time)               
+               try {
+                       connection.connect();
+               } catch (IOException e) {
+                       return false;
+               }
+               //next test for a 304 result (HTTP only)
+               if ( connection instanceof HttpURLConnection )
+               {
+                       HttpURLConnection httpConnection = (HttpURLConnection) 
connection;
+                       if ( httpConnection.getResponseCode() == 
HttpURLConnection.HTTP_NOT_MODIFIED )
+                       {
+                               return true;
+                       }
+                       if ( httpConnection.getResponseCode() == 
HttpURLConnection.HTTP_NOT_FOUND )
+                       {
+                               return false;
+                       }
+                       // test for 401 result (HTTP only)
+                       if ( httpConnection.getResponseCode() == 
HttpURLConnection.HTTP_UNAUTHORIZED )
+                       {
+                               throw new Exception( "Not authorized." );
+                       }
+               }
+               return true;
+       }
+
     /**
      * Parse an url which might contain a username and password. If the
      * given url doesn't contain a username and password then return the

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to