package org.jboss.windup.rules.apps.java.scan.provider;
import org.jboss.windup.config.AbstractRuleProvider;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.loader.RuleLoaderContext;
import org.jboss.windup.config.metadata.RuleMetadata;
import org.jboss.windup.config.operation.Commit;
import org.jboss.windup.config.operation.IterationProgress;
import org.jboss.windup.config.operation.iteration.AbstractIterationOperation;
import org.jboss.windup.config.phase.ArchiveExtractionPhase;
import org.jboss.windup.config.query.Query;
import org.jboss.windup.graph.model.ArchiveModel;
import org.jboss.windup.graph.model.DuplicateArchiveModel;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.graph.service.Service;
import org.jboss.windup.rules.apps.java.archives.model.IgnoredArchiveModel;
import org.jboss.windup.rules.apps.java.scan.operation.UnzipArchiveToOutputFolder;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationBuilder;
import org.ocpsoft.rewrite.context.EvaluationContext;
/**
* Unzip archives from the input application.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
@RuleMetadata(phase = ArchiveExtractionPhase.class)
public class UnzipArchivesToOutputRuleProvider extends AbstractRuleProvider
{
@Override
public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext)
{
return ConfigurationBuilder.begin()
.addRule()
.when(Query.fromType(ArchiveModel.class).excludingType(IgnoredArchiveModel.class))
.perform(
UnzipArchiveToOutputFolder.unzip(),
IterationProgress.monitoring("Unzipped archive", 1),
Commit.every(1)
)
.addRule()
.when(Query.fromType(ArchiveModel.class).excludingType(DuplicateArchiveModel.class))
.perform(new DuplicateArchiveOperation());
}
/**
* Processes {@link ArchiveModel}s and makes sure that any that have duplicates are removed from the tree and
* replaced with a {@link DuplicateArchiveModel} that links to them.
*/
private class DuplicateArchiveOperation extends AbstractIterationOperation<ArchiveModel>
{
@Override
public void perform(GraphRewrite event, EvaluationContext context, ArchiveModel canonicalArchive)
{
// Skip if there were no duplicates
if (!canonicalArchive.getDuplicateArchives().iterator().hasNext())
{
return;
}
/*
* Indicates that the duplicates were all within the same application. If this is found to be the case,
* then don't move it to the shared project as that is only intended for projects that are shared between
* multiple applications.
*/
boolean exclusiveToApplication = true;
/*
* This is the root of the current archive hierarchy.
*/
ArchiveModel rootArchive = canonicalArchive.getRootArchiveModel();
for (DuplicateArchiveModel duplicateArchiveModel : canonicalArchive.getDuplicateArchives())
{
if (!rootArchive.containsArchive(duplicateArchiveModel))
{
exclusiveToApplication = false;
break;
}
}
/*
* We do not remove it from its present location if it is exclusive to a single application (or a single
* "root archive").
*/
if (exclusiveToApplication)
return;
// Get the canonical archive and remove it from its current position in the tree
ArchiveModel canonicalParentArchive = canonicalArchive.getParentArchive();
FileModel canonicalArchiveParentFile = canonicalArchive.getParentFile();
canonicalArchive.setParentFile(null);
canonicalArchive.setParentArchive(null);
/*
* Create the duplicate archive, link it to the canonical archive and
* place it in the tree.
*
* Essentially this will replace the canonical Archive vertex with a vertex that points back to the
* single canonical source for this archive.
*/
Service<DuplicateArchiveModel> duplicateArchiveService = event.getGraphContext().service(DuplicateArchiveModel.class);
DuplicateArchiveModel duplicateArchive = duplicateArchiveService.create();
duplicateArchive.setCanonicalArchive(canonicalArchive);
duplicateArchive.setSHA1Hash(canonicalArchive.getSHA1Hash());
duplicateArchive.setFilePath(canonicalArchive.getFilePath());
duplicateArchive.setArchiveName(canonicalArchive.getArchiveName());
duplicateArchive.setFileName(canonicalArchive.getFileName());
duplicateArchive.setParentArchive(canonicalParentArchive);
duplicateArchive.setParentFile(canonicalArchiveParentFile);
}
}
}