maven-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From baerr...@apache.org
Subject svn commit: r696566 - in /maven/plugins/trunk/maven-eclipse-plugin/src: main/java/org/apache/maven/plugin/eclipse/writers/ test/resources/projects/project-rad-8/ test/resources/projects/project-rad-8/src/ test/resources/projects/project-rad-8/src/main/...
Date Thu, 18 Sep 2008 05:53:07 GMT
Author: baerrach
Date: Wed Sep 17 22:53:07 2008
New Revision: 696566

URL: http://svn.apache.org/viewvc?rev=696566&view=rev
Log:
[MECLIPSE-423] Fix NullPointerException when existing Manifest.MF file has no Class-Path element

EclipseManifestWriter and RadManifestWriter are a cut-and-paste. Created AbstractEclipseManifestWriter
as shared parent class
and moved all the common stuff up.  Where the code varied EclipseManifestWriter's implementation
was chosen.  This was because the variation was often a bug fix.  

The only variation that could not be easily sorted was in addDependencyToClassPath where they
only differ at the end:
	EclipseManifestWriter:
		classpath.append( dependency.getEclipseProjectName() + ".jar" );
	RadManifestWriter
		classpath.append( dependency.getArtifactId() + ".jar" );
I have taken the eclipse one as being correct and changed RadPlugin to override getProjectNameForArifact()
to return artifact.getArtifactId() to match RadManifestWriter dependency.getArtifactId() as
above.  Integration tests still work but I need a RAD person to validate this for me.

Added testProject8 for IT test. Prior to patch this exercised the defect.  After the patch
it looks like it is fixed.
However have asked for clarifiction about write() when a new MANIFEST.MF needs to be written
but there is already an existing file.
See http://www.nabble.com/m-eclipse-p%3A-EclipseManifestWriter.write%28%29---doesn%27t-retain-any-keys-except-CLASS_PATH-and-MANIFEST_VERSION-td19546126.html
The problem is that the old values will be lost.  Need to check if that is the correct intention.

Added:
    maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java
  (with props)
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml
  (with props)
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/project
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt
  (with props)
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/MANIFEST.MF
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/expected_MANIFEST.MF
    maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/WEB-INF/

Added: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,313 @@
+/*
+ * 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.
+ */
+package org.apache.maven.plugin.eclipse.writers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.eclipse.EclipseSourceDir;
+import org.apache.maven.plugin.eclipse.Messages;
+import org.apache.maven.plugin.eclipse.writers.wtp.AbstractWtpResourceWriter;
+import org.apache.maven.plugin.ide.IdeDependency;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * Common behaviours for creating or adapting the manifest files for eclipse environments.
+ * 
+ * @author <a href="mailto:nir@cfc.at">Richard van Nieuwenhoven </a>
+ */
+public abstract class AbstractEclipseManifestWriter
+    extends AbstractEclipseWriter
+{
+
+    protected static final String MANIFEST_MF_FILENAME = "MANIFEST.MF";
+
+    protected static final String META_INF_DIRECTORY = "META-INF";
+
+    public AbstractEclipseManifestWriter()
+    {
+        super();
+    }
+
+    /**
+     * Aphabeticaly sort the classpath. Do this by splitting it up, sort the entries and
gleue them together again.
+     * 
+     * @param newValue classpath to sort
+     * @return the sorted classpath
+     */
+    protected String orderClasspath( String newValue )
+    {
+        if ( newValue == null )
+        {
+            return null;
+        }
+        String[] entries = newValue.split( " " );
+        Arrays.sort( entries );
+        StringBuffer buffer = new StringBuffer( newValue.length() );
+        for ( int index = 0; index < entries.length; index++ )
+        {
+            buffer.append( entries[index] );
+            buffer.append( ' ' );
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Read and parse the existing manifest file.
+     * 
+     * @param manifestFile file
+     * @return the read manifest
+     * @throws IOException if the file could not be read
+     */
+    protected Manifest readExistingManifest( File manifestFile )
+        throws IOException
+    {
+        if ( !manifestFile.exists() )
+        {
+            return null;
+        }
+
+        Manifest existingManifest = new Manifest();
+        FileInputStream inputStream = new FileInputStream( manifestFile );
+        try
+        {
+            existingManifest.read( inputStream );
+        }
+        finally
+        {
+            IOUtil.close( inputStream );
+        }
+        return existingManifest;
+    }
+
+    /**
+     * Add one dependency to the blank separated classpath stringbuffer. When the project
is available in the reactor
+     * (current build) then the project is used else the jar representing the artifact. System
dependencies will only be
+     * included if they are in this project.
+     * 
+     * @param classpath existing classpath to append
+     * @param dependency dependency to append as jar or as project
+     */
+    protected void addDependencyToClassPath( StringBuffer classpath, IdeDependency dependency
)
+    {
+        if ( !dependency.isTestDependency() && !dependency.isProvided()
+            && !dependency.isSystemScopedOutsideProject( this.config.getProject()
) )
+        {
+
+            // blank is the separator in manifest classpath's
+            if ( classpath.length() != 0 )
+            {
+                classpath.append( ' ' );
+            }
+            // if the dependency is a workspace project add the project and not
+            // the jar
+            if ( !dependency.isReferencedProject() )
+            {
+                classpath.append( dependency.getFile().getName() );
+            }
+            else
+            {
+                classpath.append( dependency.getEclipseProjectName() + ".jar" );
+            }
+        }
+    }
+
+    /**
+     * Check if the two manifests are equal. Manifest.equal can not be used because of the
special case the Classpath
+     * entr, witch must be comaired sorted so that a different oder in the classpath does
not result in "not equal".
+     * This not not realy correct but in this case it is more important to reduce the number
of version-controll files.
+     * 
+     * @param manifest the new manifest
+     * @param existingManifest to compaire the new one with
+     * @return are the manifests equal
+     */
+    protected boolean areManifestsEqual( Manifest manifest, Manifest existingManifest )
+    {
+        if ( existingManifest == null )
+        {
+            log.info( "@@@ FALSE - Manifest are not equal because existingManifest is null"
);
+            return false;
+        }
+
+        Set keys = new HashSet();
+        Attributes existingMap = existingManifest.getMainAttributes();
+        Attributes newMap = manifest.getMainAttributes();
+        keys.addAll( existingMap.keySet() );
+        keys.addAll( newMap.keySet() );
+        Iterator iterator = keys.iterator();
+        while ( iterator.hasNext() )
+        {
+            Attributes.Name key = (Attributes.Name) iterator.next();
+            String newValue = (String) newMap.get( key );
+            String existingValue = (String) existingMap.get( key );
+            // special case classpath... they are equal when there entries
+            // are equal
+            if ( Attributes.Name.CLASS_PATH.equals( key ) )
+            {
+                newValue = orderClasspath( newValue );
+                existingValue = orderClasspath( existingValue );
+            }
+            if ( ( newValue == null || !newValue.equals( existingValue ) )
+                && ( existingValue == null || !existingValue.equals( newValue ) )
)
+            {
+                log.info( "@@@ FALSE - Manifest are not equal because key = " + key + " has
existing value = " + existingValue + " and new value = "
+                    + newValue + " are different" );
+                return false;
+            }
+        }
+        log.info( "@@@ TRUE - Manifests are equal" );
+        return true;
+    }
+
+    /**
+     * Convert all dependencies in a blank seperated list of jars and projects representing
the classpath.
+     * 
+     * @return the blank separeted classpath string
+     */
+    protected String constructManifestClasspath()
+    {
+        StringBuffer stringBuffer = new StringBuffer();
+        IdeDependency[] deps = this.config.getDepsOrdered();
+
+        for ( int index = 0; index < deps.length; index++ )
+        {
+            addDependencyToClassPath( stringBuffer, deps[index] );
+        }
+
+        return stringBuffer.toString();
+    }
+
+    /**
+     * Create a manifest contaigning the required classpath.
+     * 
+     * @return the newly created manifest
+     */
+    protected Manifest createNewManifest()
+    {
+        Manifest manifest = new Manifest();
+        manifest.getMainAttributes().put( Attributes.Name.MANIFEST_VERSION, "1.0" );
+        manifest.getMainAttributes().put( Attributes.Name.CLASS_PATH, constructManifestClasspath()
);
+        return manifest;
+    }
+
+    /**
+     * Verify is the manifest sould be overwritten this sould take in account that the manifest
should only be written
+     * if the contents of the classpath was changed not the order. The classpath sorting
oder should be ignored.
+     * 
+     * @param manifest the newly created classpath
+     * @param manifestFile the file where the manifest
+     * @return if the new manifest file must be written
+     * @throws MojoExecutionException
+     */
+    protected boolean shouldNewManifestFileBeWritten( Manifest manifest, File manifestFile
)
+        throws MojoExecutionException
+    {
+        try
+        {
+            Manifest existingManifest = readExistingManifest( manifestFile );
+            if ( areManifestsEqual( manifest, existingManifest ) )
+            {
+                this.log.info( Messages.getString( "EclipseCleanMojo.unchanged", manifestFile.getAbsolutePath()
) );
+                return false;
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.nofilefound",
+                                                                  manifestFile.getAbsolutePath()
), e );
+        }
+        return true;
+    }
+
+    /**
+     * Search the project for the existing META-INF directory where the manifest should be
located.
+     * 
+     * @return the absolute path to the META-INF directory
+     * @throws MojoExecutionException
+     */
+    protected abstract String getMetaInfBaseDirectory( MavenProject project )
+        throws MojoExecutionException;
+
+    /**
+     * If the existing manifest file located in <code>getMetaInfBaseDirectory()</code>

+     * already has a correct MANIFEST_VERSION and CLASS_PATH value then do nothing.
+     * <p>
+     * Otherwise generate a <b>NEW</b> (i.e the old one is overwritten) which
only contains
+     * values for MANIFEST_VERSION and CLASS_PATH, all other previous entries are not kept.
+     * 
+     * @see AbstractWtpResourceWriter#write(EclipseSourceDir[], ArtifactRepository, File)
+     * @param sourceDirs all eclipse source directorys
+     * @param localRepository the local reposetory
+     * @param buildOutputDirectory build output directory (target)
+     * @throws MojoExecutionException when writing the config files was not possible
+     */
+    public void write()
+        throws MojoExecutionException
+    {
+        String metaInfBaseDirectory = getMetaInfBaseDirectory( this.config.getProject() );
+
+        if ( metaInfBaseDirectory == null )
+        {
+            // TODO: if this really is an error, shouldn't we stop the build??
+            throw new MojoExecutionException(
+                                              Messages.getString(
+                                                                  "EclipseCleanMojo.nofilefound",
+                                                                  new Object[] { EclipseManifestWriter.META_INF_DIRECTORY
} ) );
+        }
+        File manifestFile =
+            new File( metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY
+                + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME );
+        Manifest manifest = createNewManifest();
+
+        if ( shouldNewManifestFileBeWritten( manifest, manifestFile ) )
+        {
+            log.info( "Writing manifest..." );
+
+            manifestFile.getParentFile().mkdirs();
+
+            try
+            {
+                FileOutputStream stream = new FileOutputStream( manifestFile );
+
+                manifest.write( stream );
+
+                stream.close();
+
+            }
+            catch ( Exception e )
+            {
+                this.log.error( Messages.getString( "EclipsePlugin.cantwritetofile",
+                                                    new Object[] { manifestFile.getAbsolutePath()
} ) );
+            }
+        }
+    }
+
+}
\ No newline at end of file

Propchange: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/writers/AbstractEclipseManifestWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>war</packaging>
+  <groupId>eclipse.test</groupId>
+  <artifactId>project-rad-8</artifactId>
+  <version>1</version>
+  <dependencies>
+    <!-- No dependencies as per MECLIPSE-423 -->
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.0</version>
+        <configuration>
+          <source>1.4</source>
+          <target>1.4</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/project
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/project?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/project
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/project
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,57 @@
+<projectDescription>
+  <name>maven-eclipse-plugin-test-project-rad-2</name>
+  <comment/>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>com.ibm.wtp.migration.MigrationBuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.j2ee.ui.LibDirBuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.webtools.additions.linksbuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.webpage.template.templatebuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.siteedit.SiteNavBuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.siteedit.SiteUpdateBuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.validation.validationbuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.wtp.j2ee.LibCopyBuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.etools.webtools.additions.jspcompilationbuilder</name>
+      <arguments/>
+    </buildCommand>
+    <buildCommand>
+      <name>com.ibm.sse.model.structuredbuilder</name>
+      <arguments/>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>com.ibm.wtp.web.WebNature</nature>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>com.ibm.etools.siteedit.WebSiteNature</nature>
+    <nature>com.ibm.etools.webpage.template.templatenature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Added: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,7 @@
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: DummyClass.txt 474384 2006-11-13 16:10:39Z jdcasey $
+ */
+public class DummyClass
+{
+}

Propchange: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/java/DummyClass.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/MANIFEST.MF?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/MANIFEST.MF
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/MANIFEST.MF
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

Added: maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/expected_MANIFEST.MF
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/expected_MANIFEST.MF?rev=696566&view=auto
==============================================================================
--- maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/expected_MANIFEST.MF
(added)
+++ maven/plugins/trunk/maven-eclipse-plugin/src/test/resources/projects/project-rad-8/src/main/webapp/META-INF/expected_MANIFEST.MF
Wed Sep 17 22:53:07 2008
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+



Mime
View raw message