| /** |
| * 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.marmotta.maven.plugins.refpack; |
| |
| import org.apache.maven.artifact.factory.ArtifactFactory; |
| import org.apache.maven.model.Model; |
| import org.apache.maven.model.building.ModelBuildingRequest; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugins.annotations.*; |
| import org.apache.maven.project.*; |
| import org.jdom2.Element; |
| import org.jdom2.Text; |
| import org.jdom2.output.Format; |
| import org.jdom2.output.XMLOutputter; |
| import org.sonatype.aether.RepositorySystem; |
| import org.sonatype.aether.RepositorySystemSession; |
| import org.sonatype.aether.artifact.Artifact; |
| import org.sonatype.aether.collection.CollectRequest; |
| import org.sonatype.aether.collection.DependencyCollectionException; |
| import org.sonatype.aether.graph.Dependency; |
| import org.sonatype.aether.graph.DependencyNode; |
| import org.sonatype.aether.repository.RemoteRepository; |
| import org.sonatype.aether.resolution.DependencyRequest; |
| import org.sonatype.aether.resolution.DependencyResolutionException; |
| import org.sonatype.aether.resolution.DependencyResult; |
| import org.sonatype.aether.util.artifact.DefaultArtifact; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Generate IzPack refpack descriptions from Maven dependencies |
| */ |
| @Mojo(name = "generate", defaultPhase = LifecyclePhase.VALIDATE, requiresDependencyResolution = ResolutionScope.COMPILE) |
| public class RefPackMojo extends AbstractMojo { |
| |
| /** |
| * Location of the file. |
| */ |
| @Parameter(property="project.build.directory", required = true) |
| private File outputDirectory; |
| |
| @Parameter(property = "project", required = true, readonly = true) |
| private MavenProject project; |
| |
| /** |
| * The Group Identifier of the artifacts that should be considered local modules. When walking |
| * the dependency tree, the process will break at each module of this group id and instead add |
| * a dependency to the other module to the refpacks. |
| */ |
| @Parameter(property="refpack.moduleGroupId", defaultValue="org.apache.marmotta", required = true) |
| private String moduleGroupId; |
| |
| /** |
| * The entry point to Aether, i.e. the component doing all the work. |
| * |
| */ |
| @Component |
| private RepositorySystem repoSystem; |
| |
| @Parameter(defaultValue = "${repositorySystemSession}", readonly = true) |
| private RepositorySystemSession session; |
| |
| /** |
| * The project's remote repositories to use for the resolution of project dependencies. |
| */ |
| @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true) |
| private List<RemoteRepository> projectRepos; |
| |
| @Component |
| private ProjectBuilder projectBuilder; |
| |
| @Component |
| private ArtifactFactory artifactFactory; |
| |
| /** |
| * The required modules of the refpack |
| */ |
| @Parameter(property = "refpack.requiredModules") |
| private List<String> requiredModules; |
| |
| // we collect here the library dependencies of each module, so we can identify which of the dependencies are already |
| // covered by another module the current module depends on |
| private HashMap<Artifact,Set<Artifact>> moduleLibraries; |
| |
| // and here we collect the module dependencies of each module |
| private HashMap<Artifact,Set<Artifact>> moduleDependencies; |
| |
| public void execute() throws MojoExecutionException { |
| moduleLibraries = new HashMap<Artifact, Set<Artifact>>(); |
| moduleDependencies = new HashMap<Artifact, Set<Artifact>>(); |
| |
| getLog().info("generating reference packs for group id "+moduleGroupId); |
| |
| for(org.apache.maven.artifact.Artifact artifact : project.getArtifacts()) { |
| if(artifact.getGroupId().equals(moduleGroupId)) { |
| |
| DefaultArtifact aetherArtifact = new DefaultArtifact(artifact.getGroupId(),artifact.getArtifactId(), artifact.getType(), artifact.getVersion()); |
| Dependency rootDependency = new Dependency(aetherArtifact, "runtime"); |
| |
| try { |
| CollectRequest collectRequest = new CollectRequest(); |
| collectRequest.setRoot(rootDependency); |
| collectRequest.setRepositories(projectRepos); |
| |
| DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot(); |
| |
| DependencyRequest request = new DependencyRequest(rootNode,null); |
| DependencyResult result = repoSystem.resolveDependencies(session,request); |
| |
| |
| getLog().info("Artifact: " + aetherArtifact); |
| for(DependencyNode child : result.getRoot().getChildren()) { |
| if(child.getDependency().getArtifact().getGroupId().equals(moduleGroupId)) { |
| processModule(child); |
| } |
| } |
| processModule(result.getRoot()); |
| /* |
| deps = aether.resolve(aetherArtifact, JavaScopes.RUNTIME); |
| |
| getLog().info("Artifact: "+aetherArtifact); |
| for(Artifact dep : deps) { |
| getLog().info("- dependency "+dep.getFile().getAbsolutePath()); |
| } |
| */ |
| } catch (DependencyResolutionException e) { |
| getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e); |
| } catch (DependencyCollectionException e) { |
| getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e); |
| } |
| } |
| |
| } |
| |
| } |
| |
| /** |
| * Collect the dependencies to other libraries that are not already collected by modules the current |
| * module depends on. |
| * |
| * @param node |
| * @param currentModule |
| */ |
| private void collectLibraryDependencies(DependencyNode node, Artifact currentModule) { |
| String groupId = node.getDependency().getArtifact().getGroupId(); |
| String artifactId = node.getDependency().getArtifact().getArtifactId(); |
| if(!isPackDependency(groupId, artifactId)) { |
| // first check if the current artifact is already covered by a module the current module depends on |
| for(Artifact dependentArtifact : moduleDependencies.get(currentModule)) { |
| if(moduleLibraries.containsKey(dependentArtifact) && |
| moduleLibraries.get(dependentArtifact).contains(node.getDependency().getArtifact())) { |
| return; |
| } |
| } |
| |
| // collect the current dependency for the module |
| moduleLibraries.get(currentModule).add(node.getDependency().getArtifact()); |
| |
| for(DependencyNode child : node.getChildren()) { |
| collectLibraryDependencies(child, currentModule); |
| } |
| } |
| } |
| |
| private boolean isPackDependency(String groupId, String artifactId) { |
| // only marmotta group-id and artifacts starting with marmotta- |
| return groupId.equals(moduleGroupId) && artifactId.startsWith("marmotta-") |
| // but not the commons and the JS-client |
| && !artifactId.equals("marmotta-commons") && !artifactId.equals("marmotta-client-js") |
| // and not the marmotta-sesame-tools |
| && !artifactId.startsWith("marmotta-util-") && !artifactId.startsWith("marmotta-sail-") |
| && !artifactId.startsWith("marmotta-rio-") && !artifactId.startsWith("marmotta-model-"); |
| } |
| |
| /** |
| * Collect the dependencies to other modules inside the same project |
| * @param node |
| * @param currentModule |
| */ |
| private void collectModuleDependencies(DependencyNode node, Artifact currentModule) { |
| String groupId = node.getDependency().getArtifact().getGroupId(); |
| String artifactId = node.getDependency().getArtifact().getArtifactId(); |
| if(isPackDependency(groupId, artifactId)) { |
| moduleDependencies.get(currentModule).add(node.getDependency().getArtifact()); |
| } |
| } |
| |
| private void processModule(DependencyNode moduleNode) { |
| CollectRequest collectRequest = new CollectRequest(); |
| collectRequest.setRoot(moduleNode.getDependency()); |
| collectRequest.setRepositories(projectRepos); |
| try { |
| // collect all the dependency graph for the module, and print it until we reach a dependency to a local module |
| DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot(); |
| |
| DependencyRequest request = new DependencyRequest(rootNode,null); |
| DependencyResult result = repoSystem.resolveDependencies(session,request); |
| |
| // add entry to module dependencies |
| moduleLibraries.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>()); |
| moduleDependencies.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>()); |
| |
| getLog().info("processing module "+moduleNode.getDependency().getArtifact().getArtifactId()+":"); |
| for(DependencyNode child : result.getRoot().getChildren()) { |
| collectModuleDependencies(child,moduleNode.getDependency().getArtifact()); |
| } |
| for(DependencyNode child : result.getRoot().getChildren()) { |
| collectLibraryDependencies(child, moduleNode.getDependency().getArtifact()); |
| } |
| |
| // information output |
| /* |
| for(Artifact otherModule : moduleDependencies.get(moduleNode.getDependency().getArtifact())) { |
| getLog().info(" - depending on module "+otherModule.getArtifactId()); |
| } |
| for(Artifact library : moduleLibraries.get(moduleNode.getDependency().getArtifact())) { |
| getLog().info(" - depending on library "+library); |
| } |
| */ |
| |
| File destination = new File(outputDirectory, moduleNode.getDependency().getArtifact().getArtifactId() + ".xml"); |
| if (!destination.getParentFile().exists()) { |
| destination.getParentFile().mkdirs(); |
| } |
| if (!destination.exists()) { |
| destination.createNewFile(); |
| } |
| |
| getLog().info("writing refpack to " + destination.getAbsolutePath()); |
| |
| // write to output directory |
| writeModuleXML(moduleNode.getDependency().getArtifact(), new FileOutputStream(destination)); |
| |
| } catch (DependencyCollectionException e) { |
| getLog().error("error while collecting dependencies for module " + moduleNode.getDependency().getArtifact(), e); |
| } catch (DependencyResolutionException e) { |
| getLog().error("error while resolving dependencies for module " + moduleNode.getDependency().getArtifact(), e); |
| } catch (IOException e) { |
| getLog().error("I/O error while writing refpack for module " + moduleNode.getDependency().getArtifact(), e); |
| } |
| |
| } |
| |
| private void writeModuleXML(Artifact module, OutputStream out) throws IOException { |
| Element installation = new Element("installation"); |
| installation.setAttribute("version","1.0"); |
| |
| Element packs = new Element("packs"); |
| installation.addContent(packs); |
| |
| Element pack = new Element("pack"); |
| packs.addContent(pack); |
| |
| // get the model for the artifact, we read name and description from it |
| |
| Model pom = getArtifactModel(module); |
| |
| // set name of pack from artifact |
| if(pom != null && pom.getName() != null) { |
| pack.setAttribute("name",pom.getName()); |
| } else { |
| pack.setAttribute("name",module.getArtifactId()); |
| } |
| |
| if(pom != null && pom.getDescription() != null) { |
| Element description = new Element("description"); |
| description.setText(Text.normalizeString(pom.getDescription())); |
| pack.addContent(description); |
| } |
| |
| // add a file entry for the module itself |
| if(!module.getExtension().equals("war")) { |
| Element mainFile = new Element("file"); |
| pack.addContent(mainFile); |
| mainFile.setAttribute("src",module.getFile().getAbsolutePath()); |
| mainFile.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/WEB-INF/lib"); |
| } |
| |
| // add a file entry for each library of the artifact |
| for(Artifact library : moduleLibraries.get(module)) { |
| Element file = new Element("file"); |
| pack.addContent(file); |
| file.setAttribute("src",library.getFile().getAbsolutePath()); |
| file.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/WEB-INF/lib"); |
| } |
| |
| // add a depends name for each module the current one depends on (in case the project is not the webapp) |
| if(!module.getExtension().equals("war")) { |
| if(requiredModules.contains(module.getArtifactId())) { |
| pack.setAttribute("required","yes"); |
| } else { |
| pack.setAttribute("required","no"); |
| } |
| |
| for(Artifact dependency : moduleDependencies.get(module)) { |
| Element depends = new Element("depends"); |
| pack.addContent(depends); |
| |
| // get the model for the artifact, we read name and description from it |
| Model pom2 = getArtifactModel(dependency); |
| |
| // set name of pack from artifact |
| if(pom2 != null && pom2.getName() != null) { |
| depends.setAttribute("packname", pom2.getName()); |
| } else { |
| depends.setAttribute("packname",module.getArtifactId()); |
| } |
| } |
| } else { |
| pack.setAttribute("required","yes"); |
| |
| // add webapp directory from installer configuration |
| Element appDir = new Element("fileset"); |
| appDir.setAttribute("dir",outputDirectory+"/../webapp/"); |
| appDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/marmotta/"); |
| appDir.setAttribute("includes","**"); |
| |
| pack.addContent(appDir); |
| |
| Element logDir = new Element("fileset"); |
| logDir.setAttribute("dir",outputDirectory+"/../log/"); |
| |
| logDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/logs/"); |
| logDir.setAttribute("includes","**"); |
| |
| pack.addContent(logDir); |
| } |
| |
| XMLOutputter writer = new XMLOutputter(Format.getPrettyFormat()); |
| writer.output(installation,out); |
| |
| } |
| |
| private Model getArtifactModel(Artifact artifact) { |
| org.apache.maven.artifact.Artifact mavenArtifact = artifactFactory.createArtifact(artifact.getGroupId(),artifact.getArtifactId(),artifact.getVersion(),"runtime",artifact.getExtension()); |
| |
| DefaultProjectBuildingRequest req = new DefaultProjectBuildingRequest(); |
| req.setRepositorySession(session); |
| req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT); |
| |
| try { |
| ProjectBuildingResult res = projectBuilder.build(mavenArtifact, req); |
| |
| return res.getProject().getModel(); |
| } catch (ProjectBuildingException e) { |
| getLog().warn("error building artifact model for artifact "+artifact,e); |
| return null; |
| } |
| |
| } |
| } |