METAMODEL-1151: Added DataContextFactories for XML files

Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/7b91f36e
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/7b91f36e
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/7b91f36e

Branch: refs/heads/master
Commit: 7b91f36e23da09fde0f59bd1810e400f438484fd
Parents: 7b1edb9
Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com>
Authored: Tue Aug 8 20:45:34 2017 -0700
Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com>
Committed: Tue Aug 8 20:45:34 2017 -0700

----------------------------------------------------------------------
 .../metamodel/xml/XmlDomDataContextFactory.java |  49 +++++++
 .../apache/metamodel/xml/XmlSaxDataContext.java |  18 ++-
 .../metamodel/xml/XmlSaxDataContextFactory.java | 134 +++++++++++++++++++
 .../apache/metamodel/xml/XmlSaxTableDef.java    |   9 +-
 ....apache.metamodel.factory.DataContextFactory |   2 +
 5 files changed, 206 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metamodel/blob/7b91f36e/xml/src/main/java/org/apache/metamodel/xml/XmlDomDataContextFactory.java
----------------------------------------------------------------------
diff --git 
a/xml/src/main/java/org/apache/metamodel/xml/XmlDomDataContextFactory.java 
b/xml/src/main/java/org/apache/metamodel/xml/XmlDomDataContextFactory.java
new file mode 100644
index 0000000..d64163e
--- /dev/null
+++ b/xml/src/main/java/org/apache/metamodel/xml/XmlDomDataContextFactory.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.xml;
+
+import org.apache.metamodel.ConnectionException;
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.factory.DataContextFactory;
+import org.apache.metamodel.factory.DataContextProperties;
+import org.apache.metamodel.factory.ResourceFactoryRegistry;
+import org.apache.metamodel.factory.UnsupportedDataContextPropertiesException;
+import org.apache.metamodel.util.BooleanComparator;
+import org.apache.metamodel.util.Resource;
+
+public class XmlDomDataContextFactory implements DataContextFactory {
+
+    @Override
+    public boolean accepts(DataContextProperties properties, 
ResourceFactoryRegistry resourceFactoryRegistry) {
+        return "xml".equals(properties.getDataContextType()) && 
!properties.toMap().containsKey("table-defs");
+    }
+
+    @Override
+    public DataContext create(DataContextProperties properties, 
ResourceFactoryRegistry resourceFactoryRegistry)
+            throws UnsupportedDataContextPropertiesException, 
ConnectionException {
+        final Resource resource = 
resourceFactoryRegistry.createResource(properties.getResourceProperties());
+
+        boolean autoFlattenTables = true;
+        if (properties.toMap().get("auto-flatten-tables") != null) {
+            autoFlattenTables = 
BooleanComparator.toBoolean(properties.toMap().get("auto-flatten-tables"));
+        }
+
+        return new XmlDomDataContext(resource, autoFlattenTables);
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/7b91f36e/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContext.java
----------------------------------------------------------------------
diff --git a/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContext.java 
b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContext.java
index 217503c..ac0a699 100644
--- a/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContext.java
+++ b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContext.java
@@ -20,6 +20,8 @@ package org.apache.metamodel.xml;
 
 import java.io.File;
 import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -71,8 +73,8 @@ public class XmlSaxDataContext extends 
QueryPostprocessDataContext {
     private final Supplier<InputSource> _inputSourceRef;
     private final Map<XmlSaxTableDef, Map<String, String>> _valueXpaths;
     private String _schemaName;
-    private XmlSaxTableDef[] _tableDefs;
-
+    private Collection<XmlSaxTableDef> _tableDefs;
+    
     /**
      * Constructs an XML DataContext based on SAX parsing.
      * 
@@ -80,12 +82,12 @@ public class XmlSaxDataContext extends 
QueryPostprocessDataContext {
      *            a factory reference for the input source to read the XML 
from.
      *            The ref will be repeatedly called for each access to the 
file!
      * @param tableDefs
-     *            an array of table definitions, which provide instructions as
+     *            a collection of table definitions, which provide 
instructions as
      *            to the xpaths to apply to the document.
      * 
      * @see XmlSaxTableDef
      */
-    public XmlSaxDataContext(Supplier<InputSource> inputSourceRef, 
XmlSaxTableDef... tableDefs) {
+    public XmlSaxDataContext(Supplier<InputSource> inputSourceRef, 
Collection<XmlSaxTableDef> tableDefs) {
         _inputSourceRef = inputSourceRef;
         _tableDefs = tableDefs;
         _valueXpaths = new HashMap<XmlSaxTableDef, Map<String, String>>();
@@ -100,8 +102,16 @@ public class XmlSaxDataContext extends 
QueryPostprocessDataContext {
             }
         }
     }
+    
+    public XmlSaxDataContext(Supplier<InputSource> inputSourceRef, 
XmlSaxTableDef... tableDefs) {
+        this(inputSourceRef, Arrays.asList(tableDefs));
+    }
 
     public XmlSaxDataContext(final Resource resource, XmlSaxTableDef... 
tableDefs) {
+        this(resource, Arrays.asList(tableDefs));
+    }
+    
+    public XmlSaxDataContext(final Resource resource, 
Collection<XmlSaxTableDef> tableDefs) {
         this(createInputSourceRef(resource), tableDefs);
     }
 

http://git-wip-us.apache.org/repos/asf/metamodel/blob/7b91f36e/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContextFactory.java
----------------------------------------------------------------------
diff --git 
a/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContextFactory.java 
b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContextFactory.java
new file mode 100644
index 0000000..8b2acb5
--- /dev/null
+++ b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxDataContextFactory.java
@@ -0,0 +1,134 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.xml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.metamodel.ConnectionException;
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.factory.DataContextFactory;
+import org.apache.metamodel.factory.DataContextProperties;
+import org.apache.metamodel.factory.ResourceFactoryRegistry;
+import org.apache.metamodel.factory.UnsupportedDataContextPropertiesException;
+import org.apache.metamodel.util.Resource;
+import org.apache.metamodel.util.SimpleTableDef;
+
+/**
+ * A {@link DataContextFactory} for XML files where a "table-defs" or 
"xml-sax-table-defs" element has been configured
+ * and represents the tables and their XPaths as defined by {@link 
XmlSaxDataContext}.
+ * 
+ * If "table-defs" is specified, it will first be interpreted as a {@link 
SimpleTableDef} which is then mapped to a
+ * {@link XmlSaxTableDef}.
+ * 
+ * Alternatively, if "xml-sax-table-defs" is specified, it may either be a 
List, like this (JSON representation of lists
+ * and maps):
+ * 
+ * <pre>
+ * [
+ *   {
+ *     "row-x-path": "/path/to/entity1"
+ *     "value-x-paths": [
+ *       "/path/to/entity1/var1",
+ *       "/path/to/entity1/var2"
+ *     ]
+ *   },
+ *   {
+ *     "row-x-path": "/path/to/model2"
+ *     "value-x-paths": [
+ *       "/path/to/model2/field3",
+ *       "/path/to/model2/field4"
+ *     ]
+ *   }
+ * ]
+ * </pre>
+ * 
+ * Or a key/value map, like this:
+ * 
+ * <pre>
+ *   {
+ *     "/path/to/entity1": [
+ *       "/path/to/entity1/var1",
+ *       "/path/to/entity1/var2"
+ *     ],
+ *     "/path/to/model2": [
+ *       "/path/to/model2/field3",
+ *       "/path/to/model2/field4"
+ *     ]
+ *   }
+ * </pre>
+ */
+public class XmlSaxDataContextFactory implements DataContextFactory {
+
+    @Override
+    public boolean accepts(DataContextProperties properties, 
ResourceFactoryRegistry resourceFactoryRegistry) {
+        final boolean hasTableDefs =
+                properties.getTableDefs() != null || 
properties.toMap().containsKey("xml-sax-table-defs");
+        return "xml".equals(properties.getDataContextType()) && hasTableDefs;
+    }
+
+    @Override
+    public DataContext create(DataContextProperties properties, 
ResourceFactoryRegistry resourceFactoryRegistry)
+            throws UnsupportedDataContextPropertiesException, 
ConnectionException {
+
+        final List<XmlSaxTableDef> tableDefs;
+        final SimpleTableDef[] simpleTableDefs = properties.getTableDefs();
+        if (simpleTableDefs == null) {
+            tableDefs = 
createTableDefFromProperties(properties.toMap().get("xml-sax-table-defs"));
+        } else {
+            tableDefs = Arrays.stream(simpleTableDefs).map(tableDef -> {
+                return new XmlSaxTableDef(tableDef.getName(), 
tableDef.getColumnNames());
+            }).collect(Collectors.toList());
+        }
+
+        final Resource resource = 
resourceFactoryRegistry.createResource(properties.getResourceProperties());
+        return new XmlSaxDataContext(resource, tableDefs);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<XmlSaxTableDef> createTableDefFromProperties(Object 
configuredTableDefs) {
+        final List<XmlSaxTableDef> tableDefs = new ArrayList<>();
+
+        if (configuredTableDefs instanceof List) {
+            final List<Map<String, Object>> list = (List<Map<String, Object>>) 
configuredTableDefs;
+            list.forEach(tableDef -> {
+                final String rowXpath = (String) tableDef.get("row-x-path");
+                final Collection<String> valueXpaths = (Collection<String>) 
tableDef.get("value-x-paths");
+                tableDefs.add(new XmlSaxTableDef(rowXpath, valueXpaths));
+            });
+        } else if (configuredTableDefs instanceof Map) {
+            final Map<String, Collection<String>> map = (Map<String, 
Collection<String>>) configuredTableDefs;
+            map.forEach((k, v) -> {
+                final String rowXpath = k;
+                final Collection<String> valueXpaths = v;
+                tableDefs.add(new XmlSaxTableDef(rowXpath, valueXpaths));
+            });
+        } else {
+            throw new IllegalArgumentException(
+                    "Unsupported value type for property 'xml-sax-table-defs'. 
Map or List expected, but got: "
+                            + configuredTableDefs);
+        }
+
+        return tableDefs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/7b91f36e/xml/src/main/java/org/apache/metamodel/xml/XmlSaxTableDef.java
----------------------------------------------------------------------
diff --git a/xml/src/main/java/org/apache/metamodel/xml/XmlSaxTableDef.java 
b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxTableDef.java
index 2a6353f..3ef14c4 100644
--- a/xml/src/main/java/org/apache/metamodel/xml/XmlSaxTableDef.java
+++ b/xml/src/main/java/org/apache/metamodel/xml/XmlSaxTableDef.java
@@ -20,6 +20,7 @@ package org.apache.metamodel.xml;
 
 import java.io.Serializable;
 import java.util.Arrays;
+import java.util.Collection;
 
 import org.apache.metamodel.schema.Table;
 
@@ -103,8 +104,12 @@ public final class XmlSaxTableDef implements Serializable {
         *            /companies/company/employee/gender, 
index(/companies/company)]
         */
        public XmlSaxTableDef(String rowXpath, String[] valueXpaths) {
-               _rowXpath = rowXpath;
-               _valueXpaths = valueXpaths;
+           _rowXpath = rowXpath;
+           _valueXpaths = valueXpaths;
+       }
+       
+       public XmlSaxTableDef(String rowXpath, Collection<String> valueXpaths) {
+           this(rowXpath, valueXpaths.toArray(new String[valueXpaths.size()]));
        }
 
        public String getRowXpath() {

http://git-wip-us.apache.org/repos/asf/metamodel/blob/7b91f36e/xml/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
----------------------------------------------------------------------
diff --git 
a/xml/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
 
b/xml/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
new file mode 100644
index 0000000..560e023
--- /dev/null
+++ 
b/xml/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
@@ -0,0 +1,2 @@
+org.apache.metamodel.xml.XmlSaxDataContextFactory
+org.apache.metamodel.xml.XmlDomDataContextFactory
\ No newline at end of file

Reply via email to