Package org.guvnor.m2repo.backend.server

Source Code of org.guvnor.m2repo.backend.server.GuvnorM2Repository

/*
* Copyright 2012 JBoss Inc
*
* Licensed 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.guvnor.m2repo.backend.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.IOUtil;
import org.drools.core.io.impl.ReaderInputStream;
import org.guvnor.common.services.project.model.GAV;
import org.kie.scanner.Aether;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonatype.aether.artifact.Artifact;
import org.sonatype.aether.deployment.DeployRequest;
import org.sonatype.aether.deployment.DeploymentException;
import org.sonatype.aether.installation.InstallRequest;
import org.sonatype.aether.installation.InstallationException;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.repository.RepositoryPolicy;
import org.sonatype.aether.util.artifact.DefaultArtifact;
import org.sonatype.aether.util.artifact.SubArtifact;

@ApplicationScoped
public class GuvnorM2Repository {

    private static final Logger log = LoggerFactory.getLogger( GuvnorM2Repository.class );

    public static final String M2_REPO_ROOT = "repositories" + File.separatorChar + "kie";
    public static String M2_REPO_DIR;

    private static final int BUFFER_SIZE = 1024;

    @PostConstruct
    protected void init() {
        setM2Repos();
    }

    private void setM2Repos() {
        final String meReposDir = System.getProperty( "org.guvnor.m2repo.dir" );

        if ( meReposDir == null || meReposDir.trim().isEmpty() ) {
            M2_REPO_DIR = M2_REPO_ROOT;
        } else {
            M2_REPO_DIR = meReposDir.trim();
        }
        log.info( "Maven Repository root set to: " + M2_REPO_DIR );

        //Ensure repository root has been created
        final File root = new File( getM2RepositoryRootDir() );
        if ( !root.exists() ) {
            log.info( "Creating Maven Repository root: " + M2_REPO_DIR );
            root.mkdirs();
        }

        Aether.getAether().getRepositories().add( getGuvnorM2Repository() );
    }

    protected String getM2RepositoryRootDir() {
        if ( !M2_REPO_DIR.endsWith( File.separator ) ) {
            return M2_REPO_DIR + File.separator;
        } else {
            return M2_REPO_DIR;
        }
    }

    public String getRepositoryURL() {
        File file = new File( getM2RepositoryRootDir() );
        return "file://" + file.getAbsolutePath();
    }

    public void deployArtifact( final InputStream inputStream,
                                final GAV gav ) {
        File jarFile = new File( System.getProperty( "java.io.tmpdir" ),
                                 toFileName( gav,
                                             null,
                                             "jar" ) );

        try {
            if ( !jarFile.exists() ) {
                jarFile.getParentFile().mkdirs();
                jarFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream( jarFile );

            final byte[] buf = new byte[ BUFFER_SIZE ];
            int byteRead = 0;
            while ( ( byteRead = inputStream.read( buf ) ) != -1 ) {
                fos.write( buf, 0, byteRead );
            }
            fos.flush();
            fos.close();
        } catch ( IOException e ) {
            throw new RuntimeException( e );
        }

        //Prepare pom file
        String pom = loadPOMFromJarInternal( new File( jarFile.getPath() ) );
        if ( pom == null ) {
            pom = generatePOM( gav );
            jarFile = appendPOMToJar( pom,
                                      jarFile.getPath(),
                                      gav );
        }
        File pomFile = new File( System.getProperty( "java.io.tmpdir" ),
                                 toFileName( gav,
                                             null,
                                             "pom" ) );
        try {
            if ( !pomFile.exists() ) {
                pomFile.getParentFile().mkdirs();
                pomFile.createNewFile();
            }

            FileOutputStream fos = new FileOutputStream( pomFile );
            IOUtils.write( pom, fos );

            fos.flush();
            fos.close();
        } catch ( IOException e ) {
            throw new RuntimeException( e );
        }

        deployArtifact( gav, jarFile, pomFile );
    }

    public void deployArtifact( final GAV gav,
                                final File jarFile,
                                final File pomfile ) {
        Artifact jarArtifact = new DefaultArtifact( gav.getGroupId(),
                                                    gav.getArtifactId(),
                                                    "jar",
                                                    gav.getVersion() );
        jarArtifact = jarArtifact.setFile( jarFile );

        Artifact pomArtifact = new SubArtifact( jarArtifact,
                                                "",
                                                "pom" );
        pomArtifact = pomArtifact.setFile( pomfile );

        // install into local repository as it's preferred when loading kjars into KieContainer
        try {
            InstallRequest installRequest = new InstallRequest();
            installRequest
                    .addArtifact( jarArtifact )
                    .addArtifact( pomArtifact );

            Aether.getAether().getSystem().install( Aether.getAether().getSession(),
                                                    installRequest );
        } catch ( InstallationException e ) {
            throw new RuntimeException( e );
        }

        DeployRequest deployRequest = new DeployRequest();
        deployRequest
                .addArtifact( jarArtifact )
                .addArtifact( pomArtifact )
                .setRepository( getGuvnorM2Repository() );

        try {
            Aether.getAether().getSystem().deploy( Aether.getAether().getSession(),
                                                   deployRequest );
        } catch ( DeploymentException e ) {
            throw new RuntimeException( e );
        }
    }

    private RemoteRepository getGuvnorM2Repository() {
        File m2RepoDir = new File( M2_REPO_DIR );
        if ( !m2RepoDir.exists() ) {
            log.error( "Repository root does not exist: " + M2_REPO_DIR );
            throw new IllegalArgumentException( "Repository root does not exist: " + M2_REPO_DIR );
        }

        try {
            String localRepositoryUrl = m2RepoDir.toURI().toURL().toExternalForm();
            return new RemoteRepository( "guvnor-m2-repo",
                                         "default",
                                         localRepositoryUrl )
                    .setPolicy( true,
                                new RepositoryPolicy( false,
                                                      RepositoryPolicy.UPDATE_POLICY_NEVER,
                                                      RepositoryPolicy.CHECKSUM_POLICY_WARN ) )
                    .setPolicy( false,
                                new RepositoryPolicy( false,
                                                      RepositoryPolicy.UPDATE_POLICY_NEVER,
                                                      RepositoryPolicy.CHECKSUM_POLICY_WARN ) );

        } catch ( MalformedURLException e ) {
            log.error( e.getMessage(),
                       e );
            throw new RuntimeException( e );
        }
    }

    /**
     * Finds files within the repository with the given filters.
     * @return an collection of java.io.File with the matching files
     */
    public Collection<File> listFiles() {
        return listFiles( null );
    }

    /**
     * Finds files within the repository with the given filters.
     * @param filters filter to apply when finding files. The filter is used to create a wildcard matcher, ie., "*fileter*.*", in which "*" is
     * to represent a multiple wildcard characters.
     * @return an collection of java.io.File with the matching files
     */
    public Collection<File> listFiles( final String filters ) {
        String wildcard = "*.jar";
        if ( filters != null ) {
            wildcard = "*" + filters + "*.jar";
        }
        Collection<File> files = FileUtils.listFiles( new File( M2_REPO_DIR ),
                                                      new WildcardFileFilter( wildcard,
                                                                              IOCase.INSENSITIVE ),
                                                      DirectoryFileFilter.DIRECTORY );

        return files;
    }

    public InputStream loadFile( final String path ) {
        try {
            return new FileInputStream( new File( M2_REPO_DIR,
                                                  path ) );
        } catch ( FileNotFoundException e ) {
            log.error( e.getMessage() );
        }
        return null;
    }

    public String getFileName( final String path ) {
        return ( new File( M2_REPO_DIR,
                           path ) ).getName();
    }

    public static String loadPOMFromJar( final String jarPath ) {
        File zip = new File( M2_REPO_DIR,
                             jarPath );

        return loadPOMFromJarInternal( zip );
    }

    public static String loadPOMFromJarInternal( final File file ) {
        try {
            ZipFile zip = new ZipFile( file );

            for ( Enumeration e = zip.entries(); e.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) e.nextElement();

                if ( entry.getName().startsWith( "META-INF/maven" ) && entry.getName().endsWith( "pom.xml" ) ) {
                    InputStream is = zip.getInputStream( entry );

                    InputStreamReader isr = new InputStreamReader( is, "UTF-8" );
                    StringBuilder sb = new StringBuilder();
                    for ( int c = isr.read(); c != -1; c = isr.read() ) {
                        sb.append( (char) c );
                    }
                    return sb.toString();
                }
            }
        } catch ( ZipException e ) {
            log.error( e.getMessage() );
        } catch ( IOException e ) {
            log.error( e.getMessage() );
        }

        return null;
    }

    public static InputStream loadPOMStreamFromJar( final InputStream jarInputStream ) throws IOException {
        ZipInputStream zis = new ZipInputStream( jarInputStream );
        ZipEntry entry;

        while ( ( entry = zis.getNextEntry() ) != null ) {
            if ( entry.getName().startsWith( "META-INF/maven" ) && entry.getName().endsWith( "pom.xml" ) ) {
                return new ReaderInputStream( new InputStreamReader( zis,
                                                                     "UTF-8" ) );
            }
        }

        throw new FileNotFoundException( "Could not find pom.xml from the jar." );
    }

    public static String loadPOMFromJar( final InputStream jarInputStream ) {
        try {

            InputStream is = loadPOMStreamFromJar( jarInputStream );
            StringBuilder sb = new StringBuilder();
            for ( int c = is.read(); c != -1; c = is.read() ) {
                sb.append( (char) c );
            }
            return sb.toString();
        } catch ( IOException e ) {
            log.error( e.getMessage() );
        }

        return null;
    }

    public File appendPOMToJar( final String pom,
                                final String jarPath,
                                final GAV gav ) {
        File originalJarFile = new File( jarPath );
        File appendedJarFile = new File( jarPath + ".tmp" );

        try {
            ZipFile war = new ZipFile( originalJarFile );

            ZipOutputStream append = new ZipOutputStream( new FileOutputStream( appendedJarFile ) );

            // first, copy contents from existing war
            Enumeration<? extends ZipEntry> entries = war.entries();
            while ( entries.hasMoreElements() ) {
                ZipEntry e = entries.nextElement();
                append.putNextEntry( e );
                if ( !e.isDirectory() ) {
                    IOUtil.copy( war.getInputStream( e ),
                                 append );
                }
                append.closeEntry();
            }

            // append pom.
            ZipEntry e = new ZipEntry( getPomXmlPath( gav ) );
            append.putNextEntry( e );
            append.write( pom.getBytes() );
            append.closeEntry();

            // close
            war.close();
            append.close();
        } catch ( ZipException e ) {
            log.error( e.getMessage() );
        } catch ( IOException e ) {
            log.error( e.getMessage() );
        }

        //originalJarFile.delete();
        //appendedJarFile.renameTo(originalJarFile);
        return appendedJarFile;
    }

    protected String toURL( final String repository,
                            final GAV gav,
                            final String classifier ) {
        final StringBuilder sb = new StringBuilder( repository );

        if ( !repository.endsWith( File.separator ) ) {
            sb.append( File.separator );
        }

        return sb.append( gav.getGroupId().replace( ".",
                                                    File.separator ) )
                .append( File.separator ).append( gav.getArtifactId() )
                .append( File.separator ).append( gav.getVersion() )
                .append( File.separator ).append( toFileName( gav,
                                                              classifier,
                                                              "jar" ) ).toString();
    }

    protected String toFileName( final GAV gav,
                                 final String classifier,
                                 final String fileType ) {
        if ( classifier != null ) {
            return gav.getArtifactId() + "-" + gav.getVersion() + "-" + classifier + "." + getFileExtension( fileType );
        }

        return gav.getArtifactId() + "-" + gav.getVersion() + "." + getFileExtension( fileType );
    }

    private String getFileExtension( final String type ) {
        if ( type.equalsIgnoreCase( "ear" ) ) {
            return "ear";
        } else if ( type.equalsIgnoreCase( "pom" ) ) {
            return "pom";
        } else if ( type.equalsIgnoreCase( "war" ) ) {
            return "war";
        }

        return "jar";
    }

    public String generatePOM( final GAV gav ) {
        Model model = new Model();
        model.setGroupId( gav.getGroupId() );
        model.setArtifactId( gav.getArtifactId() );
        model.setVersion( gav.getVersion() );
        model.setModelVersion( "4.0.0" );

/*        Repository repo = new Repository();
        repo.setId("guvnor-m2-repo");
        repo.setName("Guvnor M2 Repo");
        repo.setUrl(getRepositoryURL());
        model.addRepository(repo);*/

        StringWriter stringWriter = new StringWriter();
        try {
            new MavenXpp3Writer().write( stringWriter,
                                         model );
        } catch ( IOException e ) {
            log.error( e.getMessage() );
        }

        return stringWriter.toString();
    }

    public static String generatePomProperties( final GAV gav ) {
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.append( "groupId=" );
        sBuilder.append( gav.getGroupId() );
        sBuilder.append( "\n" );

        sBuilder.append( "artifactId=" );
        sBuilder.append( gav.getArtifactId() );
        sBuilder.append( "\n" );

        sBuilder.append( "version=" );
        sBuilder.append( gav.getVersion() );
        sBuilder.append( "\n" );

        return sBuilder.toString();
    }

    public String getPomXmlPath( final GAV gav ) {
        return "META-INF/maven/" + gav.getGroupId() + "/" + gav.getArtifactId() + "/pom.xml";
    }

    public String getPomPropertiesPath( final GAV gav ) {
        return "META-INF/maven/" + gav.getGroupId() + "/" + gav.getArtifactId() + "/pom.properties";
    }
}

TOP

Related Classes of org.guvnor.m2repo.backend.server.GuvnorM2Repository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.