package org.jboss.windup.rules.apps.java.scan.provider;
import java.util.ArrayList;
import java.util.List;
import com.tinkerpop.blueprints.Direction;
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.Iteration;
import org.jboss.windup.config.operation.IterationProgress;
import org.jboss.windup.config.operation.iteration.AbstractIterationFilter;
import org.jboss.windup.config.operation.iteration.AbstractIterationOperation;
import org.jboss.windup.config.phase.DiscoverProjectStructurePhase;
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.ProjectModel;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.graph.service.ProjectService;
import org.jboss.windup.util.ZipUtil;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationBuilder;
import org.ocpsoft.rewrite.context.EvaluationContext;
/**
* Finds Archives that were not classified as Maven archives/projects, and adds some generic project information for
* them.
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
@RuleMetadata(phase = DiscoverProjectStructurePhase.class, after = DiscoverMavenProjectsRuleProvider.class)
public class DiscoverNonMavenArchiveProjectsRuleProvider extends AbstractRuleProvider
{
@Override
public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext)
{
// @formatter:off
return ConfigurationBuilder.begin()
.addRule()
.when(
Query.fromType(ArchiveModel.class)
).perform(
Iteration.over(ArchiveModel.class)
.when(new AbstractIterationFilter<ArchiveModel>(){
@Override
public boolean evaluate(GraphRewrite event, EvaluationContext context, ArchiveModel payload)
{
return !(payload instanceof DuplicateArchiveModel) && payload.getProjectModel() == null;
}
@Override
public String toString()
{
return "ProjectModel == null";
}
})
.perform(
new AbstractIterationOperation<ArchiveModel>()
{
@Override
public void perform(GraphRewrite event, EvaluationContext context, ArchiveModel payload)
{
List<ArchiveModel> hierarchy = new ArrayList<>();
ArchiveModel parentArchive = payload;
while(parentArchive != null)
{
hierarchy.add(parentArchive);
// break once we have added a parent with a project model
if (parentArchive.getProjectModel() != null)
{
break;
}
parentArchive = parentArchive.getParentArchive();
}
ProjectModel childProjectModel = null;
ProjectService projectModelService = new ProjectService(event.getGraphContext());
for (ArchiveModel archiveModel : hierarchy)
{
ProjectModel projectModel = archiveModel.getProjectModel();
// create the project if we don't already have one
if (projectModel == null)
{
projectModel = projectModelService.create();
projectModel.setName(archiveModel.getArchiveName());
projectModel.setRootFileModel(archiveModel);
projectModel.setDescription("Unidentified Archive");
if(ZipUtil.endsWithZipExtension(archiveModel.getArchiveName()))
{
for (String extension : ZipUtil.getZipExtensions())
{
if(archiveModel.getArchiveName().endsWith(extension))
projectModel.setProjectType(extension);
}
}
projectModel.addFileModel(archiveModel);
// Attach the project to all files within the archive
for (FileModel f : archiveModel.getAllFiles())
{
// don't add archive models, as those really are separate projects...
if (f instanceof ArchiveModel)
continue;
// also, don't set the project model if one is already set
// this uses the edge directly to improve performance
if (f.asVertex().getVertices(Direction.IN, ProjectModel.PROJECT_MODEL_TO_FILE).iterator().hasNext())
continue;
// only set it if it has not already been set
projectModel.addFileModel(f);
}
}
if(childProjectModel != null)
{
childProjectModel.setParentProject(projectModel);
}
childProjectModel = projectModel;
}
}
public String toString() {
return "ScanAsNonMavenProject";
}
}
.and(IterationProgress.monitoring("Checking for non-Maven archive", 1))
)
.endIteration()
);
// @formatter:on
}
}