package org.jboss.windup.reporting.rules;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.apache.commons.lang3.ObjectUtils;
import org.jboss.forge.furnace.Furnace;
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.GraphOperation;
import org.jboss.windup.config.phase.PostReportGenerationPhase;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.graph.model.WindupVertexFrame;
import org.jboss.windup.graph.service.GraphService;
import org.jboss.windup.graph.service.ProjectService;
import org.jboss.windup.reporting.model.ApplicationReportModel;
import org.jboss.windup.reporting.model.TemplateType;
import org.jboss.windup.reporting.model.WindupVertexListModel;
import org.jboss.windup.reporting.service.ApplicationReportService;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationBuilder;
import org.ocpsoft.rewrite.context.EvaluationContext;
/**
* This renders an application index page listing all applications analyzed by the current execution of windup.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
@RuleMetadata(
phase = PostReportGenerationPhase.class,
before = AttachApplicationReportsToIndexRuleProvider.class,
haltOnException = true
)
public class CreateApplicationListReportRuleProvider extends AbstractRuleProvider
{
public static final String APPLICATION_LIST_REPORT = "Application List";
private static final String OUTPUT_FILENAME = "../index.html";
public static final String TEMPLATE_PATH = "/reports/templates/application_list.ftl";
@Inject
private Furnace furnace;
// @formatter:off
@Override
public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext)
{
return ConfigurationBuilder.begin()
.addRule()
.perform(new GraphOperation() {
@Override
public void perform(GraphRewrite event, EvaluationContext context) {
createIndexReport(event.getGraphContext());
}
});
}
// @formatter:on
private void createIndexReport(GraphContext context)
{
ApplicationReportService applicationReportService = new ApplicationReportService(context);
ApplicationReportModel report = applicationReportService.create();
report.setReportPriority(1);
report.setReportIconClass("glyphicon glyphicon-home");
report.setReportName(APPLICATION_LIST_REPORT);
report.setTemplatePath(TEMPLATE_PATH);
report.setTemplateType(TemplateType.FREEMARKER);
report.setDisplayInApplicationReportIndex(false);
report.setReportFilename(OUTPUT_FILENAME);
GraphService<WindupVertexListModel> listService = new GraphService<>(context, WindupVertexListModel.class);
WindupVertexListModel<ApplicationReportModel> appsListVertex = listService.create();
Map<String, WindupVertexFrame> relatedData = new HashMap<>();
final Iterable<ApplicationReportModel> apps = applicationReportService.findAll();
List<ApplicationReportModel> appsList = new ArrayList();
for (ApplicationReportModel applicationReportModel : apps)
{
if (applicationReportModel.isMainApplicationReport() != null && applicationReportModel.isMainApplicationReport())
{
appsList.add(applicationReportModel);
if (ProjectService.SHARED_LIBS_UNIQUE_ID.equals(applicationReportModel.getProjectModel().getUniqueID()))
relatedData.put("sharedLibsApplicationReport", applicationReportModel); // Used as kind of boolean in the template.
}
}
relatedData.put("applications", appsListVertex);
// Our current model doesn't keep the list order, but once I wrote, I'm leaving the sorting here for when it does.
Collections.sort(appsList, new AppRootFileNameComparator());
for (ApplicationReportModel applicationReportModel : appsList)
appsListVertex.addItem(applicationReportModel);
report.setRelatedResource(relatedData);
}
private static class AppRootFileNameComparator implements Comparator<ApplicationReportModel>
{
public int compare(ApplicationReportModel o1, ApplicationReportModel o2)
{
// If the info is missing, put that to the end. This may be the case of virtual apps.
if (null == o1.getProjectModel() || null == o1.getProjectModel().getRootFileModel() || null == o1.getProjectModel().getRootFileModel().getFileName() )
return 1;
if (null == o2.getProjectModel() || null == o2.getProjectModel().getRootFileModel() || null == o2.getProjectModel().getRootFileModel().getFileName() )
return -1;
// On error resume next.
try {
return ObjectUtils.compare(
o1.getProjectModel().getRootFileModel().getFileName(),
o2.getProjectModel().getRootFileModel().getFileName());
}
catch (Throwable ex)
{
return 0;
}
}
}
}