/* * Copyright 2013 James Moger * * 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.moxie.ant; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.Iterator; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.resources.FileResource; import org.moxie.Dependency; import org.moxie.IMavenCache; import org.moxie.MavenCache; import org.moxie.Metadata; import org.moxie.MetadataReader; import org.moxie.MoxieException; import org.moxie.Pom; import org.moxie.PurgePolicy; import org.moxie.Repository; import org.moxie.utils.FileUtils; import org.moxie.utils.StringUtils; public abstract class MxRepositoryTask extends MxTask { protected File baseDir; protected String repositoryId; protected String refId; protected boolean allowSnapshots; protected boolean calculateChecksums; protected boolean generatePom; private Path installedArtifacts; public MxRepositoryTask() { super(); } public void setBaseDir(File dir) { this.baseDir = dir; } public File getBaseDir() { return baseDir; } public void setAllowsnapshots(boolean value) { allowSnapshots = value; } public void setCalculatechecksums(boolean value) { calculateChecksums = value; } public void setGeneratePom(boolean value) { generatePom = value; } public void setRepositoryId(String value) { repositoryId = value; } public void setPathId(String id) { installedArtifacts = new Path(getProject()); getProject().addReference(id, installedArtifacts); } protected IMavenCache getArtifactCache(boolean isSnapshot) { IMavenCache cache; if (baseDir == null) { if (StringUtils.isEmpty(repositoryId)) { // return MoxieCache cache = getBuild().getSolver().getMoxieCache(); } else { // get repository by identifier Repository repository = getBuild().getConfig().getRepository(repositoryId); if (repository == null) { throw new MoxieException("Failed to find repositoryId: {0}", repositoryId); } if (isSnapshot && !repository.allowSnapshots()) { if (allowSnapshots) { getConsole().warn("Repository \"{0}\" prohibits snapshots! Overridden by \"allowSnapshots\" attribute!", repository.toString()); } else { throw new MoxieException("Repository \"{0}\" prohibits installation or deployment of snapshots!", repository.toString(), repository.getRepositoryUrl()); } } String url = repository.getRepositoryUrl(); if (url.startsWith("file:/")) { try { URI uri = new URI(url); baseDir = new File(uri); cache = new MavenCache(baseDir); } catch (URISyntaxException e) { throw new MoxieException("Failed to parse " + url, e); } } else { throw new MoxieException("Invalid url \"{0}\"! Moxie does not support installing or deploying artifacts to remote repositories!", url); } } } else { // return MavenCache for specified directory cache = new MavenCache(baseDir); } return cache; } /** * Install release artifacts to the artifact directory. * * @param pom * @param sourceDir * @param artifactDir * @param optionally update metadata */ protected void deployRelease(Pom pom, File sourceDir, File artifactDir, boolean updateMetadata) { String artifact = pom.artifactId + "-" + pom.version; String pattern = artifact + "*"; Dependency asDependency = new Dependency(pom.getCoordinates()); // copy artifacts copy(sourceDir, pattern, artifactDir); // output pom file generatePom(artifactDir, pom, artifact); // calculate checksums for each file calculateChecksums(artifactDir, pattern); // optionally update metadata if (updateMetadata) { updateArtifactsMetadata(artifactDir, asDependency); } } /** * Copies files of a particular pattern from one location to another * * @param fromDir * @param pattern * @param toDir */ protected void copy(File fromDir, String pattern, File toDir) { FileSet fs = new FileSet(); fs.setProject(getProject()); fs.setDir(fromDir); fs.setIncludes(pattern); Copy copy = new Copy(); copy.setTaskName(getTaskName()); copy.setProject(getProject()); copy.setTodir(toDir); copy.setVerbose(isVerbose()); copy.add(fs); copy.execute(); // add files to installed artifacts path reference(fs); } /** * Copies a single file to a destination file of a different name and/or * location. * * @param sourceFile * @param targetFile */ protected void copyFile(File sourceFile, File targetFile) { Copy copy = new Copy(); copy.setTaskName(getTaskName()); copy.setProject(getProject()); copy.setFile(sourceFile); copy.setTofile(targetFile); copy.setVerbose(isVerbose()); copy.execute(); // add target file to installed artifacts path reference(targetFile); } /** * Generates a pom.xml file * * @param dir * @param pom * @param artifact */ protected void generatePom(File dir, Pom pom, String artifact) { if (generatePom) { // output pom file getConsole().debug("generating pom"); File pomFile = new File(dir, artifact + ".pom"); FileUtils.writeContent(pomFile, pom.toXML(false)); getConsole().debug(1, "wrote {0}", pomFile); // add pom file to installed artifacts path reference(pomFile); } } /** * Updates the artifacts maven-metadata.xml with the current versions * information. * * e.g. org/moxie/toolkit/maven-metadata.xml * * @param artifactDir * @param dependency */ protected void updateArtifactsMetadata(File artifactDir, Dependency dependency) { // create/update ARTIFACTS metadata File artifactsDir = artifactDir.getParentFile(); updateMetadata(artifactsDir, dependency, false); calculateChecksums(artifactsDir, "maven-metadata.xml"); } /** * Updates the snapshot maven-metadata.xml with the current snapshot revision * and purges obsolete artifacts according to the purge policy. * * @param artifactDir * @param dependency * @param policy */ protected void updateSnapshotMetadata(File artifactDir, Dependency dependency, PurgePolicy policy) { // create/update SNAPSHOT/maven-metadata.xml updateMetadata(artifactDir, dependency, true); // purge old snapshots from SNAPSHOT/maven-metadata.xml getArtifactCache(true).purgeSnapshots(dependency, policy); calculateChecksums(artifactDir, "maven-metadata.xml"); } private void updateMetadata(File dir, Dependency dependency, boolean isSnapshotMetadata) { // create/update maven-metadata.xml File metadataFile = new File(dir, "maven-metadata.xml"); Metadata oldMetadata = null; if (metadataFile.exists()) { oldMetadata = MetadataReader.readMetadata(metadataFile); } Metadata metadata = new Metadata(dependency, isSnapshotMetadata); if (oldMetadata != null) { metadata.merge(oldMetadata); } FileUtils.writeContent(metadataFile, metadata.toXML()); metadataFile.setLastModified(metadata.lastUpdated.getTime()); // add metadata file to installed artifacts path reference(metadataFile); } /** * Calculates SHA1 and MD5 checksums for the files in the directory which * match the specified pattern. * * @param dir * @param pattern */ protected void calculateChecksums(File dir, String pattern) { if (calculateChecksums) { getConsole().debug("calculating checksums for artifacts in {0}", dir); FileSet repoSet = new FileSet(); repoSet.setProject(getProject()); repoSet.setDir(dir); repoSet.setIncludes(pattern); repoSet.setExcludes("*.sha1, *.md5, *.sig, *.asc"); Iterator<?> itr = repoSet.iterator(); while (itr.hasNext()) { FileResource file = (FileResource) itr.next(); byte [] bytes = FileUtils.readContent(file.getFile()); // calculate the SHA1 hash of the content and save result String sha1 = StringUtils.getSHA1(bytes); File sha1File = new File(dir, file.getFile().getName() + ".sha1"); FileUtils.writeContent(sha1File, sha1); getConsole().debug(1, "wrote {0}", sha1File); // add sha1 file to installed artifacts path reference(sha1File); // calculate the MD5 hash of the content and save result String md5 = StringUtils.getMD5(bytes); File md5File = new File(dir, file.getFile().getName() + ".md5"); FileUtils.writeContent(md5File, md5); getConsole().debug(1, "wrote {0}", md5File); // add md5 file to installed artifacts path reference(md5File); } } } /** * Add a reference to the installed/deployed file for processing in Ant. * * @param file */ private void reference(File file) { if (installedArtifacts != null) { installedArtifacts.createPathElement().setLocation(file); } } /** * Add a reference to the fileset for processing in Ant. * * @param file */ private void reference(FileSet fs) { if (installedArtifacts != null) { installedArtifacts.addFileset(fs); } } }