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