Commits

Marcin Grzejszczak committed 69f4b59

[Mappings] Initial commit of the Mappings project

  • Participants
  • Parent commits 6509e14

Comments (0)

Files changed (11)

Groovy/Mappings/build.gradle

+apply plugin: 'java'
+
+group = 'com.blogspot.toomuchcoding'
+version = '1.0'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile 'org.codehaus.groovy:groovy-all:2.0.5'
+    compile 'org.slf4j:slf4j-log4j12:1.7.2'
+    compile 'log4j:log4j:1.2.16'
+    compile 'com.google.guava:guava:14.0'
+
+    testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+task(executeMain, dependsOn: 'classes', type: JavaExec) {
+    main = 'com.blogspot.toomuchcoding.XmlTransformer'
+    classpath = sourceSets.main.runtimeClasspath
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/XmlTransformer.java

+package com.blogspot.toomuchcoding;
+
+import com.blogspot.toomuchcoding.factory.ScriptFactoryImpl;
+import com.blogspot.toomuchcoding.factory.TransformerFactory;
+import com.blogspot.toomuchcoding.factory.TransformerFactoryImpl;
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 22.03.13
+ * Time: 23:50
+ */
+
+public class XmlTransformer {
+
+    public static void main(String... args) throws IOException{
+        URL sampleXmlUrl = Resources.getResource("xml/SampleXml.xml");
+        String inputXml = Resources.toString(sampleXmlUrl, Charsets.UTF_8);
+        System.out.println("Converted from [" + inputXml + "]\n");
+        TransformerFactory<String, String> transformerFactory = new TransformerFactoryImpl(new ScriptFactoryImpl());
+        System.out.println(" to\n\n[" + transformerFactory.createTransformer().transform(inputXml) + "]");
+    }
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/factory/ScriptFactory.java

+package com.blogspot.toomuchcoding.factory;
+
+import java.io.File;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 30.03.13
+ * Time: 16:56
+ */
+public interface ScriptFactory {
+    File createScript();
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/factory/ScriptFactoryImpl.java

+package com.blogspot.toomuchcoding.factory;
+
+import com.google.common.io.Resources;
+
+import java.io.File;
+import java.net.URL;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 30.03.13
+ * Time: 16:57
+ */
+public class ScriptFactoryImpl implements ScriptFactory {
+    private static final String TRANSFORMER_SCRIPT_PATH = "groovy/GroovyXmlTransformer.groovy";
+
+    @Override
+    public File createScript() {
+        URL transformerScriptUrl = Resources.getResource(TRANSFORMER_SCRIPT_PATH);
+        return new File(transformerScriptUrl.getFile());
+    }
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/factory/TransformerFactory.java

+package com.blogspot.toomuchcoding.factory;
+
+import com.blogspot.toomuchcoding.transformer.Transformer;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 22.03.13
+ * Time: 23:53
+ */
+public interface TransformerFactory<T,V> {
+    Transformer<T,V> createTransformer();
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/factory/TransformerFactoryImpl.java

+package com.blogspot.toomuchcoding.factory;
+
+import com.blogspot.toomuchcoding.transformer.Transformer;
+import com.google.common.io.Resources;
+import groovy.util.GroovyScriptEngine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.net.URL;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 22.03.13
+ * Time: 23:54
+ */
+public class TransformerFactoryImpl implements TransformerFactory<String, String> {
+    private static final String GROOVY_SCRIPTS_CLASSPATH = "groovy/";
+    private static Logger LOGGER = LoggerFactory.getLogger(TransformerFactoryImpl.class);
+
+    private ScriptFactory scriptFactory;
+
+    public TransformerFactoryImpl(ScriptFactory scriptFactory) {
+        this.scriptFactory = scriptFactory;
+    }
+
+    @Override
+    public Transformer<String, String> createTransformer() {
+        Transformer<String, String> transformerFromScript = null;
+        try {
+            GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(GROOVY_SCRIPTS_CLASSPATH);
+            File scriptFile = scriptFactory.createScript();
+            URL scriptAsAClasspathResource = Resources.getResource(GROOVY_SCRIPTS_CLASSPATH + scriptFile.getName());
+            Class classFromScript = groovyScriptEngine.loadScriptByName(scriptAsAClasspathResource.getFile());
+            transformerFromScript = (Transformer<String, String>) classFromScript.newInstance();
+        } catch (Exception e) {
+            LOGGER.error("Exception occurred while trying to execute Groovy script", e);
+        }
+        return transformerFromScript;
+    }
+
+}

Groovy/Mappings/src/main/java/com/blogspot/toomuchcoding/transformer/Transformer.java

+package com.blogspot.toomuchcoding.transformer;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 22.03.13
+ * Time: 23:51
+ */
+public interface Transformer<T, V> {
+    T transform(V input);
+}

Groovy/Mappings/src/main/resources/groovy/AbstractGroovyXmlTransformer.groovy

+package groovy
+
+import com.blogspot.toomuchcoding.transformer.Transformer
+import groovy.util.slurpersupport.NodeChildren
+import groovy.xml.MarkupBuilder
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 23.03.13
+ * Time: 02:16
+ */
+abstract class AbstractGroovyXmlTransformer implements Transformer<String, String> {
+
+    static Map<String, Object> MISSING_PROPERTIES = ["convertDate": new DateConverter(), "map": new Mapper()]
+
+    @Override
+    String transform(String input) {
+        def inputXml = new XmlSlurper().parseText input
+        def writer = new StringWriter()
+        def outputXml = new MarkupBuilder(writer)
+        doTransform inputXml, outputXml
+        writer.toString()
+    }
+
+    abstract void doTransform(inputXml, outputXml)
+
+    def propertyMissing(String name) {
+        MISSING_PROPERTIES[name]
+    }
+
+
+    protected static class Mapper {
+        private Map<String, String> inputParameters
+
+        Mapper given(Map inputParameters) {
+            this.inputParameters = inputParameters
+            this
+        }
+
+        String from(NodeChildren nodeChildren) {
+            assert inputParameters != null, "The mapping can't be null!"
+            assert nodeChildren != null, "Node can't be null!"
+            String nodeText = nodeChildren.text()
+            String mappedValue = inputParameters[nodeText]
+            mappedValue ?: inputParameters.default
+        }
+
+        static Mapper map(Map<String, String> inputParameters) {
+            return new Mapper(inputParameters)
+        }
+    }
+
+    protected static class DateConverter {
+        private String inputDate
+        private String inputDateFormat
+
+        DateConverter from(NodeChildren nodeChildren) {
+            this.inputDate = nodeChildren.text()
+            this
+        }
+
+        DateConverter havingDateFormat(String inputDateFormat) {
+            this.inputDateFormat = inputDateFormat
+            this
+        }
+
+        String toOutputDateFormat(String outputDateFormat) {
+            assert inputDate != null, "The input date for which you are trying to do the conversion can't be null"
+            assert inputDateFormat != null, "The input date format for which you are trying to do the conversion can't be null"
+            assert outputDateFormat != null, "The output date format for which you are trying to do the conversion can't be null"
+            Date.parse(inputDateFormat, inputDate).format(outputDateFormat)
+        }
+
+        static DateConverter convertDate() {
+            new DateConverter()
+        }
+    }
+}

Groovy/Mappings/src/main/resources/groovy/GroovyXmlTransformer.groovy

+package groovy
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: mgrzejszczak
+ * Date: 22.03.13
+ * Time: 23:59
+ *
+ * additional functions:
+ *
+ * convertDate.from(Node).havingDateFormat("DateFormat").toOutputDateFormat("AnotherDateFormat")
+ * map.given("Value to be mapped from" : "Value to be mapped to", "default" : "default value").from(Node)
+ *
+ */
+class GroovyXmlTransformer extends AbstractGroovyXmlTransformer {
+
+    @Override
+    void doTransform(inputXml, outputXml) {
+        outputXml.OutputSystemEnvelope() {
+            OutputSystemContext {
+                ResponseID(inputXml.InputSystemContext.RequestID.text().reverse())
+                OutputSource('OUTPUT_SYSTEM')
+                OutputDate(convertDate.from(inputXml.InputSystemContext.InputDate).havingDateFormat("dd/MM/yyyy").toOutputDateFormat("yy/MM/dd"))
+            }
+            OutputAdditionalData {
+                OutputReferenceNo("SOME_PREFIX_${inputXml.AdditionalData.ReferenceNo.text()}_SOME_SUFIX")
+                OutputTypeOfAction(map.given("Some_action" : "Some_output_action", "default" : "something else").from(inputXml.AdditionalData.TypeOfAction))
+                OutputTransactions {
+                    inputXml.AdditionalData.Transactions.Transaction.each {
+                        OutputTransaction(Client: it.Client, ProductType: it.ProductType, 'Done')
+                    }
+                }
+                OutputProducts {
+                    def minProduct = inputXml.AdditionalData.Products.Product.list().min { it.Value.text() }
+                    def maxProduct = inputXml.AdditionalData.Products.Product.list().max { it.Value.text() }
+                    MinProduct(name: minProduct.Name.text(), minProduct.Value.text())
+                    MaxProduct(name: maxProduct.Name.text(), maxProduct.Value.text())
+                }
+            }
+        }
+    }
+}

Groovy/Mappings/src/main/resources/log4j.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+    <!-- Appenders -->
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %-5p [%t] %c:%L %m%n"/>
+        </layout>
+    </appender>
+    <!-- Root Logger -->
+    <root>
+        <priority value="DEBUG"/>
+        <appender-ref ref="console"/>
+    </root>
+
+</log4j:configuration>

Groovy/Mappings/src/main/resources/xml/SampleXml.xml

+<InputSystemEnvelope>
+    <InputSystemContext>
+        <RequestID>1234567890</RequestID>
+        <InputSource>INPUT_SYSTEM</InputSource>
+        <InputDate>22/03/2013</InputDate>
+    </InputSystemContext>
+    <AdditionalData>
+        <ReferenceNo>Ref1234567</ReferenceNo>
+        <TypeOfAction>Some_action</TypeOfAction>
+        <Transactions>
+            <Transaction>
+                <Client>ACME</Client>
+                <ProductType>IRS</ProductType>
+            </Transaction>
+            <Transaction>
+                <Client>Oracle</Client>
+                <ProductType>DB</ProductType>
+            </Transaction>
+        </Transactions>
+        <Products>
+            <Product>
+                <Name>Book</Name>
+                <Value>1</Value>
+            </Product>
+            <Product>
+                <Name>Car</Name>
+                <Value>10000</Value>
+            </Product>
+            <Product>
+                <Name>Boat</Name>
+                <Value>100000000</Value>
+            </Product>
+            <Product>
+                <Name>Spaceship</Name>
+                <Value>1000000000000000000</Value>
+            </Product>
+        </Products>
+    </AdditionalData>
+</InputSystemEnvelope>