diff --git a/config/api/src/main/java/org/jboss/windup/config/IteratingRuleProvider.java b/config/api/src/main/java/org/jboss/windup/config/IteratingRuleProvider.java new file mode 100644 index 0000000000..9864cb4a6c --- /dev/null +++ b/config/api/src/main/java/org/jboss/windup/config/IteratingRuleProvider.java @@ -0,0 +1,46 @@ +package org.jboss.windup.config; + +import org.jboss.windup.config.operation.ruleelement.AbstractIterationOperation; +import org.jboss.windup.graph.GraphContext; +import org.jboss.windup.graph.model.WindupVertexFrame; +import org.ocpsoft.rewrite.config.ConditionBuilder; +import org.ocpsoft.rewrite.config.Configuration; +import org.ocpsoft.rewrite.config.ConfigurationBuilder; +import org.ocpsoft.rewrite.context.EvaluationContext; + +/** + * This provides a simplified way to extend {@link WindupRuleProvider} for cases where the rule simply needs to provide + * some query, and wants to execute a function over each resulting row. + * + * @author jsightler + */ +public abstract class IteratingRuleProvider extends WindupRuleProvider +{ + /** + * Gets the condition for the {@link Configuration}'s "when" clause. + */ + public abstract ConditionBuilder getCondition(); + + /** + * Perform this function for each {@link WindupVertexFrame} returned by the "when" clause. + */ + public abstract void perform(GraphRewrite event, EvaluationContext context, PAYLOADTYPE payload); + + private class IterationOperation extends AbstractIterationOperation + { + @Override + public void perform(GraphRewrite event, EvaluationContext context, PAYLOADTYPE payload) + { + IteratingRuleProvider.this.perform(event, context, payload); + } + } + + @Override + public final Configuration getConfiguration(GraphContext context) + { + return ConfigurationBuilder.begin() + .addRule() + .when(getCondition()) + .perform(new IterationOperation()); + } +} diff --git a/graph/api/src/main/java/org/jboss/windup/graph/GraphTypeManager.java b/graph/api/src/main/java/org/jboss/windup/graph/GraphTypeManager.java index 2246668cb4..4f186a3954 100644 --- a/graph/api/src/main/java/org/jboss/windup/graph/GraphTypeManager.java +++ b/graph/api/src/main/java/org/jboss/windup/graph/GraphTypeManager.java @@ -76,7 +76,15 @@ public void addTypeToElement(Class kind, Element element) String typeFieldName = typeHoldingTypeField.getAnnotation(TypeField.class).value(); String typeValue = typeValueAnnotation.value(); - // Store the type value in a delimited list. + for (TitanProperty existingTypes : v.getProperties(typeFieldName)) + { + if (existingTypes.getValue().toString().equals(typeValue)) + { + // this is already in the list, so just exit now + return; + } + } + v.addProperty(typeFieldName, typeValue); addSuperclassType(kind, element); } diff --git a/rules/app/java/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/HashArchivesRuleProvider.java b/rules/app/java/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/HashArchivesRuleProvider.java new file mode 100644 index 0000000000..f5d200263e --- /dev/null +++ b/rules/app/java/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/HashArchivesRuleProvider.java @@ -0,0 +1,69 @@ +package org.jboss.windup.rules.apps.java.scan.provider; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.apache.commons.codec.digest.DigestUtils; +import org.jboss.windup.config.GraphRewrite; +import org.jboss.windup.config.IteratingRuleProvider; +import org.jboss.windup.config.RulePhase; +import org.jboss.windup.config.WindupRuleProvider; +import org.jboss.windup.config.query.Query; +import org.jboss.windup.graph.model.ArchiveModel; +import org.jboss.windup.util.exception.WindupException; +import org.ocpsoft.rewrite.config.ConditionBuilder; +import org.ocpsoft.rewrite.context.EvaluationContext; + +/** + * This RuleProvider gets the MD5 and SHA1 hash for each {@link ArchiveModel} in the graph. + * + * @author jsightler + * + */ +public class HashArchivesRuleProvider extends IteratingRuleProvider +{ + + @Override + protected ConditionBuilder getCondition() + { + return Query.find(ArchiveModel.class); + } + + @Override + public RulePhase getPhase() + { + return RulePhase.DISCOVERY; + } + + @Override + public List> getExecuteAfter() + { + return asClassList(UnzipArchivesToOutputRuleProvider.class); + } + + @Override + protected void perform(GraphRewrite event, EvaluationContext context, ArchiveModel payload) + { + 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); + } + 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); + } + } +} diff --git a/tests/core/src/test/java/org/jboss/windup/tests/application/WindupArchitectureSmallBinaryModeTest.java b/tests/core/src/test/java/org/jboss/windup/tests/application/WindupArchitectureSmallBinaryModeTest.java index 06e07d2c65..a4e53751a7 100644 --- a/tests/core/src/test/java/org/jboss/windup/tests/application/WindupArchitectureSmallBinaryModeTest.java +++ b/tests/core/src/test/java/org/jboss/windup/tests/application/WindupArchitectureSmallBinaryModeTest.java @@ -13,6 +13,9 @@ import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.windup.engine.WindupProcessor; import org.jboss.windup.graph.GraphContext; +import org.jboss.windup.graph.dao.ArchiveService; +import org.jboss.windup.graph.model.ArchiveModel; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,5 +59,20 @@ public static ForgeArchive getDeployment() public void testRunWindupTiny() throws Exception { super.runTest(processor, graphContext, "../../test-files/Windup1x-javaee-example-tiny.war", false); + validateArchiveHashes(); + } + + private void validateArchiveHashes() throws Exception + { + ArchiveService archiveService = new ArchiveService(graphContext); + int numberFound = 0; + for (ArchiveModel model : archiveService.findAll()) + { + numberFound++; + + Assert.assertEquals("c60bb0c51623a915cb4a9a90ba9ba70e", model.getMD5Hash()); + Assert.assertEquals("1a1888023eff8629a9e55f023c8ecf63f69fad03", model.getSHA1Hash()); + } + Assert.assertEquals(1, numberFound); } }