diff --git a/cobigen/cobigen-core/pom.xml b/cobigen/cobigen-core/pom.xml index 29013ff348..79b6731e34 100644 --- a/cobigen/cobigen-core/pom.xml +++ b/cobigen/cobigen-core/pom.xml @@ -4,7 +4,7 @@ 4.0.0 cobigen-core CobiGen - 2.1.0 + 2.1.1 jar @@ -30,7 +30,7 @@ org.freemarker freemarker - 2.3.20 + 2.3.23 diff --git a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/CobiGen.java b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/CobiGen.java index 570285b65d..3ca1bed8a1 100644 --- a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/CobiGen.java +++ b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/CobiGen.java @@ -70,7 +70,7 @@ public class CobiGen { /** * Current version of the generation, needed for configuration file validation */ - public static final String CURRENT_VERSION = "2.1.0"; + public static final String CURRENT_VERSION = "2.1.1"; /** * The {@link ContextConfiguration} for this instance @@ -425,10 +425,9 @@ private List convertIncrements(List increments, Trigger templates.add(new TemplateTo(template.getName(), template.getUnresolvedDestinationPath(), template.getMergeStrategy(), trigger, triggerInterpreter)); } - incrementTos - .add(new IncrementTo(increment.getName(), increment.getDescription(), trigger.getId(), - templates, convertIncrements(increment.getDependentIncrements(), trigger, - triggerInterpreter))); + incrementTos.add(new IncrementTo(increment.getName(), increment.getDescription(), + trigger.getId(), templates, convertIncrements(increment.getDependentIncrements(), trigger, + triggerInterpreter))); } return incrementTos; } diff --git a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/reader/TemplatesConfigurationReader.java b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/reader/TemplatesConfigurationReader.java index 46443da539..fa4c3bfa53 100644 --- a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/reader/TemplatesConfigurationReader.java +++ b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/reader/TemplatesConfigurationReader.java @@ -320,7 +320,9 @@ private void scanTemplates(Path currentDirectory, String currentPath, TemplateSc + templateNameWithoutExtension; if (observedTemplateNames.contains(templateName)) { throw new InvalidConfigurationException( - "TemplateScan has detected two files with the same file name and thus with the same " + "TemplateScan has detected two files with the same file name (" + + next.toString() + + ") and thus with the same " + "template name. Continuing would result in an indeterministic behavior.\n" + "For now, multiple files with the same name are not supported to be automatically " + "configured with templateScans."); diff --git a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/resolver/PathExpressionResolver.java b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/resolver/PathExpressionResolver.java index db66a5edf9..c96579727b 100644 --- a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/resolver/PathExpressionResolver.java +++ b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/config/resolver/PathExpressionResolver.java @@ -50,7 +50,12 @@ private void adaptVariables() { HashMap newVariables = new HashMap<>(); for (String var : variables.keySet()) { - newVariables.put(var, variables.get(var).replaceAll("\\.", "/")); + String value = variables.get(var); + if (value != null) { + newVariables.put(var, value.replaceAll("\\.", "/")); + } else { + newVariables.put(var, value); + } } variables = newVariables; } @@ -91,26 +96,34 @@ public String evaluateExpressions(String in) throws UnknownContextVariableExcept Matcher m = p.matcher(in); StringBuffer out = new StringBuffer(); while (m.find()) { - if (variables.get(m.group(1)) == null) { + if (!variables.containsKey(m.group(1))) { throw new UnknownContextVariableException(m.group(1)); } - if (m.group(2) != null) { - boolean first = true; - String modifiedValue = variables.get(m.group(1)); - for (String modifier : m.group(2).split("(\\?|#)")) { - if (first) { - first = false; - continue; // ignore first as always empty due to beginning '?' + + if (variables.get(m.group(1)) != null) { + if (m.group(2) != null) { + boolean first = true; + String modifiedValue = variables.get(m.group(1)); + for (String modifier : m.group(2).split("(\\?|#)")) { + if (first) { + first = false; + continue; // ignore first as always empty due to beginning '?' + } + modifiedValue = applyStringModifier(modifier, modifiedValue); } - modifiedValue = applyStringModifier(modifier, modifiedValue); + m.appendReplacement(out, modifiedValue); + } else { + m.appendReplacement(out, variables.get(m.group(1))); } - m.appendReplacement(out, modifiedValue); } else { - m.appendReplacement(out, variables.get(m.group(1))); + m.appendReplacement(out, ""); } } m.appendTail(out); - return out.toString(); + + // Cleanup empty path segements + String rawPath = out.toString(); + return rawPath.replaceAll("/+", "/"); } /** diff --git a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/model/JaxenXPathSupportNodeModel.java b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/model/JaxenXPathSupportNodeModel.java index 450efbd972..fce6c7fc79 100644 --- a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/model/JaxenXPathSupportNodeModel.java +++ b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/model/JaxenXPathSupportNodeModel.java @@ -40,7 +40,7 @@ public JaxenXPathSupportNodeModel(Node node) { try { useJaxenXPathSupport(); } catch (Exception e) { - LOG.error("{}", "Exception if the Jaxen classes are not present", e); + LOG.error("Exception if the Jaxen classes are not present", e); } } diff --git a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/validator/InputValidator.java b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/validator/InputValidator.java index ba822eefcc..e553ca4883 100644 --- a/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/validator/InputValidator.java +++ b/cobigen/cobigen-core/src/main/java/com/capgemini/cobigen/validator/InputValidator.java @@ -75,7 +75,7 @@ public static void validateInputsUnequalNull(Object... objects) { } /** - * Validates a {@link Map} of resolved variables for null keys and values + * Validates a {@link Map} of resolved variables for null keys * @param resolvedVariables * to be validated * @author mbrunnli (10.04.2014) @@ -90,10 +90,6 @@ public static void validateResolvedVariables(Map resolvedVariabl throw new PluginProcessingException( "A Plug-In must not add entries with null keys into the resolved variables Map"); } - if (var.getValue() == null) { - throw new PluginProcessingException( - "A Plug-In must not add entries with null values into the resolved variables Map"); - } } } diff --git a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/TemplateScanTest.java b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/TemplateScanTest.java index 01db9b1c8f..544712b4aa 100644 --- a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/TemplateScanTest.java +++ b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/TemplateScanTest.java @@ -12,6 +12,7 @@ import static org.mockito.internal.matchers.Any.ANY; import java.io.File; +import java.util.HashMap; import java.util.List; import org.apache.commons.lang3.SystemUtils; @@ -28,7 +29,6 @@ import com.capgemini.cobigen.extension.to.TemplateTo; import com.capgemini.cobigen.pluginmanager.PluginRegistry; import com.capgemini.cobigen.systemtest.common.AbstractApiTest; -import com.google.common.collect.ImmutableMap; /** * Test suite for template-scan related system tests @@ -62,10 +62,13 @@ public void testCorrectDestinationResoution() throws Exception { generationRootFolder.getAbsolutePath()); List templates = target.getMatchingTemplates(input); Assert.assertNotNull(templates); - Assert.assertEquals(1, templates.size()); + + TemplateTo targetTemplate = + getTemplateById(templates, "prefix_${variables.component#cap_first#replace('1','ONE')}.java"); + Assert.assertNotNull(targetTemplate); // Execution - target.generate(input, templates.get(0), false); + target.generate(input, targetTemplate, false); // Validation Assert.assertTrue(new File(generationRootFolder.getAbsolutePath() + SystemUtils.FILE_SEPARATOR @@ -95,6 +98,76 @@ public void testScanTemplatesFromArchivFile() throws Exception { assertThat(templates.size(), equalTo(7)); } + /** + * Tests the correct destination resolution for resources obtained by template-scans in the case of an + * empty path element + * @throws Exception + * test fails + * @author mbrunnli (20.12.2015) + */ + @Test + public void testCorrectDestinationResoution_emptyPathElement() throws Exception { + Object input = createTestInputAndConfigureMock(); + + File generationRootFolder = tmpFolder.newFolder("generationRootFolder"); + // Useful to see generates if necessary, comment the generationRootFolder above then + // File generationRootFolder = new File(testFileRootPath + "generates"); + + // pre-processing + File templatesFolder = new File(testFileRootPath); + CobiGen target = new CobiGen(templatesFolder.toURI()); + target.setContextSetting(ContextSetting.GenerationTargetRootPath, + generationRootFolder.getAbsolutePath()); + List templates = target.getMatchingTemplates(input); + Assert.assertNotNull(templates); + + TemplateTo targetTemplate = getTemplateById(templates, "prefix_Test.java"); + Assert.assertNotNull(targetTemplate); + + // Execution + target.generate(input, targetTemplate, false); + + // Validation + Assert.assertTrue(new File(generationRootFolder.getAbsolutePath() + SystemUtils.FILE_SEPARATOR + + "src" + SystemUtils.FILE_SEPARATOR + "main" + SystemUtils.FILE_SEPARATOR + "java" + + SystemUtils.FILE_SEPARATOR + "base" + SystemUtils.FILE_SEPARATOR + "Test.java").exists()); + } + + /** + * Tests the correct destination resolution for resources obtained by template-scans in the case of + * multiple empty path elements + * @throws Exception + * test fails + * @author mbrunnli (20.12.2015) + */ + @Test + public void testCorrectDestinationResoution_emptyPathElements() throws Exception { + Object input = createTestInputAndConfigureMock(); + + File generationRootFolder = tmpFolder.newFolder("generationRootFolder"); + // Useful to see generates if necessary, comment the generationRootFolder above then + // File generationRootFolder = new File(testFileRootPath + "generates"); + + // pre-processing + File templatesFolder = new File(testFileRootPath); + CobiGen target = new CobiGen(templatesFolder.toURI()); + target.setContextSetting(ContextSetting.GenerationTargetRootPath, + generationRootFolder.getAbsolutePath()); + List templates = target.getMatchingTemplates(input); + Assert.assertNotNull(templates); + + TemplateTo targetTemplate = getTemplateById(templates, "prefix_MultiEmpty.java"); + Assert.assertNotNull(targetTemplate); + + // Execution + target.generate(input, targetTemplate, false); + + // Validation + Assert.assertTrue(new File(generationRootFolder.getAbsolutePath() + SystemUtils.FILE_SEPARATOR + + "src" + SystemUtils.FILE_SEPARATOR + "main" + SystemUtils.FILE_SEPARATOR + "java" + + SystemUtils.FILE_SEPARATOR + "base" + SystemUtils.FILE_SEPARATOR + "MultiEmpty.java").exists()); + } + /** * Creates simple to debug test data, which includes only one object as input. A * {@link ITriggerInterpreter TriggerInterpreter} will be mocked with all necessary supplier classes to @@ -140,6 +213,11 @@ public String toString() { .thenReturn(true); // Simulate variable resolving of any plug-in + HashMap variables = new HashMap<>(3); + variables.put("rootPackage", "com.capgemini"); + variables.put("component", "comp1"); + variables.put("detail", null); + when( matcher.resolveVariables( argThat(new MatcherToMatcher(equalTo("fqn"), ANY, sameInstance(input))), @@ -147,9 +225,7 @@ public String toString() { // new VariableAssignmentToMatcher(equalTo("regex"), equalTo("rootPackage"), equalTo("1")), new VariableAssignmentToMatcher(equalTo("regex"), equalTo("entityName"), equalTo("3")))))) - .thenReturn( - ImmutableMap. builder().put("rootPackage", "com.capgemini") - .put("component", "comp1").build()); + .thenReturn(variables); PluginRegistry.registerTriggerInterpreter(triggerInterpreter); diff --git a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/common/AbstractApiTest.java b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/common/AbstractApiTest.java index 2d3bfe1c84..09ef2a81ae 100644 --- a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/common/AbstractApiTest.java +++ b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/systemtest/common/AbstractApiTest.java @@ -1,8 +1,12 @@ package com.capgemini.cobigen.systemtest.common; +import java.util.Collection; + import org.junit.Rule; import org.junit.rules.TemporaryFolder; +import com.capgemini.cobigen.extension.to.TemplateTo; + /** * * @author mbrunnli (07.12.2014) @@ -20,4 +24,22 @@ public class AbstractApiTest { */ @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); + + /** + * Search for template by id + * @param templates + * list of templates + * @param id + * to search for + * @return the first template, with the given id or null if not found + * @author mbrunnli (Dec 20, 2015) + */ + public TemplateTo getTemplateById(Collection templates, String id) { + for (TemplateTo template : templates) { + if (template.getId().equals(id)) { + return template; + } + } + return null; + } } diff --git a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/unittest/config/reader/TemplatesConfigurationReaderTest.java b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/unittest/config/reader/TemplatesConfigurationReaderTest.java index 00b288426d..2eae8fa15a 100644 --- a/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/unittest/config/reader/TemplatesConfigurationReaderTest.java +++ b/cobigen/cobigen-core/src/test/java/com/capgemini/cobigen/unittest/config/reader/TemplatesConfigurationReaderTest.java @@ -1,6 +1,8 @@ package com.capgemini.cobigen.unittest.config.reader; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import java.io.File; @@ -372,4 +374,23 @@ public void testIncrementComposition_combiningAllPossibleReferences() { "prefix_scanned", "scanned", "prefix_scanned2"); } + + /** + * Test for Issue 167. Tests if the + * exception message from {@link #testErrorOnDuplicateScannedIds()} contains the name of the file causing + * the exception + * + * @author sholzer (Dec 18, 2015) + */ + @Test + public void testExceptionMessageForDuplicateTemplateNames() { + String message = ""; + try { + testErrorOnDuplicateScannedIds(); + fail("An Exception should have been thrown"); + } catch (Exception e) { + message = e.getMessage(); + } + assertFalse(message.indexOf("Bar") == -1); + } } diff --git a/cobigen/cobigen-core/src/test/resources/testdata/systemtest/TemplateScanTest/test/templates/base/${variables.detail}/${variables.detail}/MultiEmpty.java.ftl b/cobigen/cobigen-core/src/test/resources/testdata/systemtest/TemplateScanTest/test/templates/base/${variables.detail}/${variables.detail}/MultiEmpty.java.ftl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cobigen/cobigen-core/src/test/resources/testdata/systemtest/TemplateScanTest/test/templates/base/${variables.detail}/Test.java.ftl b/cobigen/cobigen-core/src/test/resources/testdata/systemtest/TemplateScanTest/test/templates/base/${variables.detail}/Test.java.ftl new file mode 100644 index 0000000000..e69de29bb2