package com.intellij.flex.maven;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.component.repository.ComponentDependency;
import org.codehaus.plexus.util.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @goal replicate-repo
* @requiresDependencyResolution compile
* @threadSafe
* @aggregator
*/
@Component(role=RepositoryReplicatorMojo.class)
public class RepositoryReplicatorMojo extends AbstractMojo {
/**
* @parameter expression="${session}"
* @required
* @readonly
*/
@SuppressWarnings({"UnusedDeclaration"})
private MavenSession session;
/**
* @parameter expression="${outputDirectory}" expression="${outputDirectory}" default-value="lib"
* @readonly
* @required
*/
@SuppressWarnings({"UnusedDeclaration"})
private File outputDirectory;
private final Set<Artifact> copiedArtifacts = new HashSet<Artifact>(64);
private final Set<String> extractedConfigs = new HashSet<String>();
@Requirement
private MavenPluginManager pluginManager;
/**
* List of remote repositories to be used by the plugin to resolve dependencies.
*
* @parameter expression="${project.remoteArtifactRepositories}"
* @readonly
*/
private List<ArtifactRepository> remoteRepositories;
@Requirement
private RepositorySystem repositorySystem;
private int localRepositoryBasedirLength;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
final String localRepositoryBasedir = session.getLocalRepository().getBasedir();
File localRepositoryFile = new File(localRepositoryBasedir);
localRepositoryBasedirLength = localRepositoryBasedir.length();
try {
final PluginDescriptor pluginDescriptor = pluginManager.getPluginDescriptor(session.getTopLevelProject().getPlugin("org.sonatype.flexmojos:flexmojos-maven-plugin"), session.getCurrentProject().getRemotePluginRepositories(), session.getRepositorySession());
final File compilerLibsDirectory = new File(outputDirectory, "../build-gant/compiler-libs");
//noinspection ResultOfMethodCallIgnored
compilerLibsDirectory.mkdirs();
for (ComponentDependency dependency : pluginDescriptor.getDependencies()) {
if (dependency.getGroupId().equals("com.adobe.flex.compiler") && dependency.getType().equals("jar")) {
final String artifactId = dependency.getArtifactId();
if (artifactId.equals("adt") || artifactId.equals("asdoc") || artifactId.equals("digest") || artifactId.equals("fcsh") || artifactId.equals("fdb") || artifactId.equals("optimizer") || artifactId.equals("swcdepends")) {
continue;
}
copyIfLastModifiedNotEquals(new File(localRepositoryFile, "com/adobe/flex/compiler/" + artifactId + "/" + dependency.getVersion() + "/" + artifactId + "-" + dependency.getVersion() + ".jar"), new File(compilerLibsDirectory, artifactId + ".jar"));
}
}
}
catch (Exception e) {
throw new MojoExecutionException("Cannot find flemxojos maven plugin", e);
}
if (outputDirectory.exists()) {
try {
FileUtils.deleteDirectory(outputDirectory);
}
catch (IOException e) {
throw new MojoExecutionException("", e);
}
}
//noinspection ResultOfMethodCallIgnored
outputDirectory.mkdirs();
for (MavenProject project : session.getProjects()) {
// skip projects artifacts
copiedArtifacts.add(project.getArtifact());
try {
copyProjectArtifacts(localRepositoryFile, project);
}
catch (IOException e) {
throw new MojoExecutionException("", e);
}
for (Plugin plugin : project.getBuildPlugins()) {
if (plugin.getGroupId().startsWith("org.apache.maven")) {
continue;
}
try {
resolveAndCopyArtifact(repositorySystem.createPluginArtifact(plugin));
}
catch (IOException e) {
throw new MojoExecutionException("", e);
}
}
}
for (MavenProject project : session.getProjects()) {
try {
copyParentPom(project.getParent());
}
catch (IOException e) {
throw new MojoExecutionException("", e);
}
}
}
private boolean resolveAndCopyArtifact(Artifact artifact) throws MojoExecutionException, IOException {
if (copiedArtifacts.contains(artifact)) {
return true;
}
copiedArtifacts.add(artifact);
File artifactFile = artifact.getFile();
if (artifactFile == null && !artifact.isResolved()) {
ArtifactResolutionRequest request = new ArtifactResolutionRequest();
request.setArtifact(artifact);
request.setLocalRepository(session.getLocalRepository());
request.setRemoteRepositories(remoteRepositories);
ArtifactResolutionResult result = repositorySystem.resolve(request);
artifactFile = artifact.getFile();
if (!result.isSuccess() && artifactFile == null) {
if (getLog().isDebugEnabled()) {
for (Exception e : result.getExceptions()) {
getLog().error(e);
}
}
throw new MojoExecutionException("Failed to resolve artifact " + artifact);
}
}
return copyArtifact(artifactFile, artifactFile.getPath().substring(localRepositoryBasedirLength));
}
//private void copyFile(String groupId, String artifactId, String version) throws IOException {
// String localPath = groupId.replace('.', File.separatorChar) + artifactId + File.separatorChar + version + File.separatorChar + artifactId + '-' + version + ".jar";
// copyIfLastModifiedNotEquals(new File(localRepositoryFile, localPath), new File(outputDirectory, localPath));
//}
private void copyParentPom(MavenProject project) throws IOException, MojoExecutionException {
if (project == null) {
return;
}
Artifact artifact = project.getArtifact();
resolveAndCopyArtifact(artifact);
copyParentPom(project.getParent());
}
private static void copyIfLastModifiedNotEquals(File from, File to) throws IOException {
if (from.lastModified() != to.lastModified()) {
Utils.copyFile(from, to);
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private void copyProjectArtifacts(File localRepositoryFile, MavenProject project)
throws MojoExecutionException, IOException {
for (Artifact artifact : project.getArtifacts()) {
if (resolveAndCopyArtifact(artifact)) {
continue;
}
final File artifactFile = artifact.getFile();
final String localPath = artifactFile.getPath().substring(localRepositoryBasedirLength);
try {
if (("configs".equals(artifact.getClassifier()) || (artifact.getClassifier() == null && "framework".equals(artifact.getArtifactId()) && artifact.getType().equals("swc"))) && !extractedConfigs.contains(artifact.getVersion())) {
extractedConfigs.add(artifact.getVersion());
final File sourceDirectory = new File(artifactFile.getParentFile(), "configs_zip");
final File destinationDirectory = new File(outputDirectory, artifactFile.getParent().substring(localRepositoryBasedirLength) + "/configs_zip");
destinationDirectory.mkdirs();
destinationDirectory.setLastModified(artifactFile.lastModified());
for (String from : sourceDirectory.list()) {
// build.xml - published flex sdk contains unneeded ant file
if (from.charAt(0) != '.' && !from.equals("build.xml")) {
File fromFile = new File(sourceDirectory, from);
File toFile = new File(destinationDirectory, from);
if (fromFile.isDirectory()) {
toFile.mkdir();
copyDirectory(fromFile, toFile);
}
else {
Utils.copyFile(fromFile, toFile);
}
}
}
Utils.copyFile(new File(sourceDirectory, "macFonts.ser"), new File(outputDirectory, "fonts.ser"));
}
else if (artifact.getArtifactId().equals("playerglobal") || artifact.getArtifactId().equals("airglobal")) {
Utils.copyFile(artifactFile, new File(outputDirectory, artifactFile.getParent().substring(localRepositoryBasedirLength) + "/" + artifact.getArtifactId() + ".swc"));
}
else if (artifact.getType().equals("rb.swc")) {
if (artifact.getClassifier() == null) {
Utils.copyFile(artifactFile, new File(outputDirectory, artifactFile.getPath().substring(localRepositoryBasedirLength, artifactFile.getPath().length() - ".rb.swc".length()) + "-en_US.rb.swc"));
}
}
else if (!artifact.getType().equals("pom")) {
final String pomFilename = localPath.substring(0, localPath.length() - artifact.getType().length()) + "pom";
File pom = new File(localRepositoryFile, pomFilename);
if (pom.exists()) {
Utils.copyFile(pom, new File(outputDirectory, pomFilename));
}
}
}
catch (IOException e) {
throw new MojoExecutionException("Cannot copy", e);
}
}
}
private boolean copyArtifact(File artifactFile, String localPath) throws IOException {
File outFile = new File(outputDirectory, localPath);
if (outFile.lastModified() == artifactFile.lastModified()) {
return true;
}
//noinspection ResultOfMethodCallIgnored
outFile.getParentFile().mkdirs();
Utils.copyFile(artifactFile, outFile);
return false;
}
private static void copyDirectory(File sourceDirectory, File destinationDirectory) throws IOException {
//noinspection ResultOfMethodCallIgnored
destinationDirectory.setLastModified(sourceDirectory.lastModified());
for (String from : sourceDirectory.list()) {
if (from.charAt(0) != '.') {
final File fromFile = new File(sourceDirectory, from);
final File toFile = new File(destinationDirectory, from);
if (fromFile.isDirectory()) {
//noinspection ResultOfMethodCallIgnored
toFile.mkdir();
copyDirectory(fromFile, toFile);
}
else {
Utils.copyFile(fromFile, toFile);
}
}
}
}
}