package org.jboss.windup.rules.apps.java.archives.listener;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.logging.Logger;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.jboss.forge.addon.dependencies.Coordinate;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.graph.model.ArchiveModel;
import org.jboss.windup.graph.model.WindupConfigurationModel;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.graph.service.ArchiveService;
import org.jboss.windup.graph.service.GraphService;
import org.jboss.windup.graph.service.WindupConfigurationService;
import org.jboss.windup.rules.apps.java.archives.identify.ArchiveIdentificationService;
import org.jboss.windup.rules.apps.java.archives.model.ArchiveCoordinateModel;
import org.jboss.windup.rules.apps.java.archives.model.IdentifiedArchiveModel;
import org.jboss.windup.rules.apps.java.archives.model.IgnoredArchiveModel;
import org.jboss.windup.util.exception.WindupException;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
import org.jboss.windup.util.Logging;
/**
* {@link GraphChangedListener} responsible for identifying {@link ArchiveModel} instances when they are added to the graph.
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
* @author <a href="mailto:ozizka@redhat.com">Ondrej Zizka</a>
*/
public final class ArchiveIdentificationGraphChangedListener implements GraphChangedListener
{
private static final Logger LOG = Logging.get(ArchiveIdentificationGraphChangedListener.class);
private final ArchiveIdentificationService identifier;
private GraphContext context;
private ArchiveService archiveService;
public ArchiveIdentificationGraphChangedListener setGraphContext(GraphContext context)
{
this.context = context;
this.archiveService = new ArchiveService(context);
return this;
}
public ArchiveIdentificationGraphChangedListener(GraphContext context, ArchiveIdentificationService identifier)
{
this.identifier = identifier;
this.setGraphContext(context);
}
@Override
public void vertexPropertyChanged(Vertex vertex, String key, Object oldValue, Object setValue)
{
if (ArchiveModel.ARCHIVE_NAME.equals(key))
{
ArchiveModel archive = archiveService.frame(vertex);
setArchiveHashes(archive);
Coordinate coordinate = identifier.getCoordinate(archive.getSHA1Hash());
if (coordinate != null)
{
// If this is not a jar file, do not ignore it
if (!StringUtils.endsWithIgnoreCase(archive.getFileName(), ".jar"))
return;
// Never ignore the input application
WindupConfigurationModel configurationModel = WindupConfigurationService.getConfigurationModel(this.context);
for (FileModel inputPath : configurationModel.getInputPaths())
{
if (inputPath.equals(archive))
return;
}
IdentifiedArchiveModel identifiedArchive = GraphService.addTypeToModel(context, archive, IdentifiedArchiveModel.class);
ArchiveCoordinateModel coordinateModel = new GraphService<>(context, ArchiveCoordinateModel.class).create();
coordinateModel.setArtifactId(coordinate.getArtifactId());
coordinateModel.setGroupId(coordinate.getGroupId());
coordinateModel.setVersion(coordinate.getVersion());
coordinateModel.setClassifier(coordinate.getClassifier());
identifiedArchive.setCoordinate(coordinateModel);
LOG.info("Identified archive: [" + archive.getFilePath() + "] as [" + coordinate + "] will not be unzipped or analyzed.");
IgnoredArchiveModel ignoredArchive = GraphService.addTypeToModel(context, archive, IgnoredArchiveModel.class);
ignoredArchive.setIgnoredRegex("Known open-source library");
}
else
{
LOG.info("Archive not identified: " + archive.getFilePath() + " SHA1: " + archive.getSHA1Hash());
}
}
}
private void setArchiveHashes(ArchiveModel payload)
{
if (payload.getMD5Hash() == null)
{
try (InputStream is = payload.asInputStream())
{
String md5 = DigestUtils.md5Hex(is);
payload.setMD5Hash(md5);
}
catch (IOException e)
{
throw new WindupException("Failed to read archive file at: " + payload.getFilePath() + " due to: " + e.getMessage(), e);
}
}
if (payload.getSHA1Hash() == null)
{
try (InputStream is = payload.asInputStream())
{
String sha1 = DigestUtils.sha1Hex(is);
payload.setSHA1Hash(sha1);
}
catch (IOException e)
{
throw new WindupException("Failed to read archive file at: " + payload.getFilePath() + " due to: " + e.getMessage(), e);
}
}
}
@Override
public void vertexPropertyRemoved(Vertex vertex, String key, Object removedValue)
{
}
@Override
public void vertexAdded(Vertex vertex)
{
}
@Override
public void vertexRemoved(Vertex vertex, Map<String, Object> props)
{
}
@Override
public void edgeAdded(Edge edge)
{
}
@Override
public void edgePropertyChanged(Edge edge, String key, Object oldValue, Object setValue)
{
}
@Override
public void edgePropertyRemoved(Edge edge, String key, Object removedValue)
{
}
@Override
public void edgeRemoved(Edge edge, Map<String, Object> props)
{
}
}