Java tutorial
/* * Copyright 2010 Toni Menzel. * * 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.ops4j.pax.vault.builder; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactCollector; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.resolver.DefaultArtifactCollector; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.util.FileUtils; import org.ops4j.io.StreamUtils; /** * Woodoo * * @goal gouken * @requiresDependencyResolution test * @description build an gouken assembly */ public class BuilderPlugin extends AbstractMojo { protected static final String SEPARATOR = "/"; /** * The directory for the generated JAR. * * @parameter expression="${project.build.directory}" * @required */ private String buildDirectory; /** * Project types which this plugin supports. * * @parameter */ private List supportedProjectTypes = Arrays.asList(new String[] { "gouken" }); /** * @component */ private ArtifactHandlerManager m_artifactHandlerManager; /** * Classifier type of the bundle to be installed. For example, "jdk14". * Defaults to none which means this is the project's main bundle. * * @parameter */ protected String classifier; /** * @component */ private MavenProjectHelper m_projectHelper; /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * @parameter expression='true' * @required */ protected boolean recursive; /** * The file to generate * * @parameter default-value= * "${project.build.directory}/classes/META-INF/gouken/provisioning.properties" */ private File provisioningFile; /** * @parameter */ private Map fwOptions; /** * The file to generate * * @parameter default-value="${project.build.directory}/classes/META-INF/gouken/" */ private File folder; /** * The file to generate * * @parameter default-value="${project.build.directory}/classes/" */ private File kernelFolder; /** * @parameter default-value="${localRepository}" */ protected ArtifactRepository localRepo; /** * @parameter default-value="${project.remoteArtifactRepositories}" */ protected List remoteRepos; /** * @component */ protected ArtifactMetadataSource artifactMetadataSource; /** * @component */ protected ArtifactResolver resolver; protected ArtifactCollector collector = new DefaultArtifactCollector(); /** * @component */ protected ArtifactFactory factory; public void execute() throws MojoExecutionException, MojoFailureException { String projectType = project.getArtifact().getType(); // ignore unsupported project types, useful when bundleplugin is // configured in parent pom if (!supportedProjectTypes.contains(projectType)) { getLog().warn( "Ignoring project type " + projectType + " - supportedProjectTypes = " + supportedProjectTypes); return; } getLog().info("Execute " + BuilderPlugin.class.getName()); OutputStream out = null; try { provisioningFile.getParentFile().mkdirs(); out = new FileOutputStream(provisioningFile); StringBuilder sb = new StringBuilder(); Properties p = new Properties(); for (Object dep : project.getDependencyArtifacts()) { Artifact a = (Artifact) dep; if (a.getScope().equals("provided")) { populateProperties(sb, a.getFile().getName()); populateFile(a.getFile()); } } p.put("bundles", sb.toString()); File frameworkOptions = new File(project.getBasedir(), "framework.properties"); getLog().info("looking for " + frameworkOptions.getAbsolutePath()); if (frameworkOptions.exists()) { getLog().info("Found framework.properties"); Properties fwProps = new Properties(); fwProps.load(new FileInputStream(frameworkOptions)); p.putAll(fwProps); } p.store(out, "Written at " + new Date()); extractFile(getKernel()); File jarFile = new File(getBuildDirectory(), getBundleName(project)); exportAssembly(jarFile); Artifact mainArtifact = project.getArtifact(); // workaround for MNG-1682: force maven to install artifact using // the "jar" handler mainArtifact.setArtifactHandler(m_artifactHandlerManager.getArtifactHandler("jar")); if (null == classifier || classifier.trim().length() == 0) { mainArtifact.setFile(jarFile); } else { m_projectHelper.attachArtifact(project, jarFile, classifier); } getLog().info("Created: " + jarFile); } catch (Exception e) { throw new MojoExecutionException("Unable to create dependencies file: " + e, e); } finally { if (out != null) { try { out.close(); } catch (IOException e) { getLog().info("Failed to close: " + provisioningFile + ". Reason: " + e, e); } } } } private void exportAssembly(File jarFile) throws IOException { // Just zip folder and write to file as jar. Done. JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile)); try { File[] index = getFiles(); for (File f : index) { // sum them up all String rel = relative(f); // System.out.println( "+ " + rel ); ZipEntry entry = new ZipEntry(rel); out.putNextEntry(entry); if (f.isFile()) { InputStream fis = new FileInputStream(f); try { StreamUtils.copyStream(fis, out, false); } finally { fis.close(); } } } } finally { out.close(); } } private String relative(File f) throws IOException { String base = kernelFolder.getCanonicalPath(); return f.getCanonicalPath().substring(base.length() + 1); } private File[] getFiles() { List<File> list = new ArrayList<File>(); addAll(list, kernelFolder); // push certain keys up: File[] arr = list.toArray(new File[list.size()]); // sort: Arrays.sort(arr, new Comparator<File>() { public int compare(File file, File file1) { if (file.getName().endsWith("MANIFEST.MF")) { return -1; } else { if (file.getAbsolutePath().contains("META-INF")) { if (file1.getName().endsWith("MANIFEST.MF")) { return 1; } else { return -1; } } else { return 1; } } } }); return arr; } /** * recursive ! * * @param list * @param folder */ private void addAll(List<File> list, File folder) { for (File f : folder.listFiles()) { if (f.isFile()) { list.add(f); } else { list.add(f); addAll(list, f); } } } protected String getBundleName(MavenProject currentProject) { String finalName = currentProject.getBuild().getFinalName(); if (null != classifier && classifier.trim().length() > 0) { return finalName + '-' + classifier + ".jar"; } return finalName + ".jar"; } private void extractFile(File kernel) throws IOException { ZipInputStream in = new ZipInputStream(new FileInputStream(kernel)); ZipEntry entry = null; while ((entry = in.getNextEntry()) != null) { File sub = new File(entry.getName()); if (!entry.isDirectory()) { File dest = new File(kernelFolder.getAbsolutePath() + "/" + entry.getName()); dest.getParentFile().mkdirs(); OutputStream out = new FileOutputStream(dest); try { StreamUtils.copyStream(in, out, false); } finally { out.close(); } } } } private void populateFile(File file) throws IOException { // Basically: copy file to new destination FileUtils.copyFile(file, new File(folder, file.getName())); getLog().info("Copied file " + file.getName()); } protected void populateProperties(StringBuilder sb, String s) throws IOException { sb.append(s); sb.append(","); } public File getKernel() { File f = null; // latest local kernel for now ArtifactHandler handler = m_artifactHandlerManager.getArtifactHandler("jar"); Artifact artifact = new DefaultArtifact("com.okidokiteam.gouken", "gouken-kernel", VersionRange.createFromVersion("0.1.0-SNAPSHOT"), "compile", "jar", null, handler); ArtifactRepository repo = localRepo; try { resolver.resolve(artifact, remoteRepos, repo); f = artifact.getFile(); } catch (ArtifactResolutionException e) { e.printStackTrace(); } catch (ArtifactNotFoundException e) { e.printStackTrace(); } if (f == null) { getLog().info("Fallblack :(("); f = new File( "/Users/tonit/devel/com.okidokiteam/gouken/gouken-kernel/target/gouken-kernel-0.1.0-SNAPSHOT.jar"); } else { getLog().info("Found by resolver! ;)"); } return f; } protected String getBuildDirectory() { return buildDirectory; } protected void setBuildDirectory(String _buildirectory) { buildDirectory = _buildirectory; } }