| /* |
| * 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 npanday.artifact.impl; |
| |
| import npanday.ArtifactTypeHelper; |
| import npanday.artifact.ArtifactContext; |
| import npanday.artifact.ApplicationConfig; |
| import npanday.ArtifactType; |
| import npanday.PathUtil; |
| import npanday.artifact.NetDependencyMatchPolicy; |
| import npanday.artifact.NetDependenciesRepository; |
| import npanday.artifact.AssemblyResolver; |
| import npanday.registry.RepositoryRegistry; |
| import npanday.model.netdependency.NetDependency; |
| import npanday.dao.ProjectDao; |
| import npanday.dao.Project; |
| import npanday.dao.ProjectFactory; |
| import npanday.dao.ProjectDependency; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.artifact.versioning.VersionRange; |
| import org.apache.maven.artifact.resolver.ArtifactResolver; |
| import org.apache.maven.artifact.resolver.ArtifactNotFoundException; |
| import org.apache.maven.artifact.resolver.ArtifactResolutionException; |
| import org.apache.maven.artifact.factory.ArtifactFactory; |
| import org.apache.maven.artifact.installer.ArtifactInstallationException; |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.artifact.repository.DefaultArtifactRepository; |
| import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; |
| import org.apache.maven.model.Model; |
| import org.apache.maven.model.Dependency; |
| import org.apache.maven.model.io.xpp3.MavenXpp3Writer; |
| import org.apache.maven.model.io.xpp3.MavenXpp3Reader; |
| import org.codehaus.plexus.util.FileUtils; |
| import org.codehaus.plexus.util.IOUtil; |
| import org.codehaus.plexus.util.xml.pull.XmlPullParserException; |
| import org.codehaus.plexus.logging.LogEnabled; |
| import org.codehaus.plexus.logging.Logger; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.FileWriter; |
| import java.io.FileReader; |
| import java.util.List; |
| import java.util.ArrayList; |
| import java.util.Set; |
| import java.util.HashSet; |
| |
| /** |
| * Provides an implementation of the <code>ArtifactInstaller</code> interface. |
| * |
| * @author Shane Isbell |
| */ |
| public class ArtifactInstallerImpl |
| implements npanday.artifact.ArtifactInstaller, LogEnabled |
| { |
| |
| /** |
| * Root path of the local Maven repository |
| */ |
| private File localRepository; |
| |
| /** |
| * The artifact context that constructed this artifact installer. The context is used by the installer to get |
| * application configs and artifact dependencies that may need to be attached to the installed artifacts. |
| */ |
| private ArtifactContext artifactContext; |
| |
| /** |
| * A logger for writing log messages |
| */ |
| private Logger logger; |
| |
| /** |
| * An artifact resolver component for locating artifacts and pulling them into the local repo if they do not |
| * already exist. |
| */ |
| private ArtifactResolver resolver; |
| |
| /** |
| * The artifact factory component, which is used for creating artifacts. |
| */ |
| private ArtifactFactory artifactFactory; |
| |
| /** |
| * The assembler resolver for resolving .NET artifacts |
| */ |
| private AssemblyResolver assemblyResolver; |
| |
| /** |
| * Registry for finding repositories of configuration information |
| */ |
| private RepositoryRegistry repositoryRegistry; |
| |
| /** |
| * List of remote artifact repositories to use in resolving artifacts |
| */ |
| private List<ArtifactRepository> remoteArtifactRepositories; |
| |
| /** |
| * Registry used for finding DAOs |
| */ |
| private npanday.registry.DataAccessObjectRegistry daoRegistry; |
| |
| |
| /** |
| * Constructor. This method is intended to by invoked by the plexus-container, not by the application developer. |
| */ |
| public ArtifactInstallerImpl() |
| { |
| } |
| |
| protected void initTest( ArtifactFactory artifactFactory, Logger logger ) |
| { |
| this.artifactFactory = artifactFactory; |
| this.logger = logger; |
| } |
| |
| /** |
| * @see LogEnabled#enableLogging(org.codehaus.plexus.logging.Logger) |
| */ |
| public void enableLogging( Logger logger ) |
| { |
| this.logger = logger; |
| } |
| |
| /** |
| * @see npanday.artifact.ArtifactInstaller#resolveAndInstallNetDependenciesForProfile(String, java.util.List<org.apache.maven.model.Dependency>, java.util.List<org.apache.maven.model.Dependency>) |
| */ |
| public void resolveAndInstallNetDependenciesForProfile( String profile, List<Dependency> netDependencies, |
| List<Dependency> javaDependencies ) |
| throws IOException |
| { |
| if ( netDependencies == null ) |
| { |
| netDependencies = new ArrayList<Dependency>(); |
| } |
| |
| if ( javaDependencies == null ) |
| { |
| javaDependencies = new ArrayList<Dependency>(); |
| } |
| |
| NetDependenciesRepository repository = |
| (NetDependenciesRepository) repositoryRegistry.find( "net-dependencies" ); |
| List<NetDependencyMatchPolicy> matchPolicies = new ArrayList<NetDependencyMatchPolicy>(); |
| matchPolicies.add( new ProfileMatchPolicy( profile ) ); |
| netDependencies.addAll( repository.getDependenciesFor( matchPolicies ) ); |
| |
| assemblyResolver.resolveTransitivelyFor( new MavenProject(), netDependencies, remoteArtifactRepositories, |
| localRepository, false ); |
| |
| //Do Library Installs for Net Dependencies |
| matchPolicies = new ArrayList<NetDependencyMatchPolicy>(); |
| matchPolicies.add( new ProfileMatchPolicy( profile ) ); |
| matchPolicies.add( new ExecutableAndNetPluginAndAddinMatchPolicy() ); |
| |
| ArtifactRepository localArtifactRepo = |
| new DefaultArtifactRepository( "local", "file://" + localRepository, new DefaultRepositoryLayout() ); |
| |
| for ( Dependency dependency : netDependencies ) |
| { |
| Artifact sourceArtifact = artifactFactory.createBuildArtifact( dependency.getGroupId(), |
| dependency.getArtifactId(), |
| dependency.getVersion(), |
| dependency.getType() ); |
| //Resolve the JavaBinding for the .NET plugin |
| if ( ArtifactTypeHelper.isDotnetMavenPlugin(sourceArtifact.getType())) |
| { |
| Artifact javaBindingArtifact = artifactFactory.createBuildArtifact( sourceArtifact.getGroupId(), |
| sourceArtifact.getArtifactId() + |
| ".JavaBinding", |
| sourceArtifact.getVersion(), |
| "jar" ); |
| try |
| { |
| resolver.resolve( javaBindingArtifact, remoteArtifactRepositories, localArtifactRepo ); |
| } |
| catch ( ArtifactResolutionException e ) |
| { |
| throw new IOException( |
| "NPANDAY-001-000: Problem resolving artifact for java binding: Message = " + e.getMessage() ); |
| } |
| catch ( ArtifactNotFoundException e ) |
| { |
| throw new IOException( |
| "NPANDAY-001-001: Could not find artifact for java binding: Message =" + e.getMessage() ); |
| } |
| } |
| } |
| |
| for ( Dependency dependency : javaDependencies ) |
| { |
| Artifact javaArtifact = artifactFactory.createBuildArtifact( dependency.getGroupId(), |
| dependency.getArtifactId(), |
| dependency.getVersion(), |
| dependency.getType() ); |
| try |
| { |
| resolver.resolve( javaArtifact, remoteArtifactRepositories, localArtifactRepo ); |
| } |
| catch ( ArtifactResolutionException e ) |
| { |
| throw new IOException( |
| "NPANDAY-001-002: Problem resolving java dependency artifact: Message = " + e.getMessage() ); |
| } |
| catch ( ArtifactNotFoundException e ) |
| { |
| throw new IOException( |
| "NPANDAY-001-003: Could not find java dependency artifact: Message = " + e.getMessage() ); |
| } |
| } |
| |
| ProjectDao dao = (ProjectDao) daoRegistry.find( "dao:project" ); |
| dao.openConnection(); |
| for ( Dependency dependency : repository.getDependenciesFor( matchPolicies ) ) |
| { |
| Project project = dao.getProjectFor( dependency.getGroupId(), dependency.getArtifactId(), |
| dependency.getVersion(), dependency.getType(), |
| dependency.getClassifier() ); |
| |
| Artifact sourceArtifact = ProjectFactory.createArtifactFrom( project, artifactFactory, localRepository ); |
| |
| List<Dependency> sourceArtifactDependencies = new ArrayList<Dependency>(); |
| for ( ProjectDependency projectDependency : project.getProjectDependencies() ) |
| { |
| sourceArtifactDependencies.add( ProjectFactory.createDependencyFrom( projectDependency ) ); |
| } |
| installArtifactAndDependenciesIntoPrivateApplicationBase( localRepository, sourceArtifact, |
| sourceArtifactDependencies ); |
| } |
| dao.closeConnection(); |
| } |
| |
| /** |
| * @see npanday.artifact.ArtifactInstaller#installArtifactAndDependenciesIntoPrivateApplicationBase(java.io.File, org.apache.maven.artifact.Artifact, java.util.List<org.apache.maven.model.Dependency>) |
| */ |
| public void installArtifactAndDependenciesIntoPrivateApplicationBase( File localRepository, Artifact artifact, |
| List<Dependency> dependencies ) |
| throws IOException |
| { |
| |
| Set<Artifact> artifactDependencies = new HashSet<Artifact>(); |
| for ( Dependency dependency : dependencies ) |
| { |
| |
| String scope = ( dependency.getScope() == null ) ? Artifact.SCOPE_COMPILE : dependency.getScope(); |
| Artifact artifactDependency = artifactFactory.createDependencyArtifact( dependency.getGroupId(), |
| dependency.getArtifactId(), |
| VersionRange.createFromVersion( |
| dependency.getVersion() ), |
| dependency.getType(), |
| dependency.getClassifier(), scope, |
| null ); |
| |
| File artifactDependencyFile = PathUtil.getDotNetArtifact( artifactDependency , localRepository ); |
| |
| if ( artifactDependencyFile == null || !artifactDependencyFile.exists() ) |
| { |
| if (!ArtifactTypeHelper.isDotnetAnyGac( artifactDependency.getType() )) |
| { |
| logger.warn( "NPANDAY-000-017: Could not find artifact dependency to copy in local repository: Artifact ID = " + |
| artifactDependency.getId() + ", File Path = " + |
| ( ( artifactDependencyFile != null ) ? artifactDependencyFile.getAbsolutePath() : null ) ); |
| } |
| continue; |
| } |
| |
| artifactDependency.setFile( artifactDependencyFile ); |
| artifactDependencies.add( artifactDependency ); |
| } |
| |
| if ( artifact != null ) |
| { |
| File artifactFile = artifact.getFile(); |
| if ( artifactFile == null || !artifactFile.exists() ) |
| { |
| throw new IOException( "NPANDAY-001-016: Could not find artifact: Artifact ID = " + |
| artifact.getArtifactId() + ", Path = " + |
| ( ( artifactFile != null ) ? artifactFile.getAbsolutePath() : null ) ); |
| } |
| artifactDependencies.add( artifact ); |
| } |
| //File installDirectory = PathUtil.getPrivateApplicationBaseFileFor( artifact, localRepository ).getParentFile(); |
| File installDirectory = PathUtil.getPrivateApplicationBaseFileFor( artifact, localRepository ).getParentFile(); |
| for ( Artifact artifactDependency : artifactDependencies ) |
| { |
| if ( !ArtifactTypeHelper.isDotnetAnyGac( artifactDependency.getType() ) ) |
| { |
| logger.info( "NPANDAY-001-005: Installing file into private assembly bin: File = " + |
| artifactDependency.getFile().getAbsolutePath() ); |
| FileUtils.copyFileToDirectory( artifactDependency.getFile(), installDirectory ); |
| } |
| } |
| } |
| |
| /** |
| * @see npanday.artifact.ArtifactInstaller#installArtifactWithPom(org.apache.maven.artifact.Artifact,java.io.File,boolean) |
| */ |
| public void installArtifactWithPom( Artifact artifact, File pomFile, boolean modifyProjectMetadata ) |
| throws ArtifactInstallationException |
| { |
| ApplicationConfig applicationConfig = artifactContext.getApplicationConfigFor( artifact ); |
| |
| File configExeFile = applicationConfig.getConfigBuildPath(); |
| |
| if ( configExeFile.exists() ) |
| { |
| try |
| { |
| |
| FileUtils.copyFileToDirectory( configExeFile, PathUtil.getUserAssemblyCacheFileFor( artifact,localRepository ).getParentFile() ); |
| |
| } |
| catch ( IOException e ) |
| { |
| throw new ArtifactInstallationException( "NPANDAY-001-006: Failed to install artifact: ID = " + |
| artifact.getId() + ", File = " + |
| ( ( artifact.getFile() != null ) ? artifact.getFile().getAbsolutePath() : "" ), e ); |
| } |
| } |
| |
| try |
| { |
| if ( artifact.getFile() != null && artifact.getFile().exists() )//maybe just a test compile and no install |
| { |
| |
| File artifactFile = artifact.getFile(); |
| |
| File destFile = PathUtil.getUserAssemblyCacheFileFor( artifact, localRepository ); |
| logger.info( |
| "NPANDAY-001-007: Installing file into repository: File = " + artifact.getFile().getAbsolutePath() |
| + ", Dest Directory = " + destFile.getParent()); |
| try |
| { |
| //this is previously using copyFile(File, File) |
| FileUtils.copyFileToDirectory( artifactFile.getAbsolutePath(), destFile.getParent() ); |
| } |
| catch ( IOException e ) |
| { |
| throw new ArtifactInstallationException( "NPANDAY-001-008: Failed to install artifact: ID = " + |
| artifact.getId() + ", File = " + |
| ( ( artifact.getFile() != null ) ? artifact.getFile().getAbsolutePath() : "" ), e ); |
| } |
| } |
| else |
| { |
| logger.info( "NPANDAY-001-010: Artifact does not exist. Nothing to install: Artifact = " + |
| artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() ); |
| } |
| } |
| catch ( ArtifactInstallationException e ) |
| { |
| throw new ArtifactInstallationException( "NPANDAY-001-011: Failed to install artifact: ID = " + |
| artifact.getId() + ", File = " + |
| ( ( artifact.getFile() != null ) ? artifact.getFile().getAbsolutePath() : "" ), e ); |
| } |
| |
| if ( !artifact.getType().equals( "exe.config" ) )//TODO: Generalize for any attached artifact |
| { |
| MavenXpp3Reader reader = new MavenXpp3Reader(); |
| Model model; |
| try |
| { |
| model = reader.read( new FileReader( pomFile ) ); |
| if ( configExeFile.exists() ) |
| { |
| Dependency dependency = new Dependency(); |
| dependency.setGroupId( artifact.getGroupId() ); |
| dependency.setArtifactId( artifact.getArtifactId() ); |
| dependency.setVersion( artifact.getVersion() ); |
| dependency.setType( ArtifactType.DOTNET_EXECUTABLE_CONFIG.getPackagingType() ); |
| model.addDependency( dependency ); |
| } |
| } |
| catch ( XmlPullParserException e ) |
| { |
| throw new ArtifactInstallationException( "NPANDAY-001-012: Unable to read pom file" ); |
| } |
| catch ( IOException e ) |
| { |
| throw new ArtifactInstallationException( "NPANDAY-001-013: Unable to read pom file" ); |
| } |
| |
| ProjectDao dao = (ProjectDao) daoRegistry.find( "dao:project" ); |
| dao.openConnection(); |
| try |
| { |
| dao.storeModelAndResolveDependencies( model, pomFile.getParentFile(), localRepository, |
| new ArrayList<ArtifactRepository>() ); |
| } |
| catch ( java.io.IOException e ) |
| { |
| e.printStackTrace(); |
| throw new ArtifactInstallationException( |
| "NPANDAY-001-014: Unable to store model: Message = " + e.getMessage() ); |
| } |
| finally |
| { |
| dao.closeConnection(); |
| deleteTempDir(pomFile); |
| } |
| } |
| } |
| |
| /** |
| * background cleaner that deletes the bin folder created besides the solutions file |
| */ |
| private void deleteTempDir(File pomFile) |
| { |
| //get the directory of the current pom file. |
| File pomDir = pomFile.getParentFile(); |
| |
| File binDir = new File(pomDir, "bin"); |
| |
| try |
| { |
| FileUtils.deleteDirectory(binDir); |
| |
| File targetDir = new File(pomDir, "target"); |
| |
| String[] directories = targetDir.list(); |
| |
| for(String dir:directories) |
| { |
| File insideTarget = new File(targetDir, dir); |
| if(insideTarget.isDirectory()) |
| { |
| String tempDir = insideTarget.getName(); |
| |
| if(isAllDigit(tempDir)) |
| { |
| |
| FileUtils.deleteDirectory( insideTarget ); |
| |
| } |
| } |
| |
| } |
| } |
| catch(Exception e) |
| { |
| System.out.println("NPANDAY-001-316: Unable to delete temp bin directory: \nError Stack Trace: "+e.getMessage()); |
| } |
| |
| } |
| |
| private boolean isAllDigit(String value) |
| { |
| boolean isValid=true; |
| |
| for(char index:value.toCharArray()) |
| { |
| |
| if(!Character.isDigit( index )) |
| { |
| isValid = false; |
| } |
| } |
| return isValid; |
| } |
| |
| /** |
| * @see npanday.artifact.ArtifactInstaller#installFileWithoutPom(String, String, String, String, java.io.File) |
| */ |
| public void installFileWithoutPom( String groupId, String artifactId, String version, String packaging, |
| File artifactFile ) |
| throws ArtifactInstallationException |
| { |
| Artifact artifact = |
| artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, packaging, null ); |
| artifact.setFile( artifactFile ); |
| Model model = new Model(); |
| model.setGroupId( groupId ); |
| model.setArtifactId( artifactId ); |
| model.setVersion( version ); |
| model.setPackaging( packaging ); |
| File tempFile; |
| FileWriter fileWriter; |
| try |
| { |
| tempFile = File.createTempFile( "mvninstall", ".pom" ); |
| tempFile.deleteOnExit(); |
| fileWriter = new FileWriter( tempFile ); |
| new MavenXpp3Writer().write( fileWriter, model ); |
| } |
| catch ( IOException e ) |
| { |
| throw new ArtifactInstallationException( |
| "NPANDAY-001-015: Unable to read model: Message =" + e.getMessage() ); |
| } |
| IOUtil.close( fileWriter ); |
| installArtifactWithPom( artifact, tempFile, false ); |
| } |
| |
| /** |
| * @see npanday.artifact.ArtifactInstaller#init(npanday.artifact.ArtifactContext, java.util.List<org.apache.maven.artifact.repository.ArtifactRepository>, java.io.File) |
| */ |
| public void init( ArtifactContext artifactContext, List<ArtifactRepository> remoteArtifactRepositories, |
| File localRepository ) |
| { |
| this.remoteArtifactRepositories = remoteArtifactRepositories; |
| this.localRepository = localRepository; |
| this.artifactContext = artifactContext; |
| } |
| |
| private class ExecutableAndNetPluginAndAddinMatchPolicy |
| implements NetDependencyMatchPolicy |
| { |
| public boolean match( NetDependency netDependency ) |
| { |
| return ArtifactTypeHelper.isDotnetExecutable(netDependency.getType()) || |
| ArtifactTypeHelper.isDotnetMavenPlugin(netDependency.getType()) || |
| netDependency.getType().equals( ArtifactType.VISUAL_STUDIO_ADDIN.getPackagingType() ) || |
| netDependency.getType().equals( ArtifactType.SHARP_DEVELOP_ADDIN.getPackagingType() ); |
| } |
| } |
| |
| private class ProfileMatchPolicy |
| implements NetDependencyMatchPolicy |
| { |
| |
| private String profile; |
| |
| public ProfileMatchPolicy( String profile ) |
| { |
| this.profile = profile; |
| } |
| |
| public boolean match( NetDependency netDependency ) |
| { |
| //If no profile is specified in net-dependencies.xml, it matches |
| if ( netDependency.getProfile() == null || netDependency.getProfile().trim().equals( "" ) ) |
| { |
| return true; |
| } |
| |
| if ( profile == null ) |
| { |
| return false; |
| } |
| |
| return profile.equals( netDependency.getProfile() ); |
| } |
| } |
| } |