Hi Robert,

On 12/09/16 19:42, Robert Scholte wrote:
Hi Karl Heinz,

We probably need to revisit this code. I think Aether is also capable in
generating these files...

Sure I appreciate any suggestions ..it was only my first state which worked ...This code should be improved of course...

I have a question conerning the repositoryManager which I currently use in DefaultProjectInstaller:

private File getLocalRepoFile( ProjectBuildingRequest buildingRequest, ArtifactRepository artifactRepository,
                                   Artifact artifact )
    {
String path = repositoryManager.getPathForLocalArtifact( buildingRequest, artifact );
        return new File( artifactRepository.getBasedir(), path );
    }

I'm not sure if this couldn't be made simpler ?

Kind regards
Karl Heinz Marbaise



Robert

On Mon, 12 Sep 2016 13:22:30 +0200, <[email protected]> wrote:

Author: khmarbaise
Date: Mon Sep 12 11:22:29 2016
New Revision: 1760333

URL: http://svn.apache.org/viewvc?rev=1760333&view=rev
Log:
[MSHARED-593] Add interface to install a Maven Project

Added:

maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/


maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstaller.java


maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstallerRequest.java


maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/


maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DefaultProjectInstaller.java


maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DualDigester.java

Modified:
    maven/shared/trunk/maven-artifact-transfer/pom.xml

Modified: maven/shared/trunk/maven-artifact-transfer/pom.xml
URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-artifact-transfer/pom.xml?rev=1760333&r1=1760332&r2=1760333&view=diff

==============================================================================

--- maven/shared/trunk/maven-artifact-transfer/pom.xml (original)
+++ maven/shared/trunk/maven-artifact-transfer/pom.xml Mon Sep 12
11:22:29 2016
@@ -168,6 +168,17 @@
       <artifactId>maven-common-artifact-filters</artifactId>
       <version>3.0.0</version>
     </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>3.0.24</version>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.6</version>
+    </dependency>
    <!-- Maven 3.0.x -->
     <dependency>

Added:
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstaller.java

URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstaller.java?rev=1760333&view=auto

==============================================================================

---
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstaller.java
(added)
+++
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstaller.java
Mon Sep 12 11:22:29 2016
@@ -0,0 +1,49 @@
+package org.apache.maven.shared.project.install;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.ProjectBuildingRequest;
+import
org.apache.maven.shared.artifact.install.ArtifactInstallerException;
+
+/**
+ * This defines the interface to install a single Maven Project.
+ *
+ * @author Karl Heinz Marbaise <a
href="mailto:[email protected]";>[email protected]</a>
+ */
+public interface ProjectInstaller
+{
+    /**
+     * This will install a single project which may contain several
artifacts. Those artifacts will be installed into
+     * the appropriate repository.
+     *
+     * @param projectBuildingRequest {@link ProjectBuildingRequest}
+     * @param projectInstallerRequest {@link ProjectInstallerRequest}
+     * @param artifactRepository {@link ArtifactRepository}
+     * @throws IOException In case of problem to install project.
+     * @throws ArtifactInstallerException In case of problems to
install artifacts.
+     */
+    void installProject( ProjectBuildingRequest
projectBuildingRequest, ProjectInstallerRequest projectInstallerRequest,
+                         ArtifactRepository artifactRepository )
+        throws IOException, ArtifactInstallerException;
+
+}

Added:
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstallerRequest.java

URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstallerRequest.java?rev=1760333&view=auto

==============================================================================

---
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstallerRequest.java
(added)
+++
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/ProjectInstallerRequest.java
Mon Sep 12 11:22:29 2016
@@ -0,0 +1,90 @@
+package org.apache.maven.shared.project.install;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @author Robert Scholte
+ */
+public class ProjectInstallerRequest
+{
+    // From AbstractInstallMojo
+
+    private boolean createChecksum;
+
+    private boolean updateReleaseInfo;
+
+    // From InstallMojo
+
+    private MavenProject project;
+
+    /**
+     * @return the createChecksum
+     */
+    public boolean isCreateChecksum()
+    {
+        return createChecksum;
+    }
+
+    /**
+     * @param createChecksum the createChecksum to set
+     */
+    public ProjectInstallerRequest setCreateChecksum( boolean
createChecksum )
+    {
+        this.createChecksum = createChecksum;
+        return this;
+    }
+
+    /**
+     * @return the updateReleaseInfo
+     */
+    public boolean isUpdateReleaseInfo()
+    {
+        return updateReleaseInfo;
+    }
+
+    /**
+     * @param updateReleaseInfo the updateReleaseInfo to set
+     */
+    public ProjectInstallerRequest setUpdateReleaseInfo( boolean
updateReleaseInfo )
+    {
+        this.updateReleaseInfo = updateReleaseInfo;
+        return this;
+    }
+
+    /**
+     * @return the project
+     */
+    public MavenProject getProject()
+    {
+        return project;
+    }
+
+    /**
+     * @param project the project to set
+     */
+    public ProjectInstallerRequest setProject( MavenProject project )
+    {
+        this.project = project;
+        return this;
+    }
+
+}

Added:
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DefaultProjectInstaller.java

URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DefaultProjectInstaller.java?rev=1760333&view=auto

==============================================================================

---
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DefaultProjectInstaller.java
(added)
+++
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DefaultProjectInstaller.java
Mon Sep 12 11:22:29 2016
@@ -0,0 +1,275 @@
+package org.apache.maven.shared.project.install.internal;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.artifact.ProjectArtifact;
+import org.apache.maven.project.artifact.ProjectArtifactMetadata;
+import org.apache.maven.shared.artifact.install.ArtifactInstaller;
+import
org.apache.maven.shared.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.project.install.ProjectInstaller;
+import org.apache.maven.shared.project.install.ProjectInstallerRequest;
+import org.apache.maven.shared.repository.RepositoryManager;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This will install a whole project into the appropriate repository.
+ *
+ * @author Karl Heinz Marbaise <a
href="mailto:[email protected]";>[email protected]</a>
+ */
+@Component( role = ProjectInstaller.class )
+public class DefaultProjectInstaller
+    implements ProjectInstaller
+{
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(
DefaultProjectInstaller.class );
+
+    @Inject
+    private ArtifactInstaller installer;
+
+    @Inject
+    private RepositoryManager repositoryManager;
+
+    private final DualDigester digester = new DualDigester();
+
+    public void installProject( ProjectBuildingRequest
buildingRequest, ProjectInstallerRequest request,
+                                ArtifactRepository artifactRepository )
+        throws IOException, ArtifactInstallerException
+    {
+
+        MavenProject project = request.getProject();
+        boolean createChecksum = request.isCreateChecksum();
+        boolean updateReleaseInfo = request.isUpdateReleaseInfo();
+
+        Artifact artifact = project.getArtifact();
+        String packaging = project.getPackaging();
+        File pomFile = project.getFile();
+
+        List<Artifact> attachedArtifacts =
project.getAttachedArtifacts();
+
+        // TODO: push into transformation
+        boolean isPomArtifact = "pom".equals( packaging );
+
+        ProjectArtifactMetadata metadata;
+
+        if ( updateReleaseInfo )
+        {
+            artifact.setRelease( true );
+        }
+
+        Collection<File> metadataFiles = new LinkedHashSet<File>();
+
+        if ( isPomArtifact )
+        {
+            // installer.install( pomFile, artifact, localRepository );
+            installer.install( buildingRequest,
Collections.<Artifact>singletonList( new ProjectArtifact( project ) ) );
+            installChecksums( buildingRequest, artifactRepository,
artifact, createChecksum );
+            addMetaDataFilesForArtifact( artifactRepository,
artifact, metadataFiles, createChecksum );
+        }
+        else
+        {
+            metadata = new ProjectArtifactMetadata( artifact, pomFile );
+            artifact.addMetadata( metadata );
+
+            File file = artifact.getFile();
+
+            // Here, we have a temporary solution to MINSTALL-3
(isDirectory() is true if it went through compile
+            // but not package). We are designing in a proper
solution for Maven 2.1
+            if ( file != null && file.isFile() )
+            {
+                installer.install( buildingRequest,
Collections.<Artifact>singletonList( artifact ) );
+                installChecksums( buildingRequest,
artifactRepository, artifact, createChecksum );
+                addMetaDataFilesForArtifact( artifactRepository,
artifact, metadataFiles, createChecksum );
+            }
+            else if ( !attachedArtifacts.isEmpty() )
+            {
+                throw new IllegalArgumentException( "The packaging
plugin for this project did not assign "
+                    + "a main file to the project but it has
attachments. Change packaging to 'pom'." );
+            }
+            else
+            {
+                // CHECKSTYLE_OFF: LineLength
+                throw new IllegalArgumentException( "The packaging
for this project did not assign a file to the build artifact" );
+                // CHECKSTYLE_ON: LineLength
+            }
+        }
+
+        for ( Artifact attached : attachedArtifacts )
+        {
+            // installer.install( attached.getFile(), attached,
localRepository );
+            installer.install( buildingRequest,
Collections.singletonList( attached ) );
+            installChecksums( buildingRequest, artifactRepository,
attached, createChecksum );
+            addMetaDataFilesForArtifact( artifactRepository,
attached, metadataFiles, createChecksum );
+        }
+
+        installChecksums( metadataFiles );
+    }
+
+    /**
+     * Installs the checksums for the specified artifact if this has
been enabled in the plugin configuration. This
+     * method creates checksums for files that have already been
installed to the local repo to account for on-the-fly
+     * generated/updated files. For example, in Maven 2.0.4- the
<code>ProjectArtifactMetadata</code> did not install
+     * the original POM file (cf. MNG-2820). While the plugin
currently requires Maven 2.0.6, we continue to hash the
+     * installed POM for robustness with regard to future changes
like re-introducing some kind of POM filtering.
+     *
+     * @param artifact The artifact for which to create checksums,
must not be <code>null</code>.
+     * @param createChecksum {@code true} if checksum should be
created, otherwise {@code false}.
+     * @throws IOException If the checksums could not be installed.
+     */
+    private void installChecksums( ProjectBuildingRequest
buildingRequest, ArtifactRepository artifactRepository,
+                                   Artifact artifact, boolean
createChecksum )
+        throws IOException
+    {
+        if ( !createChecksum )
+        {
+            return;
+        }
+
+        File artifactFile = getLocalRepoFile( buildingRequest,
artifactRepository, artifact );
+        installChecksums( artifactFile );
+    }
+
+    // CHECKSTYLE_OFF: LineLength
+    protected void addMetaDataFilesForArtifact( ArtifactRepository
artifactRepository, Artifact artifact,
+                                                Collection<File>
targetMetadataFiles, boolean createChecksum )
+    // CHECKSTYLE_ON: LineLength
+    {
+        if ( !createChecksum )
+        {
+            return;
+        }
+
+        Collection<ArtifactMetadata> metadatas =
artifact.getMetadataList();
+        if ( metadatas != null )
+        {
+            for ( ArtifactMetadata metadata : metadatas )
+            {
+                File metadataFile = getLocalRepoFile(
artifactRepository, metadata );
+                targetMetadataFiles.add( metadataFile );
+            }
+        }
+    }
+
+    /**
+     * Installs the checksums for the specified metadata files.
+     *
+     * @param metadataFiles The collection of metadata files to
install checksums for, must not be <code>null</code>.
+     * @throws IOException If the checksums could not be installed.
+     */
+    protected void installChecksums( Collection<File> metadataFiles )
+        throws IOException
+    {
+        for ( File metadataFile : metadataFiles )
+        {
+            installChecksums( metadataFile );
+        }
+    }
+
+    /**
+     * Installs the checksums for the specified file (if it exists).
+     *
+     * @param installedFile The path to the already installed file in
the local repo for which to generate checksums,
+     *            must not be <code>null</code>.
+     * @throws IOException In case of errors. Could not install
checksums.
+     */
+    private void installChecksums( File installedFile )
+        throws IOException
+    {
+        boolean signatureFile = installedFile.getName().endsWith(
".asc" );
+        if ( installedFile.isFile() && !signatureFile )
+        {
+            LOGGER.debug( "Calculating checksums for " +
installedFile );
+            digester.calculate( installedFile );
+            installChecksum( installedFile, ".md5", digester.getMd5() );
+            installChecksum( installedFile, ".sha1",
digester.getSha1() );
+        }
+    }
+
+    /**
+     * Installs a checksum for the specified file.
+     *
+     * @param installedFile The base path from which the path to the
checksum files is derived by appending the given
+     *            file extension, must not be <code>null</code>.
+     * @param ext The file extension (including the leading dot) to
use for the checksum file, must not be
+     *            <code>null</code>.
+     * @param checksum the checksum to write
+     * @throws IOException If the checksum could not be installed.
+     */
+    private void installChecksum( File installedFile, String ext,
String checksum )
+        throws IOException
+    {
+        File checksumFile = new File( installedFile.getAbsolutePath()
+ ext );
+        LOGGER.debug( "Installing checksum to " + checksumFile );
+        try
+        {
+            // noinspection ResultOfMethodCallIgnored
+            checksumFile.getParentFile().mkdirs();
+            FileUtils.fileWrite( checksumFile.getAbsolutePath(),
"UTF-8", checksum );
+        }
+        catch ( IOException e )
+        {
+            throw new IOException( "Failed to install checksum to " +
checksumFile, e );
+        }
+    }
+
+    /**
+     * Gets the path of the specified artifact within the local
repository. Note that the returned path need not exist
+     * (yet).
+     *
+     * @param artifact The artifact whose local repo path should be
determined, must not be <code>null</code>.
+     * @return The absolute path to the artifact when installed,
never <code>null</code>.
+     */
+    private File getLocalRepoFile( ProjectBuildingRequest
buildingRequest, ArtifactRepository artifactRepository,
+                                   Artifact artifact )
+    {
+        String path = repositoryManager.getPathForLocalArtifact(
buildingRequest, artifact );
+        return new File( artifactRepository.getBasedir(), path );
+    }
+
+    /**
+     * Gets the path of the specified artifact metadata within the
local repository. Note that the returned path need
+     * not exist (yet).
+     *
+     * @param metadata The artifact metadata whose local repo path
should be determined, must not be <code>null</code>.
+     * @return The absolute path to the artifact metadata when
installed, never <code>null</code>.
+     */
+    private File getLocalRepoFile( ArtifactRepository
artifactRepository, ArtifactMetadata metadata )
+    {
+        String path =
artifactRepository.pathOfLocalRepositoryMetadata( metadata,
artifactRepository );
+        return new File( artifactRepository.getBasedir(), path );
+    }
+
+}

Added:
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DualDigester.java

URL:
http://svn.apache.org/viewvc/maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DualDigester.java?rev=1760333&view=auto

==============================================================================

---
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DualDigester.java
(added)
+++
maven/shared/trunk/maven-artifact-transfer/src/main/java/org/apache/maven/shared/project/install/internal/DualDigester.java
Mon Sep 12 11:22:29 2016
@@ -0,0 +1,112 @@
+package org.apache.maven.shared.project.install.internal;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.commons.codec.binary.Hex;
+import org.codehaus.plexus.util.IOUtil;
+
+
+/**
+ * Calculates md5 and sha1 digest.
+ * <p/>
+ * Todo: Consider using a thread to calculate one of the digests when
the files are large; it's fairly slow !
+ *
+ * @author Kristian Rosenvold
+ */
+public class DualDigester
+{
+    private final MessageDigest md5 = getDigester( "MD5" );
+
+    private final MessageDigest sh1 = getDigester( "SHA-1" );
+
+    private static final int BUFSIZE = 65536 * 2;
+
+    private final byte[] buffer = new byte[BUFSIZE];
+
+    static MessageDigest getDigester( String algorithm )
+    {
+        try
+        {
+            return MessageDigest.getInstance( algorithm );
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new RuntimeException( "Unable to initialize digest
" + algorithm + " : " + e.getMessage() );
+        }
+    }
+
+    public void calculate( File file ) throws IOException
+    {
+        FileInputStream fis = null;
+
+        try
+        {
+            fis = new FileInputStream( file );
+            calculate( fis );
+            fis.close();
+            fis = null;
+        }
+        catch ( IOException e )
+        {
+            throw new IOException( "Failed to calculate digest
checksum for " + file, e );
+        }
+        finally
+        {
+            IOUtil.close( fis );
+        }
+    }
+
+    void calculate( InputStream stream )
+        throws IOException
+    {
+        md5.reset();
+        sh1.reset();
+        update( stream );
+    }
+
+    public String getMd5()
+    {
+        return Hex.encodeHexString( md5.digest() );
+    }
+
+    public String getSha1()
+    {
+        return Hex.encodeHexString( sh1.digest() );
+    }
+
+    private void update( InputStream is )
+        throws IOException
+    {
+        int size = is.read( buffer, 0, BUFSIZE );
+        while ( size >= 0 )
+        {
+            md5.update( buffer, 0, size );
+            sh1.update( buffer, 0, size );
+            size = is.read( buffer, 0, BUFSIZE );
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]




Mit freundlichem Gruß
Karl-Heinz Marbaise
--
SoftwareEntwicklung Beratung Schulung    Tel.: +49 (0) 2405 / 415 893
Dipl.Ing.(FH) Karl-Heinz Marbaise        USt.IdNr: DE191347579
Hauptstrasse 177
52146 Würselen                           http://www.soebes.de

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to