diff --git a/cobigen/cobigen-xmlplugin/pom.xml b/cobigen/cobigen-xmlplugin/pom.xml index ade2033b87..15734f09bb 100644 --- a/cobigen/cobigen-xmlplugin/pom.xml +++ b/cobigen/cobigen-xmlplugin/pom.xml @@ -2,10 +2,9 @@ 4.0.0 - com.capgemini cobigen-xmlplugin CobiGen - XML Plug-In - 2.1.0 + 3.0.0-SNAPSHOT jar @@ -18,121 +17,13 @@ com.capgemini cobigen-core - 1.2.0 + 3.0.0-SNAPSHOT - - ch.elca.el4j.modules - module-core - 3.1 - - - javax.inject - inject - - - org.slf4j - slf4j-log4j12 - - - log4j - log4j - - - org.springframework - * - - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - - - net.java.dev.which4j - which4j - - - org.aspectj - aspectjmatcher - - - org.apache.bcel - bcel - - - cglib - cglib-nodep - - - - - - - org.slf4j - log4j-over-slf4j - 1.7.7 - - - org.slf4j - jcl-over-slf4j - 1.7.7 - - - - - ch.elca.el4j.modules - module-xml_merge-common - 3.1 - - - javax.inject - inject - - - jdom - jdom - - - - - - - javax.inject - javax.inject - 1 - - - - - org.jdom - jdom - 1.1.3 + lexeme + com.github.maybeec + 1.0.0 - - - - - - el4jReleaseRepositoryExternal - External release repository of the EL4J project - http://public-el4.elca-services.ch/el4j/maven2repository - - false - - - true - - - diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlPluginActivator.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlPluginActivator.java index 882eab6084..2b10b80083 100644 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlPluginActivator.java +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlPluginActivator.java @@ -2,39 +2,38 @@ import java.util.List; -import com.capgemini.cobigen.extension.IGeneratorPluginActivator; -import com.capgemini.cobigen.extension.IMerger; -import com.capgemini.cobigen.extension.ITriggerInterpreter; -import com.capgemini.cobigen.xmlplugin.merger.XmlMerger; -import com.capgemini.cobigen.xmlplugin.merger.action.CompleteMergeAction; -import com.capgemini.cobigen.xmlplugin.merger.action.OverrideMergeAction; +import com.capgemini.cobigen.api.extension.GeneratorPluginActivator; +import com.capgemini.cobigen.api.extension.Merger; +import com.capgemini.cobigen.api.extension.TriggerInterpreter; +import com.capgemini.cobigen.impl.PluginRegistry; +import com.capgemini.cobigen.xmlplugin.merger.delegates.MergeType; +import com.capgemini.cobigen.xmlplugin.merger.delegates.XmlMergerDelegate; import com.google.common.collect.Lists; /** - * - * @author mbrunnli (06.04.2014) + * Plug-in activator to be registered at CobiGen's {@link PluginRegistry}. */ -public class XmlPluginActivator implements IGeneratorPluginActivator { +public class XmlPluginActivator implements GeneratorPluginActivator { /** - * {@inheritDoc} - * @author mbrunnli (06.04.2014) + * defining the default location of the merge schemas */ + static private String defaultMergeSchemaLocation = "src/main/resources/mergeSchemas"; + @Override - public List bindMerger() { - List merger = Lists.newLinkedList(); - merger.add(new XmlMerger("xmlmerge", new CompleteMergeAction())); - merger.add(new XmlMerger("xmlmerge_override", new OverrideMergeAction())); + public List bindMerger() { + List merger = Lists.newLinkedList(); + + merger.add(new XmlMergerDelegate(defaultMergeSchemaLocation, MergeType.BASEOVERWRITE)); + merger.add(new XmlMergerDelegate(defaultMergeSchemaLocation, MergeType.BASEATTACHOROVERWRITE)); + merger.add(new XmlMergerDelegate(defaultMergeSchemaLocation, MergeType.PATCHOVERWRITE)); + merger.add(new XmlMergerDelegate(defaultMergeSchemaLocation, MergeType.PATCHATTACHOROVERWRITE)); return merger; } - /** - * {@inheritDoc} - * @author mbrunnli (08.04.2014) - */ @Override - public List bindTriggerInterpreter() { - return Lists. newArrayList(new XmlTriggerInterpreter("xml")); + public List bindTriggerInterpreter() { + return Lists. newArrayList(new XmlTriggerInterpreter("xml")); } } diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlTriggerInterpreter.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlTriggerInterpreter.java index 3a72b34b28..e79ca6954f 100644 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlTriggerInterpreter.java +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/XmlTriggerInterpreter.java @@ -1,20 +1,18 @@ package com.capgemini.cobigen.xmlplugin; -import com.capgemini.cobigen.extension.IInputReader; -import com.capgemini.cobigen.extension.IMatcher; -import com.capgemini.cobigen.extension.ITriggerInterpreter; +import com.capgemini.cobigen.api.extension.InputReader; +import com.capgemini.cobigen.api.extension.MatcherInterpreter; +import com.capgemini.cobigen.api.extension.TriggerInterpreter; import com.capgemini.cobigen.xmlplugin.inputreader.XmlInputReader; import com.capgemini.cobigen.xmlplugin.matcher.XmlMatcher; /** - * {@link ITriggerInterpreter} implementation of a Xml Interpreter - * - * @author fkreis (18.11.2014) + * {@link TriggerInterpreter} implementation of a Xml Interpreter */ -public class XmlTriggerInterpreter implements ITriggerInterpreter { +public class XmlTriggerInterpreter implements TriggerInterpreter { /** - * {@link ITriggerInterpreter} type to be registered + * {@link TriggerInterpreter} type to be registered */ public String type; @@ -30,30 +28,18 @@ public XmlTriggerInterpreter(String type) { this.type = type; } - /** - * {@inheritDoc} - * @author fkreis (18.11.2014) - */ @Override public String getType() { return type; } - /** - * {@inheritDoc} - * @author fkreis (18.11.2014) - */ @Override - public IInputReader getInputReader() { + public InputReader getInputReader() { return new XmlInputReader(); } - /** - * {@inheritDoc} - * @author fkreis (18.11.2014) - */ @Override - public IMatcher getMatcher() { + public MatcherInterpreter getMatcher() { return new XmlMatcher(); } diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/inputreader/XmlInputReader.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/inputreader/XmlInputReader.java index 17cab52dc6..a24baaf6d4 100644 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/inputreader/XmlInputReader.java +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/inputreader/XmlInputReader.java @@ -12,18 +12,13 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import com.capgemini.cobigen.extension.IInputReader; +import com.capgemini.cobigen.api.extension.InputReader; /** - * - * @author fkreis (10.11.2014) + * {@link InputReader} for XML files. */ -public class XmlInputReader implements IInputReader { +public class XmlInputReader implements InputReader { - /** - * {@inheritDoc} - * @author fkreis (10.11.2014) - */ @Override public boolean isValidInput(Object input) { if (input instanceof Document) { @@ -31,13 +26,8 @@ public boolean isValidInput(Object input) { } else { return false; } - } - /** - * {@inheritDoc} - * @author fkreis (10.11.2014) - */ @Override public Map createModel(Object input) { if (isValidInput(input)) { @@ -49,15 +39,12 @@ public Map createModel(Object input) { } else { return null; } - } /** - * {@inheritDoc}
- *
+ * {@inheritDoc}.
* Since the {@link XmlInputReader} does not support multiple input objects it always returns * false. - * @author fkreis (10.11.2014) */ @Override public boolean combinesMultipleInputObjects(Object input) { @@ -66,35 +53,38 @@ public boolean combinesMultipleInputObjects(Object input) { /** * {@inheritDoc}
- *
* Since the {@link XmlInputReader} does not support multiple input objects it always returns an empty * {@link List}. - * @author fkreis (10.11.2014) */ @Override public List getInputObjects(Object input, Charset inputCharset) { - List emptyList = new LinkedList<>(); - return emptyList; + return new LinkedList<>(); + } + + /** + * {@inheritDoc}
+ * Since the {@link XmlInputReader} does not support multiple input objects it always returns an empty + * {@link List}. + */ + @Override + public List getInputObjectsRecursively(Object input, Charset inputCharset) { + return new LinkedList<>(); } /** * {@inheritDoc}
- *
* Since the {@link XmlInputReader} does not provide any template methods it always returns an empty * {@link Map}. - * @author fkreis (10.11.2014) */ @Override public Map getTemplateMethods(Object input) { - Map emptyMap = new HashMap<>(); - return emptyMap; + return new HashMap<>(); } /** * @param input * the element the model should derived from * @return derived sub model - * @author fkreis (17.11.2014) */ private Map deriveSubModel(Element input) { // prepare result object diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/matcher/XmlMatcher.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/matcher/XmlMatcher.java index 1ce1805eba..337caa6bb0 100644 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/matcher/XmlMatcher.java +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/matcher/XmlMatcher.java @@ -8,17 +8,16 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import com.capgemini.cobigen.exceptions.InvalidConfigurationException; -import com.capgemini.cobigen.extension.IMatcher; -import com.capgemini.cobigen.extension.to.MatcherTo; -import com.capgemini.cobigen.extension.to.VariableAssignmentTo; +import com.capgemini.cobigen.api.exception.InvalidConfigurationException; +import com.capgemini.cobigen.api.extension.MatcherInterpreter; +import com.capgemini.cobigen.api.to.MatcherTo; +import com.capgemini.cobigen.api.to.VariableAssignmentTo; import com.google.common.collect.Maps; /** - * - * @author fkreis (18.11.2014) + * {@link MatcherInterpreter} for XML matcher configurations. */ -public class XmlMatcher implements IMatcher { +public class XmlMatcher implements MatcherInterpreter { /** * Assigning logger to XmlClassMatcher @@ -47,10 +46,6 @@ private enum VariableType { REGEX } - /** - * {@inheritDoc} - * @author fkreis (18.11.2014) - */ @Override public boolean matches(MatcherTo matcher) { try { @@ -71,10 +66,6 @@ public boolean matches(MatcherTo matcher) { return false; } - /** - * {@inheritDoc} - * @author fkreis (18.11.2014) - */ @Override public Map resolveVariables(MatcherTo matcher, List variableAssignments) throws InvalidConfigurationException { @@ -91,7 +82,7 @@ public Map resolveVariables(MatcherTo matcher, resolvedVariables.put(va.getVarName(), va.getValue()); break; case REGEX: - // TODO + // TODO #64 } } return resolvedVariables; diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/BasicXmlMerge.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/BasicXmlMerge.java deleted file mode 100644 index 258f8ae665..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/BasicXmlMerge.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * EL4J, the Extension Library for the J2EE, adds incremental enhancements to - * the spring framework, http://el4j.sf.net - * Copyright (C) 2006 by ELCA Informatique SA, Av. de la Harpe 22-24, - * 1000 Lausanne, Switzerland, http://www.elca.ch - * - * EL4J is published under the GNU Lesser General Public License (LGPL) - * Version 2.1. See http://www.gnu.org/licenses/ - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * For alternative licensing, please contact info@elca.ch - */ -package com.capgemini.cobigen.xmlplugin.merger; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.jdom.DefaultJDOMFactory; -import org.jdom.DocType; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.UncheckedJDOMFactory; -import org.jdom.input.DOMBuilder; -import org.jdom.input.SAXBuilder; -import org.jdom.output.DOMOutputter; -import org.jdom.output.Format; -import org.jdom.output.XMLOutputter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.EntityResolver; - -import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException; -import ch.elca.el4j.services.xmlmerge.DocumentException; -import ch.elca.el4j.services.xmlmerge.Mapper; -import ch.elca.el4j.services.xmlmerge.Matcher; -import ch.elca.el4j.services.xmlmerge.MergeAction; -import ch.elca.el4j.services.xmlmerge.ParseException; -import ch.elca.el4j.services.xmlmerge.XmlMerge; -import ch.elca.el4j.services.xmlmerge.XmlMergeContext; -import ch.elca.el4j.services.xmlmerge.factory.StaticOperationFactory; -import ch.elca.el4j.services.xmlmerge.matcher.TagMatcher; -import ch.elca.el4j.services.xmlmerge.merge.DefaultXmlMerge; - -import com.capgemini.cobigen.util.SystemUtil; -import com.capgemini.cobigen.xmlplugin.merger.action.BasicMergeAction; - -/** - * This class is basically the same as the {@link DefaultXmlMerge} class. The only difference is, that - * {@link Document}s are build with a {@link DOMBuilder} that is using a {@link UncheckedJDOMFactory}.
- * See {@link DefaultXmlMerge} - */ -public class BasicXmlMerge implements XmlMerge { - - /** - * Root merge action. - */ - private MergeAction m_rootMergeAction; - - /** - * Root matcher. - */ - private Matcher m_rootMatcher = new TagMatcher(); - - /** - * Assigning logger to BasicXmlMerge - */ - private static final Logger LOG = LoggerFactory.getLogger(BasicXmlMerge.class); - - /** - * Creates a new {@link BasicXmlMerge} instance, which is able to merge two xml documents. - * @param action - * {@link BasicMergeAction} to be performed while merging document elements - * @param mapper - * transforms elements to influence the merging mechanism - * @param matcher - * to determine if two elements match to be merged - */ - public BasicXmlMerge(BasicMergeAction action, Mapper mapper, Matcher matcher) { - m_rootMergeAction = action; - m_rootMergeAction.setActionFactory(new StaticOperationFactory(action)); - m_rootMergeAction.setMapperFactory(new StaticOperationFactory(mapper)); - m_rootMergeAction.setMatcherFactory(new StaticOperationFactory(matcher)); - } - - /** - * {@inheritDoc} - */ - @Override - public void setRootMapper(Mapper rootMapper) { - } - - /** - * {@inheritDoc} - */ - @Override - public void setRootMergeAction(MergeAction rootMergeAction) { - m_rootMergeAction = rootMergeAction; - } - - /** - * {@inheritDoc} - */ - @Override - public String merge(String[] sources) throws AbstractXmlMergeException { - - InputStream[] inputStreams = new InputStream[sources.length]; - - for (int i = 0; i < sources.length; i++) { - inputStreams[i] = new ByteArrayInputStream(sources[i].getBytes()); - } - - InputStream merged = merge(inputStreams); - - ByteArrayOutputStream result = new ByteArrayOutputStream(); - - try { - byte[] buffer = new byte[1024]; - int len; - while ((len = merged.read(buffer)) != -1) { - result.write(buffer, 0, len); - } - } catch (IOException e) { - // should never happen - LOG.error("Could not read merged inputstream.", e); - throw new RuntimeException(e); - } - - return result.toString(); - } - - /** - * {@inheritDoc} - */ - @Override - public org.w3c.dom.Document merge(org.w3c.dom.Document[] sources) throws AbstractXmlMergeException { - DOMBuilder domb = new DOMBuilder(); - domb.setFactory(new DefaultJDOMFactory()); - - // to save all XML files as JDOM objects - Document[] docs = new Document[sources.length]; - - for (int i = 0; i < sources.length; i++) { - // ask JDOM to parse the given inputStream - docs[i] = domb.build(sources[i]); - } - - Document result = doMerge(docs); - - DOMOutputter outputter = new DOMOutputter(); - outputter.setForceNamespaceAware(true); - - try { - return outputter.output(result); - } catch (JDOMException e) { - LOG.error("Could not convert JDOM Document to w3c DOM Document.", e); - throw new DocumentException(result, e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public InputStream merge(InputStream[] sources) throws AbstractXmlMergeException { - SAXBuilder sxb = new SAXBuilder(); - - EntityResolver entityResolver = XmlMergeContext.getEntityResolver(); - if (entityResolver != null) { - sxb.setEntityResolver(entityResolver); - } - - // to save all XML files as JDOM objects - Document[] docs = new Document[sources.length]; - - for (int i = 0; i < sources.length; i++) { - try { - // ask JDOM to parse the given inputStream - docs[i] = sxb.build(sources[i]); - } catch (JDOMException e) { - LOG.error("Could not parse the inputstream into a JDOM Document", e); - throw new ParseException(e); - } catch (IOException e) { - LOG.error("Could not read one of the inputstreams to be merged.", e); - throw new ParseException(e); - } - } - - Document result = doMerge(docs); - - Format prettyFormatter = Format.getPrettyFormat(); - // Use system line separator to avoid problems - // with carriage return under linux - prettyFormatter.setLineSeparator(SystemUtil.LINE_SEPARATOR); - XMLOutputter sortie = new XMLOutputter(prettyFormatter); - - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - try { - sortie.output(result, buffer); - } catch (IOException e) { - LOG.error("Error while writing the JDOM Document to an outputstream.", e); - throw new DocumentException(result, e); - } - - return new ByteArrayInputStream(buffer.toByteArray()); - } - - /** - * Performs the actual merge. - * - * @param docs - * The documents to merge - * @return The merged result document - * @throws AbstractXmlMergeException - * If an error occurred during the merge - */ - private Document doMerge(Document[] docs) throws AbstractXmlMergeException { - Document temporary = docs[0]; - - for (int i = 1; i < docs.length; i++) { - - if (!m_rootMatcher.matches(temporary.getRootElement(), docs[i].getRootElement())) { - throw new IllegalArgumentException("Root elements do not match."); - } - - Document output = new Document(); - if (docs[0].getDocType() != null) { - output.setDocType((DocType) docs[0].getDocType().clone()); - } - output.setRootElement(new Element("root")); - - m_rootMergeAction.perform(temporary.getRootElement(), docs[i].getRootElement(), - output.getRootElement()); - - Element root = (Element) output.getRootElement().getChildren().get(0); - root.detach(); - - temporary.setRootElement(root); - } - - return temporary; - } - -} - -// Checkstyle: MagicNumber on diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlDocumentMatcher.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlDocumentMatcher.java deleted file mode 100644 index 80513e9f3e..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlDocumentMatcher.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.capgemini.cobigen.xmlplugin.merger; - -import org.jdom.Attribute; -import org.jdom.Element; - -import ch.elca.el4j.services.xmlmerge.Matcher; - -/** - * Used by an {@link ch.elca.el4j.services.xmlmerge.XmlMerge} instance to evaluate whether two elements match, - * by calling the Matcher's {@link XmlDocumentMatcher#matches} method. - * @author trippl (12.03.2013) - * - */ -public class XmlDocumentMatcher implements Matcher { - - /** - * Evaluates whether the two given elements match, by doing the following: - *

- * - Compares value of "id" attribute if the elements have one.
- * - Compares value of "resource" attribute if the elements qualified name is "import".
- * - Compares value of "name" attribute if the elements qualified name is "query", "property" or "define". - *
- * - Compares value of "on" attribute if the elements qualified name is "transition".
- * - Compares value of the elements Text if the elements share the same parent element ( - * {@link #parentElementsMatch(Element, Element)})
- * - All other elements are compared by their qualified name (not very accurate). - * @author trippl (12.03.2013) - */ - @Override - public boolean matches(Element originalElement, Element patchElement) { - if (originalElement.getQualifiedName().equals(patchElement.getQualifiedName())) { - - if (originalElement.getAttribute("id") != null && patchElement.getAttribute("id") != null) { - return originalElement.getAttributeValue("id").equals(patchElement.getAttributeValue("id")); - } - - if (originalElement.getQualifiedName().equals("import")) { - if (originalElement.getAttribute("resource") != null - && patchElement.getAttribute("resource") != null) { // should not be null - return originalElement.getAttributeValue("resource").equals( - patchElement.getAttributeValue("resource")); - } - } - - if (originalElement.getName().equals("query") || originalElement.getName().equals("property") - || originalElement.getQualifiedName().equals("define")) { - if (originalElement.getAttribute("name") != null && patchElement.getAttribute("name") != null) { // should - // not - // be - // null - return originalElement.getAttributeValue("name").equals( - patchElement.getAttributeValue("name")); - } - } - - if (originalElement.getName().equals("transition")) { - if (originalElement.getAttribute("on") != null && patchElement.getAttribute("on") != null) { // should - // not - // be - // null - return originalElement.getAttributeValue("on").equals( - patchElement.getAttributeValue("on")); - } - } - - if (originalElement.getName().equals("outputLabel") - || originalElement.getName().equals("message")) { - if (originalElement.getAttribute("for") != null && patchElement.getAttribute("for") != null) { // should - // not - // be - // null - if (originalElement.getAttributeValue("for") - .equals(patchElement.getAttributeValue("for"))) { - if (originalElement.getAttribute("value") != null - && patchElement.getAttribute("value") != null) { - return originalElement.getAttributeValue("value").equals( - patchElement.getAttributeValue("value")); - } else { - return originalElement.getAttributeValue("for").equals( - patchElement.getAttributeValue("for")); - } - } - return false; - } - } - - if (parentElementsMatch(originalElement, patchElement)) { - return originalElement.getText().equals(patchElement.getText()); - } - - else { - return true; - } - } - return false; - } - - /** - * Compares the values of the {@link Element}s "id" {@link Attribute}, if they have one. - * @param element1 - * to check the id from - * @param element2 - * to check the id from - * @return true, if the ids match, false, if they don't match or don't exist - * @author trippl (27.03.2013) - */ - private boolean idsMatch(Element element1, Element element2) { - if (element1.getAttribute("id") != null && element2.getAttribute("id") != null) { - return element1.getAttributeValue("id").equals(element2.getAttributeValue("id")); - } - return false; - } - - /** - * Validates, if the parent {@link Element}s of the given {@link Element}s match, by calling - * {@link #idsMatch(Element, Element)}. If they don't match, this function is recursively called until - * {@link Element#getParentElement()} returns null. - * @param originalParent - * original parent element - * @param patchParent - * generated patch element - * @return true if any parents match
- * false if none of them match or {@link Element#getParentElement()} return - * null - * @author trippl (27.03.2013) - */ - private boolean parentElementsMatch(Element originalParent, Element patchParent) { - Element element1Parent = originalParent.getParentElement(); - Element element2Parent = patchParent.getParentElement(); - if (element1Parent == null || element2Parent == null) { - return false; - } else { - if (idsMatch(element1Parent, element2Parent)) { - return true; - } - return parentElementsMatch(element1Parent, element2Parent); - } - } - -} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlMerger.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlMerger.java deleted file mode 100644 index ca2e7ad543..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/XmlMerger.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.capgemini.cobigen.xmlplugin.merger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException; -import ch.elca.el4j.services.xmlmerge.XmlMerge; -import ch.elca.el4j.services.xmlmerge.mapper.IdentityMapper; - -import com.capgemini.cobigen.exceptions.MergeException; -import com.capgemini.cobigen.extension.IMerger; -import com.capgemini.cobigen.xmlplugin.merger.action.BasicMergeAction; - -/** - * The {@link XmlMerger} combines all functionality for merging XML structures - * - * @author mbrunnli (12.03.2013) - */ -public class XmlMerger implements IMerger { - - /** - * Assigning logger to XmlMerger - */ - private static final Logger LOG = LoggerFactory.getLogger(XmlMerger.class); - - /** - * Merger type to be registered - */ - private String type; - - /** - * {@link XmlMerge} instance - */ - private XmlMerge xmlMerge; - - /** - * Creates a new {@link XmlMerger} with the given {@link BasicMergeAction} to be performed when merging - * xml elements - * @param type - * to be registered - * @param action - * to be performed when merging two xml elements - * @author mbrunnli (08.04.2014) - */ - public XmlMerger(String type, BasicMergeAction action) { - xmlMerge = new BasicXmlMerge(action, new IdentityMapper(), new XmlDocumentMatcher()); - this.type = type; - } - - /** - * {@inheritDoc} - * @author mbrunnli (08.04.2014) - */ - @Override - public String getType() { - return type; - } - - /** - * {@inheritDoc} - * @author trippl (05.03.2013) - */ - @Override - public String merge(File base, String patch, String targetCharset) throws IOException, MergeException { - DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); - - DocumentBuilder docBuilder; - String source = "base file"; // just for better error handling - try { - docBuilderFactory.setNamespaceAware(true); - docBuilderFactory.setValidating(false); - docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", - false); - docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", - false); - docBuilder = docBuilderFactory.newDocumentBuilder(); - - Document baseDoc = - docBuilder.parse(new InputSource(new InputStreamReader(new FileInputStream(base), - targetCharset))); - source = "patch"; // base doc parsed correctly, next should be patch - - Document patchDoc = docBuilder.parse(new InputSource(new StringReader(patch))); - - // removeRedundantComments(baseDoc, patchDoc); <-- BasicXmlMerge combined with - // CompletMergeAction takes care of that - - Document[] toMerge = { baseDoc, patchDoc }; - Document resultXml = xmlMerge.merge(toMerge); - - return prettyPrintDocument(resultXml); - } catch (ParserConfigurationException e) { - // ignore - developer fault - LOG.error("This might be a bug.", e); - } catch (AbstractXmlMergeException e) { - LOG.error("An exception occured while merging the file '{}'", base.getAbsolutePath(), e); - throw new MergeException("An exception occured while merging the file " + base.getAbsolutePath() - + ":\n" + e.getMessage()); - } catch (TransformerException e) { - LOG.error("An exception occured while merging the file '{}'", base.getAbsolutePath(), e); - throw new MergeException("An exception occured while printing the merged file " - + base.getAbsolutePath() + ":\n" + e.getMessage()); - } catch (SAXException e) { - LOG.error("An exception occured while parsing the patch.", e); - if (e.getMessage().contains( - "The processing instruction target matching \"[xX][mM][lL]\" is not allowed")) { - throw new MergeException("An exception occured while parsing the " + source + ".\n" - + "Please check whether the first line of the " + source + "(" + base.getName() + ") " - + " starts with the xml declaration like:\n" - + "\nOtherwise you will get this error."); - } - throw new MergeException("An exception occured while parsing the patch:\n" + e.getMessage()); - } - return null; - } - - /** - * Prints the given document to the specified destination. - * @return The merged document contents - * @param doc - * Document to be print - * @throws TransformerException - * if an unrecoverable error occurs during the course of the transformation. - * @author trippl (05.03.2013) - */ - private String printDocument(Document doc) throws TransformerException { - - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); - if (doc.getDoctype() != null) { - transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); - transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId()); - } - DOMSource source = new DOMSource(doc); - StringWriter writer = new StringWriter(); - StreamResult result = new StreamResult(writer); - transformer.transform(source, result); - return writer.toString(); - } - - /** - * Calls {@link #removeEmptyLines(Document)}, {@link #addEmptyLinesBetweenRootChildNodes(Document)} and - * {@link #printDocument(Document)}. In that order. - * @param doc - * Document to be print - * @return The merged document contents - * @throws TransformerException - * If an unrecoverable error occurs during the course of the transformation. - * @author trippl (06.03.2013) - */ - private String prettyPrintDocument(Document doc) throws TransformerException { - removeEmptyLines(doc); - addEmptyLinesBetweenRootChildNodes(doc); - return printDocument(doc); - } - - /** - * Removes comments within the patch document if they also appear in the base document. Note: only removes - * the first appearance within the patch document. - * @param base - * The base document - * @param patch - * The patch document - * @author trippl (06.03.2013) - */ - @SuppressWarnings("unused") - private void removeRedundantComments(Document base, Document patch) { - - XPathFactory xpathFactory = XPathFactory.newInstance(); - // XPath to find all comment nodes. - try { - XPathExpression xpathExp = xpathFactory.newXPath().compile("//comment()"); - - NodeList origianlCommentNodes = (NodeList) xpathExp.evaluate(base, XPathConstants.NODESET); - NodeList patchCommentNodes = (NodeList) xpathExp.evaluate(patch, XPathConstants.NODESET); - - for (int i = 0; i < patchCommentNodes.getLength(); i++) { - Node commentNode = patchCommentNodes.item(i); - if (containsComment(origianlCommentNodes, commentNode)) { - commentNode.getParentNode().removeChild(commentNode); - } - } - } catch (XPathExpressionException e) { - // ignore - developer fault - LOG.error("This might be a bug.", e); - } - } - - /** - * Checks if the given {@link NodeList} contains the specified {@link Node}. This is done by comparing - * their node values. - * @param comments - * {@link NodeList} of comments to be checked - * @param comment - * {@link Node} comment to be searched - * @return true if the comment appears in the NodeList, else false. - * @author trippl (06.03.2013) - */ - private boolean containsComment(NodeList comments, Node comment) { - for (int i = 0; i < comments.getLength(); i++) { - if (comments.item(i).getNodeValue().equals(comment.getNodeValue())) { - return true; - } - } - return false; - } - - /** - * Removes empty lines within the given {@link Document}. - * @param doc - * {@link Document} to be checked for empty lines - * @author trippl (06.03.2013) - */ - private void removeEmptyLines(Document doc) { - - doc.normalize(); - XPathFactory xpathFactory = XPathFactory.newInstance(); - try { - // XPath to find empty text nodes. - XPathExpression xpathExp = xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']"); - - NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET); - - // Remove each empty text node from document. - for (int i = 0; i < emptyTextNodes.getLength(); i++) { - Node emptyTextNode = emptyTextNodes.item(i); - emptyTextNode.getParentNode().removeChild(emptyTextNode); - } - } catch (XPathExpressionException e) { - // ignore - developer fault - LOG.error("This might be a bug.", e); - } - } - - /** - * Adds a empty line before every child node of the {@link Document}s root element node and a empty line - * after the root node's last child. If the Document's root node is null, nothing is done. - * @param doc - * {@link Document} to be formatted - * @author trippl (07.03.2013) - */ - private void addEmptyLinesBetweenRootChildNodes(Document doc) { - - Node root = doc.getDocumentElement(); - if (root == null) { - return; - } - - List nodes = copyNodeList(root.getChildNodes()); - - for (Node node : nodes) { - root.insertBefore(doc.createTextNode("\n\n\t"), node); - } - - root.appendChild(doc.createTextNode("\n\n")); - } - - /** - * Adds the {@link NodeList}'s content into a {@link List} - * @param nodes - * {@link Node}s to be copied - * @return A {@link List} containing the {@link NodeList}'s {@link Node}s - * @author trippl (03.04.2013) - */ - private List copyNodeList(NodeList nodes) { - List copy = new ArrayList<>(); - - for (int i = 0; i < nodes.getLength(); i++) { - copy.add(nodes.item(i)); - } - return copy; - } -} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/BasicMergeAction.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/BasicMergeAction.java deleted file mode 100644 index ee6b3cb23d..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/BasicMergeAction.java +++ /dev/null @@ -1,256 +0,0 @@ -package com.capgemini.cobigen.xmlplugin.merger.action; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.jdom.Attribute; -import org.jdom.Comment; -import org.jdom.Content; -import org.jdom.Element; -import org.jdom.Namespace; -import org.jdom.Text; - -import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException; -import ch.elca.el4j.services.xmlmerge.Action; -import ch.elca.el4j.services.xmlmerge.Mapper; -import ch.elca.el4j.services.xmlmerge.Matcher; -import ch.elca.el4j.services.xmlmerge.MergeAction; -import ch.elca.el4j.services.xmlmerge.action.AbstractMergeAction; -import ch.elca.el4j.services.xmlmerge.action.OrderedMergeAction; - -import com.google.common.collect.Maps; - -/** - * This class provides the functionality of the {@link OrderedMergeAction} class to it's subclasses.
- * In Order to work the subclasses have to override the following functions:
- * {@link #mergeNamespaces(Element, Element, Element)}
- * {@link #mergeAttributes(Element, Element, Element)}
- * {@link #mergeContent(Element, Element, Element)} - * - * @author trippl (05.04.2013) - */ -public abstract class BasicMergeAction extends AbstractMergeAction { - - /** - * {@inheritDoc} - */ - @Override - public void perform(Element originalElement, Element patchElement, Element outputParentElement) - throws AbstractXmlMergeException { - - Mapper mapper = (Mapper) m_mapperFactory.getOperation(originalElement, patchElement); - - if (originalElement == null) { - outputParentElement.addContent(mapper.map(patchElement)); - } else if (patchElement == null) { - outputParentElement.addContent((Content) originalElement.clone()); - } else { - - Element workingElement = - new Element(originalElement.getName(), originalElement.getNamespacePrefix(), - originalElement.getNamespaceURI()); - - mergeNamespaces(workingElement, originalElement, patchElement); - mergeAttributes(workingElement, originalElement, patchElement); - mergeContent(workingElement, originalElement, patchElement); - - outputParentElement.addContent(workingElement); - } - - } - - /** - * Merges the {@link Namespace}s of the originalElement and the patchElement and adds them to the - * outElement. - * - * @param outElement - * the {@link Element} the namespaces are added to - * @param originalElement - * the original {@link Element} - * @param patchElement - * the patch {@link Element} - * @author trippl (05.04.2013) - */ - protected abstract void mergeNamespaces(Element outElement, Element originalElement, Element patchElement); - - /** - * Merges the {@link Attribute}s of the originalElement and the patchElement and adds them to the - * outElement. - * - * @param outElement - * the {@link Element} the namespaces are added to - * @param originalElement - * the original {@link Element} - * @param patchElement - * the patch {@link Element} - * @author trippl (05.04.2013) - */ - protected abstract void mergeAttributes(Element outElement, Element originalElement, Element patchElement); - - /** - * Checks if the given {@link List} contains the specified {@link Content}. - * - * @param content - * {@link Content} to be searched - * @param contents - * {@link List} of {@link Content} to be compared - * @return The {@link Content} in the {@link List}, if found, else null - * @throws AbstractXmlMergeException - * - If an error occurs during the match-operation creation - * @author trippl (03.04.2013) - */ - protected Content findContent(Content content, List contents) throws AbstractXmlMergeException { - - for (Content c : contents) { - if (content.getClass().equals(c.getClass())) { - if (content instanceof Comment) { - if (content.getValue().equals(c.getValue())) { - return c; - } - } else if (content instanceof Text) { - return c; - } else if (content instanceof Element) { - Element element = (Element) content; - Element e = (Element) c; - if (((Matcher) m_matcherFactory.getOperation(element, e)).matches(element, e)) { - return c; - } - } - } - } - return null; - } - - /** - * Merges the {@link Content}s of the originalElement and the patchElement and adds them to the - * outElement. - * - * @param outElement - * the {@link Element} the contents are added to - * @param originalElement - * the original {@link Element} - * @param patchElement - * the patch {@link Element} - * @throws AbstractXmlMergeException - * if an error occurred during the merge - * @author trippl (28.03.2013) - */ - protected abstract void mergeContent(Element outElement, Element originalElement, Element patchElement) - throws AbstractXmlMergeException; - - /** - * Applies the action which performs the merge between two source elements. - * - * @param workingParent - * Output parent element - * @param originalElement - * Original element - * @param patchElement - * Patch element - * @throws AbstractXmlMergeException - * if an error occurred during the merge - */ - protected void applyAction(Element workingParent, Element originalElement, Element patchElement) - throws AbstractXmlMergeException { - - Action action = (Action) m_actionFactory.getOperation(originalElement, patchElement); - Mapper mapper = (Mapper) m_mapperFactory.getOperation(originalElement, patchElement); - - if (action instanceof BasicMergeAction) { - MergeAction mergeAction = (MergeAction) action; - mergeAction.setActionFactory(m_actionFactory); - mergeAction.setMapperFactory(m_mapperFactory); - mergeAction.setMatcherFactory(m_matcherFactory); - } - - action.perform(originalElement, mapper.map(patchElement), workingParent); - } - - /** - * Adds attributes from in element to out element. - * - * @param out - * out element - * @param in - * in element - */ - protected void addAttributes(Element out, Element in) { - - LinkedHashMap allAttributes = new LinkedHashMap<>(); - - List outAttributes = new ArrayList<>(out.getAttributes()); - List inAttributes = new ArrayList<>(in.getAttributes()); - - for (int i = 0; i < inAttributes.size(); i++) { - Attribute attr = inAttributes.get(i); - allAttributes.put(attr.getQualifiedName(), (Attribute) attr.clone()); - } - - for (Attribute attr : outAttributes) { - if (!attr.getName().equals("schemaLocation") - || allAttributes.get(attr.getQualifiedName()) == null) { - allAttributes.put(attr.getQualifiedName(), (Attribute) attr.clone()); - } else { - String schemaLocationOrig = allAttributes.get(attr.getQualifiedName()).getValue().trim(); - String schemaLocationPatch = attr.getValue().trim(); - - Map schemaLocations = Maps.newLinkedHashMap(); - schemaLocations.putAll(extractSchemaLocationDefinitions(schemaLocationOrig)); - schemaLocations.putAll(extractSchemaLocationDefinitions(schemaLocationPatch)); - - Attribute newAttr = (Attribute) attr.clone(); - newAttr.setValue(schemaLocationsToString(schemaLocations)); - allAttributes.put(attr.getQualifiedName(), newAttr); - } - } - - out.setAttributes(new ArrayList<>(allAttributes.values())); - } - - /** - * Writes schema locations back to a single string - * - * @param schemaLocations - * a mapping of schema name to schema location - * @return the schema location value - */ - private String schemaLocationsToString(Map schemaLocations) { - - StringBuilder schemaLocationsAttrValue = new StringBuilder(); - for (String schema : schemaLocations.keySet()) { - schemaLocationsAttrValue.append(schema); - schemaLocationsAttrValue.append(" "); - schemaLocationsAttrValue.append(schemaLocations.get(schema)); - schemaLocationsAttrValue.append(" "); - } - return schemaLocationsAttrValue.toString().trim(); - } - - /** - * Extracts all schema location definitions from the schema location value by splitting the value at each - * whitespace. Each odd element will be interpreted as a schema, each even one will be interpreted as the - * schema location from the previous element. - * - * @param schemaLocationValue - * schemaLocation attribute value - * @return a mapping of schema name to schema location - */ - private Map extractSchemaLocationDefinitions(String schemaLocationValue) { - - Map schemaLocations = Maps.newLinkedHashMap(); - String[] schemalocationsOrig = schemaLocationValue.split("\\s+"); - int i = 0; - String schema = null; - for (String schemaLocationFragment : schemalocationsOrig) { - if (i % 2 == 0) { - schema = schemaLocationFragment; - } else { - schemaLocations.put(schema, schemaLocationFragment); - } - i++; - } - return schemaLocations; - } -} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/CompleteMergeAction.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/CompleteMergeAction.java deleted file mode 100644 index 44d08226bf..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/CompleteMergeAction.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.capgemini.cobigen.xmlplugin.merger.action; - -import java.util.List; - -import org.jdom.Comment; -import org.jdom.Content; -import org.jdom.Element; -import org.jdom.Namespace; -import org.jdom.Text; -import org.jdom.filter.ContentFilter; - -import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException; -import ch.elca.el4j.services.xmlmerge.action.CompleteAction; -import ch.elca.el4j.services.xmlmerge.action.OrderedMergeAction; - -/** - * This class combines the functionality of the {@link OrderedMergeAction} class and the - * {@link CompleteAction} class - * - * @author trippl (05.04.2013) - */ -public class CompleteMergeAction extends BasicMergeAction { - - /** - * {@inheritDoc} - */ - @Override - protected void mergeContent(Element outElement, Element originalElement, Element patchElement) - throws AbstractXmlMergeException { - - ContentFilter filter = - new ContentFilter(ContentFilter.ELEMENT | ContentFilter.COMMENT | ContentFilter.TEXT - | ContentFilter.CDATA); - List originalContent = originalElement.getContent(filter); - List patchContent = patchElement.getContent(filter); - - for (Content content : originalContent) { - Content match = findContent(content, patchContent); - - if (match != null) { - // content in both elements - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - Element matchElement = (Element) match; - applyAction(outElement, element, matchElement); - } - patchContent.remove(match); - } else { - // content in originalContent only - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - applyAction(outElement, element, null); - } - } - } - - for (Content content : patchContent) { - // content in patchContent only - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - applyAction(outElement, null, element); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void mergeNamespaces(Element outElement, Element originalElement, Element patchElement) { - - for (Namespace namespace : (List) originalElement.getAdditionalNamespaces()) { - outElement.addNamespaceDeclaration(namespace); - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void mergeAttributes(Element outElement, Element originalElement, Element patchElement) { - - addAttributes(outElement, originalElement); - addAttributes(outElement, patchElement); - } - -} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/OverrideMergeAction.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/OverrideMergeAction.java deleted file mode 100644 index d30cdc2227..0000000000 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/action/OverrideMergeAction.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.capgemini.cobigen.xmlplugin.merger.action; - -import java.util.List; - -import org.jdom.Comment; -import org.jdom.Content; -import org.jdom.Element; -import org.jdom.Namespace; -import org.jdom.Text; -import org.jdom.filter.ContentFilter; - -import ch.elca.el4j.services.xmlmerge.AbstractXmlMergeException; -import ch.elca.el4j.services.xmlmerge.action.OrderedMergeAction; -import ch.elca.el4j.services.xmlmerge.action.OverrideAction; - -/** - * This class combines the functionality of the {@link OrderedMergeAction} class and the - * {@link OverrideAction} class - * @author trippl (05.04.2013) - */ -public class OverrideMergeAction extends BasicMergeAction { - - /** - * {@inheritDoc} - */ - @Override - protected void mergeContent(Element outElement, Element originalElement, Element patchElement) - throws AbstractXmlMergeException { - - ContentFilter filter = - new ContentFilter(ContentFilter.ELEMENT | ContentFilter.COMMENT | ContentFilter.TEXT - | ContentFilter.CDATA); - List originalContent = originalElement.getContent(filter); - List patchContent = patchElement.getContent(filter); - - for (Content content : patchContent) { - Content match = findContent(content, originalContent); - - if (match != null) { - // content in both elements - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - Element matchElement = (Element) match; - applyAction(outElement, matchElement, element); - } - originalContent.remove(match); - } else { - // content in patchContent only - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - applyAction(outElement, null, element); - } - } - } - - for (Content content : originalContent) { - // content in originalContent only - if (content instanceof Comment || content instanceof Text) { - outElement.addContent((Content) content.clone()); - } else if (content instanceof Element) { - Element element = (Element) content; - applyAction(outElement, element, null); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void mergeNamespaces(Element outElement, Element originalElement, Element patchElement) { - for (Namespace namespace : (List) patchElement.getAdditionalNamespaces()) { - outElement.addNamespaceDeclaration(namespace); - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void mergeAttributes(Element outElement, Element originalElement, Element patchElement) { - addAttributes(outElement, patchElement); - addAttributes(outElement, originalElement); - } - -} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/MergeType.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/MergeType.java new file mode 100644 index 0000000000..faefe5f733 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/MergeType.java @@ -0,0 +1,71 @@ +package com.capgemini.cobigen.xmlplugin.merger.delegates; + +import com.github.maybeec.lexeme.ConflictHandlingType; + +/** + * Maps the ConflictHandlingTypes and the already used merge types + * @author sholzer (Dec 22, 2015) + */ +public enum MergeType { + + /** + * In case of a conflict the patch document is preferred + */ + PATCHOVERWRITE("xmlmerge_override", ConflictHandlingType.PATCHOVERWRITE), + /** + * In case of a conflict the base document is preferred + */ + BASEOVERWRITE("xmlmerge", ConflictHandlingType.BASEOVERWRITE), + /** + * In case of a conflict the base document is preferred. Attributes and text nodes will be attached where + * possible + */ + BASEATTACHOROVERWRITE("xmlmerge_attachTexts", ConflictHandlingType.BASEATTACHOROVERWRITE), + /** + * In case of a conflict the patch document is preferred. Attributes and text nodes will be attached where + * possible + */ + PATCHATTACHOROVERWRITE("xmlmerge_override_attachTexts", ConflictHandlingType.PATCHATTACHOROVERWRITE); + + /** + * The ConflictHandlingType + */ + public ConflictHandlingType type; + + /** + * The name of the merge mode + */ + public String value; + + /** + * + * @param value + * the name of the merge mode + * @param type + * the ConflictHandlingType + * @author sholzer (Dec 22, 2015) + */ + private MergeType(String value, ConflictHandlingType type) { + this.type = type; + this.value = value; + } + + /** + * Returns the field 'type' + * @return value of type + * @author sholzer (Dec 22, 2015) + */ + public ConflictHandlingType getType() { + return type; + } + + /** + * Returns the field 'value' + * @return value of value + * @author sholzer (Dec 22, 2015) + */ + public String getValue() { + return value; + } + +} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/XmlMergerDelegate.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/XmlMergerDelegate.java new file mode 100644 index 0000000000..544bb5d2f1 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/merger/delegates/XmlMergerDelegate.java @@ -0,0 +1,73 @@ +package com.capgemini.cobigen.xmlplugin.merger.delegates; + +import java.io.File; +import java.nio.file.Path; + +import com.capgemini.cobigen.api.exception.MergeException; +import com.capgemini.cobigen.api.extension.Merger; +import com.github.maybeec.lexeme.LeXeMerger; +import com.github.maybeec.lexeme.common.exception.XMLMergeException; + +/** + * Provides a XmlLawMerger instance with the {@link Merger} interface + */ +public class XmlMergerDelegate implements Merger { + + /** Merger type of this instance. */ + + private MergeType mergeType = MergeType.PATCHOVERWRITE; + + /** {@link LeXeMerger} instance to be used. */ + private LeXeMerger merger; + + /** + * + * @param mergeSchemaLocation + * path to the folder containing the merge schemas to be used + * @param mergeType + * the way how conflicts will be handled + * @author sholzer (Aug 27, 2015) + */ + public XmlMergerDelegate(String mergeSchemaLocation, MergeType mergeType) { + this.mergeType = mergeType; + merger = new LeXeMerger(mergeSchemaLocation); + } + + /** + * + * @param mergeSchemaLocation + * path to the folder containing the merge schemas to be used + * @param mergeType + * the way how conflicts will be handled + * @author sholzer (Aug 27, 2015) + */ + public XmlMergerDelegate(Path mergeSchemaLocation, MergeType mergeType) { + this.mergeType = mergeType; + merger = new LeXeMerger(mergeSchemaLocation); + } + + @Override + public String getType() { + return mergeType.value; + } + + @Override + public String merge(File base, String patch, String targetCharset) throws MergeException { + try { + return merger.mergeInString(base, patch, targetCharset, mergeType.type); + } catch (XMLMergeException e) { + throw new MergeException(base, "Error during merge processing by LeXeMe.", e); + } + } + + /** + * Sets the validation flag + * @param validation + * true if a validation is desired. false otherwise. Default is true + * @author sholzer (Sep 1, 2015) + */ + public void setValidation(boolean validation) { + merger.setValidation(validation); + } + +} diff --git a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/util/XmlUtil.java b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/util/XmlUtil.java index 989b2ec1e5..07ec118d13 100644 --- a/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/util/XmlUtil.java +++ b/cobigen/cobigen-xmlplugin/src/main/java/com/capgemini/cobigen/xmlplugin/util/XmlUtil.java @@ -31,8 +31,8 @@ public class XmlUtil { * @throws ParserConfigurationException * thrown if document builder is configured wrong */ - public static Document parseXmlFileToDom(File file) throws SAXException, IOException, - ParserConfigurationException { + public static Document parseXmlFileToDom(File file) + throws SAXException, IOException, ParserConfigurationException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document parsedDocument = dBuilder.parse(file); @@ -54,8 +54,8 @@ public static Document parseXmlFileToDom(File file) throws SAXException, IOExcep * @throws ParserConfigurationException * thrown if document builder is configured wrong */ - public static Document parseXmlStreamToDom(InputStream stream) throws SAXException, IOException, - ParserConfigurationException { + public static Document parseXmlStreamToDom(InputStream stream) + throws SAXException, IOException, ParserConfigurationException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document parsedDocument = dBuilder.parse(stream); diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/beanMappings.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/beanMappings.xml new file mode 100644 index 0000000000..cace1abbb0 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/beanMappings.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/hibernate.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/hibernate.xml new file mode 100644 index 0000000000..49c5b9f526 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/hibernate.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jfs-html.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jfs-html.xml new file mode 100644 index 0000000000..749808bae0 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jfs-html.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jsf-facelets.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jsf-facelets.xml new file mode 100644 index 0000000000..b547adfbb4 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/incomplete_jsf-facelets.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/jaxrSchema.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/jaxrSchema.xml new file mode 100644 index 0000000000..332dc874fd --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/jaxrSchema.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/maven.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/maven.xml new file mode 100644 index 0000000000..7b87f562b9 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/maven.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/persistenceOrm.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/persistenceOrm.xml new file mode 100644 index 0000000000..e5471123e6 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/persistenceOrm.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springAOP.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springAOP.xml new file mode 100644 index 0000000000..2a9ec0b964 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springAOP.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springBeans.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springBeans.xml new file mode 100644 index 0000000000..5ab720d4f7 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springBeans.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springContext.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springContext.xml new file mode 100644 index 0000000000..63a0eb0c0d --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springContext.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springSecurity.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springSecurity.xml new file mode 100644 index 0000000000..afa9a5edf4 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springSecurity.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springTransaction.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springTransaction.xml new file mode 100644 index 0000000000..a2fdfb862e --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springTransaction.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springUtil.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springUtil.xml new file mode 100644 index 0000000000..e7c5ef5b3d --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springUtil.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springWebflow.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springWebflow.xml new file mode 100644 index 0000000000..554e99b8b6 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/springWebflow.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/xhtml.xml b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/xhtml.xml new file mode 100644 index 0000000000..4fdd345856 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/main/resources/mergeSchemas/xhtml.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/UpgradeTestdataConfigurations.java b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/UpgradeTestdataConfigurations.java new file mode 100644 index 0000000000..29cfb80b25 --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/UpgradeTestdataConfigurations.java @@ -0,0 +1,62 @@ +package com.capgemini.cobigen.xmlplugin; + +import java.io.File; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.capgemini.cobigen.impl.config.upgrade.ContextConfigurationUpgrader; +import com.capgemini.cobigen.impl.config.upgrade.TemplateConfigurationUpgrader; +import com.google.common.collect.Lists; + +/** + * Just a script to maintain test data after upgrading configurations. Should be run with caution! + */ +public class UpgradeTestdataConfigurations { + + /** Logger instance. */ + private static final Logger LOG = LoggerFactory.getLogger(UpgradeTestdataConfigurations.class); + + /** + * Just a script to maintain test data after upgrading configurations. Should be run with caution! + */ + @Test + @Ignore + public void upgradeTestdataConfigurations() { + File root = new File("src/test/resources/testdata/"); + LinkedList workingset = Lists.newLinkedList(); + List rootChildren = Arrays.asList(root.listFiles()); + workingset.addAll(rootChildren); + LOG.debug("Adding {} files to worklist.", rootChildren.size()); + + while (!workingset.isEmpty()) { + File current = workingset.pop(); + if (current.isDirectory() && !current.getName().equals("upgrade")) { + List children = Arrays.asList(current.listFiles()); + workingset.addAll(children); + LOG.debug("Adding {} files to worklist.", children.size()); + } else if (current.getName().equals("context.xml")) { + if (!current.toPath().getParent().getFileName().toString().startsWith("faulty")) { + LOG.debug("Upgrading ContextConfiguration: {}", current.toPath()); + new ContextConfigurationUpgrader() + .upgradeConfigurationToLatestVersion(current.toPath().getParent(), true); + current.toPath().resolveSibling("context.bak.xml").toFile().delete(); + } + } else if (current.getName().equals("templates.xml")) { + if (!current.toPath().getParent().getFileName().toString().startsWith("faulty")) { + LOG.debug("Upgrading TemplateConfiguration: {}", current.toPath()); + new TemplateConfigurationUpgrader() + .upgradeConfigurationToLatestVersion(current.toPath().getParent(), true); + current.toPath().resolveSibling("templates.bak.xml").toFile().delete(); + } + } + } + + LOG.debug("DONE."); + } +} diff --git a/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/XmlPluginIntegrationTest.java b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/XmlPluginIntegrationTest.java index c5e3d301bc..ee1ef32d52 100644 --- a/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/XmlPluginIntegrationTest.java +++ b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/XmlPluginIntegrationTest.java @@ -1,31 +1,37 @@ package com.capgemini.cobigen.xmlplugin.integrationtest; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + import java.io.File; +import java.nio.file.Paths; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import junit.framework.AssertionFailedError; - import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.SystemUtils; import org.junit.Assert; -import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.w3c.dom.Document; -import com.capgemini.cobigen.CobiGen; -import com.capgemini.cobigen.config.ContextConfiguration.ContextSetting; -import com.capgemini.cobigen.extension.to.TemplateTo; -import com.capgemini.cobigen.pluginmanager.PluginRegistry; +import com.capgemini.cobigen.api.CobiGen; +import com.capgemini.cobigen.api.exception.InvalidConfigurationException; +import com.capgemini.cobigen.api.exception.MergeException; +import com.capgemini.cobigen.api.to.TemplateTo; +import com.capgemini.cobigen.impl.CobiGenFactory; +import com.capgemini.cobigen.impl.PluginRegistry; import com.capgemini.cobigen.xmlplugin.XmlPluginActivator; +import junit.framework.AssertionFailedError; + /** - * Test suite for testing the xml plugin correctly integrated with cobigen-core - * @author fkreis (19.11.2014) + * Test suite for testing the xml plugin correctly integrated with cobigen-core. */ public class XmlPluginIntegrationTest { @@ -49,8 +55,8 @@ public class XmlPluginIntegrationTest { * Common test setup * @author fkreis (19.11.2014) */ - @Before - public void setup() { + @BeforeClass + public static void setup() { PluginRegistry.loadPlugin(XmlPluginActivator.class); } @@ -63,38 +69,8 @@ public void setup() { @Test public void testXmlReaderIntegration_SingleAttribute() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); - - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); - - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_SingleAttribute")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_SingleAttribute.txt"); - - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("rootAttr1ContentrootAttr2ContentrootAttr3Content", - FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } - } - - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); - } + generateTemplateAndTestOutput("xmlTestTemplate_SingleAttribute", "xmlTestOutput_SingleAttribute.txt", + "rootAttr1ContentrootAttr2ContentrootAttr3Content"); } /** @@ -106,39 +82,8 @@ public void testXmlReaderIntegration_SingleAttribute() throws Exception { @Test public void testXmlReaderIntegration_AttributeList() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); - - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); - - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_AttributeList")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_AttributeList.txt"); - - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals( - "rootAttr1rootAttr1ContentrootAttr2rootAttr2ContentrootAttr3rootAttr3Content", - FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } - } - - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); - } + generateTemplateAndTestOutput("xmlTestTemplate_AttributeList", "xmlTestOutput_AttributeList.txt", + "rootAttr1rootAttr1ContentrootAttr2rootAttr2ContentrootAttr3rootAttr3Content"); } /** @@ -150,38 +95,8 @@ public void testXmlReaderIntegration_AttributeList() throws Exception { @Test public void testXmlReaderIntegration_TextContent() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); - - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); - - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_TextContent")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_TextContent.txt"); - - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("rootTextContent1rootTextContent2", - FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } - } - - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); - } + generateTemplateAndTestOutput("xmlTestTemplate_TextContent", "xmlTestOutput_TextContent.txt", + "rootTextContent1rootTextContent2"); } /** @@ -193,38 +108,8 @@ public void testXmlReaderIntegration_TextContent() throws Exception { @Test public void testXmlReaderIntegration_TextNodes() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); - - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); - - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_TextNodes")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_TextNodes.txt"); - - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("rootTextContent1 rootTextContent2 ", - FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } - } - - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); - } + generateTemplateAndTestOutput("xmlTestTemplate_TextNodes", "xmlTestOutput_TextNodes.txt", + "rootTextContent1 rootTextContent2 "); } /** @@ -236,37 +121,21 @@ public void testXmlReaderIntegration_TextNodes() throws Exception { @Test public void testXmlReaderIntegration_SingleChild() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); - - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); - - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_SingleChild")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_SingleChild.txt"); + generateTemplateAndTestOutput("xmlTestTemplate_SingleChild", "xmlTestOutput_SingleChild.txt", + "child1"); + } - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("child1", FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } - } + /** + * Tests the xml reader integration for text nodes + * @throws Exception + * test fails + * @author fkreis (26.11.2014) + */ + @Test + public void testXmlReaderIntegration_ChildList() throws Exception { - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); - } + generateTemplateAndTestOutput("xmlTestTemplate_ChildList", "xmlTestOutput_ChildList.txt", + "child1childdublicatechilddublicate"); } /** @@ -276,74 +145,146 @@ public void testXmlReaderIntegration_SingleChild() throws Exception { * @author fkreis (26.11.2014) */ @Test - public void testXmlReaderIntegration_ChildList() throws Exception { + public void testXmlReaderIntegration_VariablesConstant() throws Exception { - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); + generateTemplateAndTestOutput("xmlTestTemplate_VariablesConstant", + "xmlTestOutput_VariablesConstant.txt", "testConstantValue"); + } - // read xml File as Document - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document inputDocument = dBuilder.parse(testinput); + /** + * Regression test that the error message of cobigen-core has not be changed, which indicates a merge + * strategy to not being found. This is necessary for the tests checking the already implemented merge + * strategies to exist. + * @throws Exception + * test fails + */ + @Test + public void testMergeStrategyNotFoundErrorMessageRegression() throws Exception { + generateTemplateAndTestOutput("xmlTestTemplate_SingleAttribute", "xmlTestOutput_SingleAttribute.txt", + null); + try { + generateTemplateAndTestOutput("xmlTestTemplate_SingleAttribute", + "xmlTestOutput_SingleAttribute.txt", null); + } catch (InvalidConfigurationException e) { + assertThat(e.getMessage(), containsString("No merger for merge strategy")); + } + } - // find matching templates and use testtemplate for generation - List templates = cobiGen.getMatchingTemplates(inputDocument); - boolean templateFound = false; - for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_ChildList")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_ChildList.txt"); + /** + * Tests the merge strategy xmlmerge_attachTexts to exist and being registered. + * @throws Exception + * test fails + * @author mbrunnli (Jan 10, 2016) + */ + @Test + public void testMergeStrategyDefined_xmlmerge_attachTexts() throws Exception { - // validate results - Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("child1childdublicatechilddublicate", - FileUtils.readFileToString(expectedFile)); - templateFound = true; - break; - } + generateTemplateAndTestOutput("xmlTestTemplate_TextNodes", "xmlTestOutput_TextNodes.txt", null); + try { + generateTemplateAndTestOutput("xmlTestTemplate_TextNodes", "xmlTestOutput_TextNodes.txt", null); + } catch (MergeException e) { + assertThat(e.getMessage(), not(containsString("No merger for merge strategy"))); } + } - if (!templateFound) { - throw new AssertionFailedError("Test template not found"); + /** + * Tests the merge strategy xmlmerge_override_attachTexts to exist and being registered. + * @throws Exception + * test fails + * @author mbrunnli (Jan 10, 2016) + */ + @Test + public void testMergeStrategyDefined_xmlmerge_override_attachTexts() throws Exception { + + generateTemplateAndTestOutput("xmlTestTemplate_SingleChild", "xmlTestOutput_SingleChild.txt", null); + try { + generateTemplateAndTestOutput("xmlTestTemplate_SingleChild", "xmlTestOutput_SingleChild.txt", + null); + } catch (MergeException e) { + assertThat(e.getMessage(), not(containsString("No merger for merge strategy"))); } } /** - * Tests the xml reader integration for text nodes + * Tests the merge strategy xmlmerge to exist and being registered. * @throws Exception * test fails - * @author fkreis (26.11.2014) + * @author mbrunnli (Jan 10, 2016) */ @Test - public void testXmlReaderIntegration_VariablesConstant() throws Exception { + public void testMergeStrategyDefined_xmlmerge() throws Exception { + + generateTemplateAndTestOutput("xmlTestTemplate_ChildList", "xmlTestOutput_ChildList.txt", null); + try { + generateTemplateAndTestOutput("xmlTestTemplate_ChildList", "xmlTestOutput_ChildList.txt", null); + } catch (MergeException e) { + assertThat(e.getMessage(), not(containsString("No merger for merge strategy"))); + } + } - CobiGen cobiGen = new CobiGen(cobigenConfigFolder); - File tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); - cobiGen - .setContextSetting(ContextSetting.GenerationTargetRootPath, tmpFolderCobiGen.getAbsolutePath()); + /** + * Tests the merge strategy xmlmerge_override to exist and being registered. + * @throws Exception + * test fails + * @author mbrunnli (Jan 10, 2016) + */ + @Test + public void testMergeStrategyDefined_xmlmerge_override() throws Exception { + + generateTemplateAndTestOutput("xmlTestTemplate_VariablesConstant", + "xmlTestOutput_VariablesConstant.txt", null); + try { + generateTemplateAndTestOutput("xmlTestTemplate_VariablesConstant", + "xmlTestOutput_VariablesConstant.txt", null); + } catch (MergeException e) { + assertThat(e.getMessage(), not(containsString("No merger for merge strategy"))); + } + } + + /** + * Generates the template with the given templateId and reads the generated File with the outputFileName. + * It will be asserted, that this file has the expectedFileContents passed as parameter. + * @param templateId + * Template to generate + * @param outputFileName + * file name of the generated output File + * @param expectedFileContents + * generated contents to be expected (asserted) + * @throws Exception + * if anything fails. + * @author mbrunnli (Jan 9, 2016) + */ + private void generateTemplateAndTestOutput(String templateId, String outputFileName, + String expectedFileContents) throws Exception { + CobiGen cobiGen = CobiGenFactory.create(cobigenConfigFolder.toURI()); + + // wenn der temporäre Output Ordner breits existiert, dann wird dieser wiederverwendet. + File tmpFolderCobiGen = + new File(tmpFolder.getRoot().getAbsolutePath() + SystemUtils.FILE_SEPARATOR + "cobigen_output"); + if (!tmpFolderCobiGen.exists()) { + tmpFolderCobiGen = tmpFolder.newFolder("cobigen_output"); + } // read xml File as Document DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document inputDocument = dBuilder.parse(testinput); - // find matching templates and use testtemplate for generation + // find matching templates and use test template for generation List templates = cobiGen.getMatchingTemplates(inputDocument); boolean templateFound = false; for (TemplateTo template : templates) { - if (template.getId().equals("xmlTestTemplate_VariablesConstant")) { - cobiGen.generate(inputDocument, template, false); - File expectedFile = - new File(tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR - + "xmlTestOutput_VariablesConstant.txt"); + if (template.getId().equals(templateId)) { + cobiGen.generate(inputDocument, template, Paths.get(tmpFolderCobiGen.getAbsolutePath()), + false); + File expectedFile = new File( + tmpFolderCobiGen.getAbsoluteFile() + SystemUtils.FILE_SEPARATOR + outputFileName); - // validate results Assert.assertTrue(expectedFile.exists()); - Assert.assertEquals("testConstantValue", FileUtils.readFileToString(expectedFile)); + // validate results if expected file contents are defined + if (expectedFileContents != null) { + Assert.assertEquals(expectedFileContents, FileUtils.readFileToString(expectedFile)); + } templateFound = true; break; } diff --git a/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/merger/XmlPluginMergerIntegrationTest.java b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/merger/XmlPluginMergerIntegrationTest.java new file mode 100644 index 0000000000..dc719a7bee --- /dev/null +++ b/cobigen/cobigen-xmlplugin/src/test/java/com/capgemini/cobigen/xmlplugin/integrationtest/merger/XmlPluginMergerIntegrationTest.java @@ -0,0 +1,326 @@ +package com.capgemini.cobigen.xmlplugin.integrationtest.merger; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; + +import com.capgemini.cobigen.api.extension.Merger; +import com.capgemini.cobigen.xmlplugin.merger.delegates.MergeType; +import com.capgemini.cobigen.xmlplugin.merger.delegates.XmlMergerDelegate; + +/** + * Tests if the used XML patchPreferingMerger behaves as desired. + */ +public class XmlPluginMergerIntegrationTest { + + /** + * The merger under test, prefers patch values over base values + */ + private Merger patchPreferingMerger; + + /** + * The merger under test, prefers base values over patch values + */ + private Merger basePreferingMerger; + + /** + * + */ + private final String charset = StandardCharsets.UTF_8.name(); + + /** + * the path to the used resources + */ + private final String resourcesRoot = "src/test/resources/testdata/unittest/merger/"; + + /** + * Sets up a patchPreferingMerger and a basePreferingMerger without validation + */ + @Before + public void setUp() { + final String mergeSchemaLocation = "src/main/resources/mergeSchemas/"; + patchPreferingMerger = new XmlMergerDelegate(mergeSchemaLocation, MergeType.PATCHATTACHOROVERWRITE); + // ((XmlLawMergerDelegate) patchPreferingMerger).setValidation(false); + basePreferingMerger = new XmlMergerDelegate(mergeSchemaLocation, MergeType.BASEATTACHOROVERWRITE); + ((XmlMergerDelegate) basePreferingMerger).setValidation(false); + } + + /** + * @throws Exception + * test fails + */ + @Test + public void mergeDoesNotDestroySchemaLocation() throws Exception { + String basePath = resourcesRoot + "BaseFile_namespaces.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(basePath, charset); + String mergedString = basePreferingMerger.merge(baseFile, patchString, charset); + Assert.assertTrue("Schema definition 'xsi:schemaLocation' has been destroyed.", + mergedString.contains("xsi:schemaLocation")); + + } + + /** + * Tests Issue #18 - https://github.com/oasp/tools-cobigen/issues/18 + * + * @throws Exception + * test fails + */ + @Test + public void testMergeAlsoMergesSchemaLocations() throws Exception { + + String basePath = resourcesRoot + "BaseFile_namespaces.xml"; + String patchPath = resourcesRoot + "PatchFile_namespaces.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedDoc = basePreferingMerger.merge(baseFile, patchString, charset); + + Assert.assertTrue("Merged document does not contain schema locations defined in base.", mergedDoc.contains( + "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd")); + Assert.assertTrue("Merged document does not contain schema locations defined in patch.", mergedDoc.contains( + "http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd")); + } + + /** + * Tests whether merging of schemaLocations is not producing duplicates + * + * @throws Exception + * test fails + */ + @Test + public void testNoDuplicateNamespacesMerged() throws Exception { + + String basePath = resourcesRoot + "BaseFile_namespaces.xml"; + String patchPath = resourcesRoot + "PatchFile_namespaces.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedDoc = basePreferingMerger.merge(baseFile, patchString, charset); + + Assert.assertFalse("Merge duplicates schema locations.", mergedDoc.contains( + "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd " + + "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd")); + } + + /** + * Merges two Spring web flow documents. + * @author sholzer (Aug 27, 2015) + * @throws Exception + * hopefully never + */ + @Test + public void webFlowTest() throws Exception { + String basePath = resourcesRoot + "BaseFile_flow.xml"; + String patchPath = resourcesRoot + "PatchFile_flow.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedString = basePreferingMerger.merge(baseFile, patchString, charset); + + Document mergeDoc = parseString(mergedString); + + Assert.assertEquals(1, mergeDoc.getElementsByTagName("flow").getLength()); + Assert.assertEquals(1, mergeDoc.getElementsByTagName("view-state").getLength()); + Assert.assertEquals(2, mergeDoc.getElementsByTagName("subflow-state").getLength()); + Assert.assertEquals(1, mergeDoc.getElementsByTagName("end-state").getLength()); + Assert.assertEquals(3, ((Element) mergeDoc.getElementsByTagName("view-state").item(0)) + .getElementsByTagName("transition").getLength()); + Assert.assertEquals(1, ((Element) mergeDoc.getElementsByTagName("subflow-state").item(0)) + .getElementsByTagName("transition").getLength()); + Assert.assertEquals(1, ((Element) mergeDoc.getElementsByTagName("subflow-state").item(1)) + .getElementsByTagName("transition").getLength()); + } + + /** + * Merges two xhtml documents + * @throws Exception + * test fails + * @author sholzer (Aug 28, 2015) + */ + @Test + public void xhtmlTest() throws Exception { + String basePath = resourcesRoot + "BaseFile_overview.xhtml"; + String patchPath = resourcesRoot + "PatchFile_overview.xhtml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedString = basePreferingMerger.merge(baseFile, patchString, charset); + + Document mergeDoc = parseString(mergedString); + // changed by sholzer on 10.09.2015. The element in + // question is now the second in the list (to be + // honest I can't tell why but the document remains valid + Assert.assertEquals(1, mergeDoc.getElementsByTagName("ui:composition").getLength()); + Assert.assertEquals(4, mergeDoc.getElementsByTagName("ui:define").getLength()); + Assert.assertEquals(1, + ((Element) mergeDoc.getElementsByTagName("ui:define").item(1)).getElementsByTagName("title").getLength()); + Assert.assertEquals(1, ((Element) mergeDoc.getElementsByTagName("ui:define").item(0)) + .getElementsByTagName("ui:include").getLength()); + Assert.assertEquals(1, ((Element) mergeDoc.getElementsByTagName("ui:define").item(2)) + .getElementsByTagName("ui:include").getLength()); + Assert.assertEquals(1, ((Element) mergeDoc.getElementsByTagName("ui:define").item(3)) + .getElementsByTagName("ui:include").getLength()); + } + + /** + * @throws Exception + * test fails + * @author sholzer (Aug 28, 2015) + */ + @Test + public void queryTest() throws Exception { + String basePath = resourcesRoot + "BaseFile_queries.xml"; + String patchPath = resourcesRoot + "PatchFile_queries.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedString = basePreferingMerger.merge(baseFile, patchString, charset); + + Document mergeDoc = parseString(mergedString); + Assert.assertEquals(1, mergeDoc.getElementsByTagName("hibernate-mapping").getLength()); + Assert.assertEquals(5, mergeDoc.getElementsByTagName("query").getLength()); + } + + /** + * @throws Exception + * test fails + */ + @Test + public void xhtmlTableTest() throws Exception { + String basePath = resourcesRoot + "BaseFile_table.xhtml"; + String patchPath = resourcesRoot + "PatchFile_table.xhtml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedString = basePreferingMerger.merge(baseFile, patchString, charset); + + Document mergeDoc = parseString(mergedString); + + Assert.assertEquals(1, mergeDoc.getDocumentElement().getElementsByTagName("div").getLength()); + Assert.assertEquals(1, mergeDoc.getDocumentElement().getElementsByTagName("h:dataTable").getLength()); + Assert.assertEquals(7, ((Element) mergeDoc.getDocumentElement().getElementsByTagName("h:dataTable").item(0)) + .getElementsByTagName("h:column").getLength()); + } + + /** + * Tests Issue https://github.com/devonfw/tools-cobigen/issues/119 + * @throws Exception + * when something goes wrong + */ + @Test + public void testMergeDozerMapping() throws Exception { + String basePath = resourcesRoot + "BaseFile_OneOneNine_dozer.xml"; + String patchPath = resourcesRoot + "PatchFile_OneOneNine_dozer.xml"; + + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedDoc = basePreferingMerger.merge(baseFile, patchString, charset); + assertEquals("not the expected amount of mappings", 5, mergedDoc.split(" is + // returned as well and needed to be considered + } + + /** + * Test for Issue #189. Tests if maven configurations can be merged to accumulate dependencies + * @throws Exception + * shouldn't happen + */ + @Test + public void testMavenAddDependency() throws Exception { + String basePath = resourcesRoot + "BasePom.xml"; + String patchPath = resourcesRoot + "PatchPom.xml"; + File baseFile = new File(basePath); + String patchString = readFile(patchPath, charset); + String mergedDoc = patchPreferingMerger.merge(baseFile, patchString, charset); + assertEquals("Not the expected number of dependencies elements", 1, + mergedDoc.split(" - - + + - - - + + + - diff --git a/cobigen/cobigen-xmlplugin/src/test/resources/testdata/integrationtest/templates/testTemplates/templates.xml b/cobigen/cobigen-xmlplugin/src/test/resources/testdata/integrationtest/templates/testTemplates/templates.xml index d58dcc66d6..b36e8027ad 100644 --- a/cobigen/cobigen-xmlplugin/src/test/resources/testdata/integrationtest/templates/testTemplates/templates.xml +++ b/cobigen/cobigen-xmlplugin/src/test/resources/testdata/integrationtest/templates/testTemplates/templates.xml @@ -1,15 +1,12 @@ - - - - - -