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]
