Java tutorial
/* * Copyright 2012 Andrej Petras <andrej@ajka-andrej.com>. * * 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 net.java.jpatch.maven.common; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import net.java.jpatch.maven.PatchMojo; import net.java.jpatch.maven.logger.JPatchLogger; import net.java.jpatch.maven.util.FileUtil; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.manager.WagonManager; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.*; import org.apache.maven.project.path.PathTranslator; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.settings.Settings; import org.codehaus.mojo.versions.api.DefaultVersionsHelper; import org.codehaus.mojo.versions.api.VersionsHelper; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.zip.ZipArchiver; import org.codehaus.plexus.archiver.zip.ZipUnArchiver; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.components.io.fileselectors.FileInfo; import org.codehaus.plexus.components.io.fileselectors.FileSelector; import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; import org.sonatype.aether.util.DefaultRepositorySystemSession; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.cli.ExecutionEventLogger; import org.apache.maven.execution.*; import org.apache.maven.lifecycle.internal.ExecutionEventCatapult; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.scm.manager.ScmManager; import org.apache.maven.shared.invoker.InvocationRequest; import org.apache.maven.shared.invoker.InvocationResult; import org.apache.maven.shared.invoker.Invoker; import org.apache.maven.shared.invoker.MavenCommandLineBuilder; import org.codehaus.mojo.versions.api.ArtifactVersions; /** * The abstract MAVEN class. * * @author Andrej Petras <andrej@ajka-andrej.com> */ public abstract class AbstractMavenMojo extends AbstractMojo { /** The property: RELEASE_PROPERTY_DATE */ protected static final String RELEASE_PROPERTY_DATE = "Date"; /** The property: RELEASE_PROPERTY_USER_NAME */ protected static final String RELEASE_PROPERTY_USER_NAME = "User"; /** The property: RELEASE_PROPERTY_JAVA_VERSION */ protected static final String RELEASE_PROPERTY_JAVA_VERSION = "Java"; /** The property: RELEASE_PROPERTY_OS_NAME */ protected static final String RELEASE_PROPERTY_OS_NAME = "Os"; /** * Include packages to run. * @parameter expression="${includePackages}" default-value="jar,war,ejb,ear" */ private String includePackages; /** * Exclude file types from the build package/release process. * * @parameter expression="${excludeExt}" default-value="jar,war,ear,zip,rar" */ private String excludeExt; /** * The list of projects. * * @parameter expression="${projects}" * @required */ protected List<String> projects; /** * The MAVEN file. * * @parameter expression="${mavenFile}" default-value="pom.xml" */ protected String mavenFile; /** * The release name. * * @parameter expression="${releaseSuffix}" default-value="RELEASE" */ private String releaseSuffix; /** * The patch name. * * @parameter expression="${patchSuffix}" default-value="FP" */ private String patchSuffix; /** * @parameter expression="${localRepository}" * @required * @readonly */ protected ArtifactRepository localRepository; /** * @parameter expression="${project.remoteArtifactRepositories}" * @required * @readonly */ protected List<ArtifactRepository> remoteRepositories; /** * The project builder. * * @component */ @Requirement private ProjectBuilder projectBuilder; /** * The execution event catapult. * * @component */ private ExecutionEventCatapult eventCatapult; /** * The MAVEN invoker. * * @component */ private Invoker invoker; /** * The SCM manager. * * @component */ protected ScmManager scmManager; /** * Component used to create an artifact. * * @component */ protected RepositorySystem repositorySystem; /** * The MAVEN project. * * @parameter default-value="${project}" * @required * @readonly */ protected MavenProject mavenProject; /** * Goals to run on subproject. * @parameter expression="${goals}" default-value="install" */ private String goals; /** * Goals to run on subproject. * @parameter expression="${profiles}" */ private String profiles; /** * The build properties. * @parameter expression="${properties}" */ private Properties properties; /** * Gets the patch number from the artifact version. * * @param version the artifact version. * * @return the patch number. */ protected int getPatchNumber(ArtifactVersion version) { int result = -1; String tmp = version.toString(); int index = tmp.lastIndexOf(patchSuffix); if (index != -1) { try { tmp = tmp.substring(index + patchSuffix.length()); result = Integer.parseInt(tmp); } catch (Exception ex) { // do nothing } } return result; } protected Artifact createPatchArtifact(int number) { return createPatchArtifact(mavenProject.getVersion() + "-" + patchSuffix + number); } protected Artifact createPatchArtifact(String version) { return createArtifact(mavenProject.getGroupId(), mavenProject.getArtifactId(), version, "zip"); } protected Artifact createPatchArtifact() { return createPatchArtifact(mavenProject.getVersion() + "-" + patchSuffix); } protected Artifact createReleaseArtifact() { return createArtifact(mavenProject.getGroupId(), mavenProject.getArtifactId(), mavenProject.getVersion() + "-" + releaseSuffix, "zip"); } protected Properties loadReleaseProperties() throws MojoExecutionException { Artifact releaseArtifact = createReleaseArtifact(); File directory = createTargetDirectory(releaseArtifact.getVersion()); Properties result = new Properties(); try { File propFile = new File(directory, mavenProject.getBuild().getFinalName() + ".properties"); result.load(new FileInputStream(propFile)); } catch (IOException e) { throw new MojoExecutionException("Error creating the release properties file!", e); } return result; } protected Artifact resolveReleaseArtifact() { // Create release artifact Artifact releaseArtifact = createReleaseArtifact(); // Search for existing release resolveArtifactFromLocalRepository(releaseArtifact); return releaseArtifact; } /** * Setups the release artifact. * - create release artifact * - unpack release artifact * - load the release properties * * @return the release properties. * * @throws MojoExecutionException if the method fails. * @throws MojoFailureException if the method fails. */ protected File setupReleaseDirectory() throws MojoExecutionException, MojoFailureException { // Resolve release artifact Artifact releaseArtifact = resolveReleaseArtifact(); File releaseFile = releaseArtifact.getFile(); // Check existing release if (releaseFile == null || !releaseFile.exists()) { getLog().info(releaseFile.getAbsolutePath()); getLog().error("Release file does not exist! For new release execute first jpatch:release."); throw new MojoFailureException("Release package does not exist!"); } // Create release directory File directory = createTargetDirectory(releaseArtifact.getVersion()); // Unpack release in the target directory unpackFile(directory.getParentFile(), releaseArtifact.getFile(), directory.getName()); return directory; } /** * Setups the release artifact. * - create release artifact * - unpack release artifact * - load the release properties * * @return the release properties. * * @throws MojoExecutionException if the method fails. * @throws MojoFailureException if the method fails. */ protected Properties setupReleaseArtifact() throws MojoExecutionException, MojoFailureException { File releaseDirectory = setupReleaseDirectory(); // Open release properties file Properties releaseProperties = loadReleaseProperties(); return releaseProperties; } /** * Finds all version of the artifact. * * @param artifact the artifact. * * @return the list of artifact versions. * * @throws MojoExecutionException if the method fails. */ protected List<ArtifactVersion> findAllVersionOfArtifact(Artifact artifact) throws MojoExecutionException { List<ArtifactVersion> result = new ArrayList<ArtifactVersion>(); try { ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false); if (versions != null) { versions.setIncludeSnapshots(true); result.addAll(Arrays.asList(versions.getVersions())); } } catch (ArtifactMetadataRetrievalException ex) { throw new MojoExecutionException( "Error by searching the artifact version. Artifact " + artifact.getId(), ex); } return result; } /** * Executes the build of the list of projects. * * @param projects the list of projects. * * @throws MojoExecutionException if the method fails. * @throws MojoFailureException if the method fails. */ protected void executeBuildProjects(List<MavenProject> projects) throws MojoExecutionException, MojoFailureException { // Execute projects getLog().info("Execute build projects"); MavenSession mavenSession = createMavenSession(projects); buildMavenSession(mavenSession); // Check the build result if (mavenSession.getResult().hasExceptions()) { Throwable throwable = mavenSession.getResult().getExceptions().get(0); throw new MojoFailureException("Error by executing the build!", throwable); } } protected static List<MavenProject> filterMavenProjects(List<MavenProject> projects, Set<String> packages) throws MojoExecutionException { List<MavenProject> result = new ArrayList<MavenProject>(); for (MavenProject project : projects) { if (packages.contains(project.getPackaging())) { result.add(project); } } return result; } protected void packDirectory(File directory, File file) { ZipArchiver archiver = new ZipArchiver(); archiver.setDestFile(file); archiver.addDirectory(directory); try { archiver.createArchive(); } catch (ArchiverException ex) { Logger.getLogger(PatchMojo.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(PatchMojo.class.getName()).log(Level.SEVERE, null, ex); } } protected void unpackFile(File directory, File file) { unpackFile(directory, file, file.getName()); } protected void unpackFile(File directory, File file, String name) { getLog().info("Unpack file " + file.getName()); File unpackDir = new File(directory, name); unpackDir.mkdirs(); ZipUnArchiver unArchiver = new ZipUnArchiver(file); unArchiver.setDestDirectory(unpackDir); unArchiver.enableLogging(new JPatchLogger(getLog())); unArchiver.extract(); } protected File unpackArtifactFile(File directory, File file) { return unpackArtifactFile(directory, file, file.getName()); } protected File unpackArtifactFile(File directory, File file, String name) { getLog().info("Unpack file " + file.getName()); File unpackDir = new File(directory, name); unpackDir.mkdirs(); ZipUnArchiver unArchiver = new ZipUnArchiver(file); unArchiver.setDestDirectory(unpackDir); unArchiver.enableLogging(new JPatchLogger(getLog())); final Set<String> exclude = getExcludeExt(); FileSelector selector = new FileSelector() { @Override public boolean isSelected(FileInfo fi) throws IOException { boolean result; String name = fi.getName(); if (fi.isDirectory()) { name = name.substring(0, name.length() - 1); } String ext = FileUtil.getFileNameExt(name); result = !exclude.contains(ext); if (result) { int index = name.indexOf("/"); if (index != -1) { String prefix = name.substring(0, index); ext = FileUtil.getFileNameExt(prefix); result = !exclude.contains(ext); } } return result; } }; unArchiver.setFileSelectors(new FileSelector[] { selector }); unArchiver.extract(); return unpackDir; } protected File createAndAttachedPackage(File directory) { String fileName = mavenProject.getBuild().getFinalName(); File packFile = new File(mavenProject.getBuild().getDirectory(), fileName + ".zip"); packDirectory(directory, packFile); addAttachedArtifact(mavenProject.getGroupId(), mavenProject.getArtifactId(), mavenProject.getVersion(), "zip", packFile); return packFile; } protected void addAttachedArtifact(String groupId, String artifactId, String version, String packaging, File file) { Artifact pack = repositorySystem.createArtifact(groupId, artifactId, version, packaging); pack.setFile(file); mavenProject.addAttachedArtifact(pack); } private Artifact createArtifact(String groupId, String artifactId, String version, String packaging) { return repositorySystem.createArtifact(groupId, artifactId, version, packaging); } protected void addAttachedArtifact(String groupId, String artifactId, String version, String type, String classifier, File file) { Artifact result = repositorySystem.createArtifactWithClassifier(groupId, artifactId, version, type, classifier); result.setFile(file); mavenProject.addAttachedArtifact(result); } protected File createTargetDirectory(String name) { File result = new File(mavenProject.getBuild().getDirectory(), name); if (!result.exists()) { result.mkdirs(); } return result; } protected File createBuildFile() { String fileName = mavenProject.getBuild().getFinalName(); String buildDirectory = mavenProject.getBuild().getDirectory(); String packaging = mavenProject.getPackaging(); File buildFile = new File(buildDirectory, fileName + "." + packaging); try { buildFile.createNewFile(); } catch (IOException ex) { Logger.getLogger(PatchMojo.class.getName()).log(Level.SEVERE, null, ex); } mavenProject.getArtifact().setFile(buildFile); return buildFile; } protected void resolveArtifactFromLocalRepository(Artifact artifact) { ArtifactResolutionRequest request = new ArtifactResolutionRequest(); request.setLocalRepository(localRepository); request.setArtifact(artifact); repositorySystem.resolve(request); } protected Set<String> getExcludeExt() { List<String> tmp = Arrays.asList(excludeExt.split(",")); Set<String> result = new HashSet<String>(tmp); return result; } protected Set<String> getPackages() { List<String> tmp = Arrays.asList(includePackages.split(",")); Set<String> result = new HashSet<String>(tmp); return result; } /** * Loads the list of projects. * * @param directories the list of project directories. * * @return the list of the MAVEN projects. * * @throws MojoExecutionException * @throws ProjectBuildingException */ protected List<MavenProject> loadMavenProjects() throws MojoExecutionException { List<File> files = new ArrayList<File>(); for (String item : projects) { File file = new File(item, mavenFile); files.add(file); } DefaultRepositorySystemSession mavenSession = new DefaultRepositorySystemSession(); mavenSession.setLocalRepositoryManager(new SimpleLocalRepositoryManager(localRepository.getBasedir())); DefaultProjectBuildingRequest config = new DefaultProjectBuildingRequest(); config.setLocalRepository(localRepository); config.setRemoteRepositories(remoteRepositories); config.setRepositorySession(mavenSession); List<ProjectBuildingResult> results = null; try { results = projectBuilder.build(files, true, config); } catch (ProjectBuildingException ex) { throw new MojoExecutionException("Error create the maven project!", ex); } List<MavenProject> result = new ArrayList<MavenProject>(); for (ProjectBuildingResult item : results) { result.add(item.getProject()); } return result; } /** * Creates the MAVEN session. * * @return the MAVEN session. */ protected MavenSession createMavenSession(List<MavenProject> mavenProjects) { JPatchLogger jpatchLogger = new JPatchLogger(getLog()); ExecutionListener listener = new ExecutionEventLogger(jpatchLogger); MavenExecutionRequest execRequest = new DefaultMavenExecutionRequest(); execRequest.setStartTime(new Date()); execRequest.setExecutionListener(listener); MavenExecutionResult execResult = new DefaultMavenExecutionResult(); MavenSession result = new MavenSession(null, null, execRequest, execResult); result.setProjects(mavenProjects); return result; } // /** // * Short the MAVEN project. // * // * @param mavenProjects the list of MAVEN projects. // * // * @return shorted list of MAVEN projects. // */ // protected List<MavenProject> createBuildOrder(List<MavenProject> mavenProjects) throws MojoFailureException { // List<MavenProject> result = new ArrayList<MavenProject>(); // try { // ProjectSorter sorter = new ProjectSorter(mavenProjects); // result.addAll(sorter.getSortedProjects()); // } catch (Exception ex) { // getLog().error("Error by creating the build order.", ex); // throw new MojoFailureException("Error by creating the build order.", ex); // } // return result; // } /** * Builds the MAVEN session. * * @param session the MAVEN session. * */ protected void buildMavenSession(MavenSession session) { List<String> buildGoals = Arrays.asList(goals.split(",")); List<String> buildProfiles = null; if (profiles != null) { buildProfiles = Arrays.asList(profiles.split(",")); } eventCatapult.fire(ExecutionEvent.Type.SessionStarted, session, null); for (MavenProject project : session.getProjects()) { BuildSummary buildSummary = buildMavenProject(project, buildGoals, buildProfiles); session.getResult().addBuildSummary(buildSummary); if (buildSummary instanceof BuildFailure) { BuildFailure bf = (BuildFailure) buildSummary; session.getResult().addException(bf.getCause()); break; } } eventCatapult.fire(ExecutionEvent.Type.SessionEnded, session, null); } /** * Build MAVEN project. * * @param project the MAVEN project. * @param buildGoals the goals; * @param buildProfiles the profiles; * * @return the build summary. */ private BuildSummary buildMavenProject(MavenProject project, List<String> buildGoals, List<String> buildProfiles) { BuildSummary result; InvocationRequest request = new InvocationBuildRequest(); request.setPomFile(project.getFile()); request.setGoals(buildGoals); request.setRecursive(false); request.setProfiles(buildProfiles); request.setProperties(properties); Date startTime = new Date(); try { getLog().info(""); getLog().info("Build project [" + project.getId() + "]"); getLog().info("Command " + new MavenCommandLineBuilder().build(request)); getLog().info(""); InvocationResult invokerResult = invoker.execute(request); if (invokerResult.getExecutionException() != null) { throw invokerResult.getExecutionException(); } if (invokerResult.getExitCode() != 0) { throw new MojoFailureException("Exit code was " + invokerResult.getExitCode()); } result = new BuildSuccess(project, new Date().getTime() - startTime.getTime()); } catch (Exception e) { Date finished = new Date(); result = new BuildFailure(project, finished.getTime() - startTime.getTime(), e); } return result; } /** * @component * @since 1.0-alpha-1 */ protected org.apache.maven.artifact.factory.ArtifactFactory artifactFactory; /** * @component * @since 1.0-alpha-1 */ protected org.apache.maven.artifact.resolver.ArtifactResolver resolver; /** * @parameter expression="${reactorProjects}" * @required * @readonly * @since 1.0-alpha-1 */ protected List reactorProjects; /** * The artifact metadata source to use. * * @component * @required * @readonly * @since 1.0-alpha-1 */ protected ArtifactMetadataSource artifactMetadataSource; /** * @parameter expression="${project.remoteArtifactRepositories}" * @readonly * @since 1.0-alpha-3 */ protected List remoteArtifactRepositories; /** * @parameter expression="${project.pluginArtifactRepositories}" * @readonly * @since 1.0-alpha-3 */ protected List remotePluginRepositories; /** * @component * @since 1.0-alpha-3 */ private WagonManager wagonManager; /** * @parameter expression="${settings}" * @readonly * @since 1.0-alpha-3 */ protected Settings settings; /** * settings.xml's server id for the URL. * This is used when wagon needs extra authentication information. * * @parameter expression="${maven.version.rules.serverId}" default-value="serverId"; * @since 1.0-alpha-3 */ private String serverId; /** * The Wagon URI of a ruleSet file containing the rules that control how to compare version numbers. * * @parameter expression="${maven.version.rules}" * @since 1.0-alpha-3 */ private String rulesUri; /** * Whether to allow snapshots when searching for the latest version of an artifact. * * @parameter expression="${allowSnapshots}" default-value="false" * @since 1.0-alpha-1 */ protected Boolean allowSnapshots; /** * Our versions helper. */ private VersionsHelper helper; /** * The Maven Session. * * @parameter expression="${session}" * @required * @readonly * @since 1.0-alpha-1 */ protected MavenSession session; /** * @component */ protected PathTranslator pathTranslator; /** * @component */ protected ArtifactResolver artifactResolver; public VersionsHelper getHelper() throws MojoExecutionException { if (helper == null) { helper = new DefaultVersionsHelper(artifactFactory, artifactMetadataSource, remoteArtifactRepositories, remotePluginRepositories, localRepository, wagonManager, settings, serverId, rulesUri, getLog(), session, pathTranslator); } return helper; } }