package org.jboss.windup.rules.apps.java.scan.provider;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.metadata.RuleMetadata;
import org.jboss.windup.config.phase.ArchiveMetadataExtractionPhase;
import org.jboss.windup.config.query.Query;
import org.jboss.windup.config.ruleprovider.IteratingRuleProvider;
import org.jboss.windup.graph.model.ArchiveModel;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.graph.service.ArchiveService;
import org.jboss.windup.reporting.model.TechnologyTagLevel;
import org.jboss.windup.reporting.service.TechnologyTagService;
import org.jboss.windup.rules.apps.java.model.JarManifestModel;
import org.jboss.windup.rules.apps.java.service.JarManifestService;
import org.jboss.windup.util.Logging;
import org.ocpsoft.rewrite.config.ConditionBuilder;
import org.ocpsoft.rewrite.context.EvaluationContext;
/**
* Discovers MANIFEST.MF files within archives.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
@RuleMetadata(phase = ArchiveMetadataExtractionPhase.class, perform = "DiscoverManifestFilesInArchives")
public class DiscoverArchiveManifestFilesRuleProvider extends IteratingRuleProvider<ArchiveModel>
{
private static final Logger LOG = Logging.get(DiscoverArchiveManifestFilesRuleProvider.class);
private static final String TECH_TAG = "Manifest";
private static final TechnologyTagLevel TECH_TAG_LEVEL = TechnologyTagLevel.INFORMATIONAL;
@Override
public ConditionBuilder when()
{
return Query.fromType(ArchiveModel.class);
}
@Override
public void perform(GraphRewrite event, EvaluationContext context, ArchiveModel payload)
{
ArchiveService archiveService = new ArchiveService(event.getGraphContext());
FileModel manifestFile = archiveService.getChildFile(payload, "META-INF/MANIFEST.MF");
if (manifestFile == null)
{
// no manifest found, skip this one
return;
}
TechnologyTagService technologyTagService = new TechnologyTagService(event.getGraphContext());
JarManifestService jarManifestService = new JarManifestService(event.getGraphContext());
technologyTagService.addTagToFileModel(manifestFile, TECH_TAG, TECH_TAG_LEVEL);
JarManifestModel jarManifest = jarManifestService.addTypeToModel(manifestFile);
jarManifest.setArchive(payload);
jarManifest.setGenerateSourceReport(true);
try (InputStream is = manifestFile.asInputStream())
{
Manifest manifest = new Manifest(is);
if (manifest.getMainAttributes().isEmpty())
{
// no manifest found, skip this one
return;
}
for (Object key : manifest.getMainAttributes().keySet())
{
String property = StringUtils.trim(key.toString());
String propertyValue = StringUtils.trim(manifest.getMainAttributes().get(key).toString());
jarManifest.asVertex().setProperty(property, propertyValue);
}
if (StringUtils.isBlank(jarManifest.getName())) {
// if the name is still blank, try to get it from the first entry in the file list.
// A few apache projects do it this way
for (String entry : manifest.getEntries().keySet()) {
for (Object key : manifest.getAttributes(entry).keySet())
{
String property = StringUtils.trim(key.toString());
String propertyValue = StringUtils.trim(manifest.getAttributes(entry).get(key).toString());
if (StringUtils.isBlank((String)jarManifest.asVertex().getProperty(property)))
jarManifest.asVertex().setProperty(property, propertyValue);
}
if (!StringUtils.isBlank(jarManifest.getName()))
break;
}
}
}
catch (IOException e)
{
LOG.log(Level.WARNING, "Exception reading manifest from file: " + manifestFile.getFilePath(), e);
}
}
}