olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rare...@apache.org
Subject olingo-odata4 git commit: OLINGO-861: Adding support to resolve entities defined in the reference documents
Date Wed, 10 Feb 2016 16:09:21 GMT
Repository: olingo-odata4
Updated Branches:
  refs/heads/master 7a68ae68a -> 801899a08


OLINGO-861: Adding support to resolve entities defined in the reference documents


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/801899a0
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/801899a0
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/801899a0

Branch: refs/heads/master
Commit: 801899a0859bb2aa6bad567d7cff243b0c25a58d
Parents: 7a68ae6
Author: Ramesh Reddy <rareddy@jboss.org>
Authored: Wed Feb 10 10:03:20 2016 -0600
Committer: Ramesh Reddy <rareddy@jboss.org>
Committed: Wed Feb 10 10:03:20 2016 -0600

----------------------------------------------------------------------
 .../olingo/server/core/MetadataParser.java      |  66 ++++++++++--
 .../olingo/server/core/ReferenceResolver.java   |  32 ++++++
 .../server/core/SchemaBasedEdmProvider.java     | 104 ++++++++++++++++---
 3 files changed, 180 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index e8122d7..b564792 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -18,9 +18,12 @@
  */
 package org.apache.olingo.server.core;
 
+import java.io.IOException;
 import java.io.Reader;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -33,6 +36,7 @@ import javax.xml.stream.events.EndElement;
 import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
 
+import org.apache.olingo.commons.api.edm.EdmException;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.geo.SRID;
 import org.apache.olingo.commons.api.edm.provider.CsdlAction;
@@ -42,7 +46,6 @@ import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
 import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
 import org.apache.olingo.commons.api.edm.provider.CsdlBindingTarget;
 import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
-import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
@@ -92,16 +95,22 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
  */
 public class MetadataParser {
   private boolean parseAnnotations = false;
-
+  private final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
+  private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
+  
   public void setParseAnnotations(boolean f) {
     this.parseAnnotations = true;
   }
   
+  public void setReferenceResolver(ReferenceResolver resolver) {
+    this.referenceResolver = resolver;
+  }
+  
   public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
     XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
 
-    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
     final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
     
     new ElementReader<SchemaBasedEdmProvider>() {
@@ -109,6 +118,8 @@ public class MetadataParser {
       void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
           String name) throws XMLStreamException {
         String version = attr(element, "Version");
+        String xmlBase = attrNS(element, XML_LINK_NS, "base");
+        provider.setXMLBase(xmlBase);
         if ("4.0".equals(version)) {
           readDataServicesAndReference(reader, element, provider, references);
         } else {
@@ -124,14 +135,18 @@ public class MetadataParser {
                   event.asStartElement().getName().getLocalPart() : 
                   event.asEndElement().getName().getLocalPart()));
     }
+    provider.addReferences(references);
     return new ServiceMetadataImpl(provider, references, null);
   }
 
-  CsdlEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+  SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
     XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
-
-    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+    return buildEdmProvider(reader);
+  } 
+  
+  SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader) throws XMLStreamException
{
+    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(this.referenceResolver);
     new ElementReader<SchemaBasedEdmProvider>() {
       @Override
       void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
@@ -141,8 +156,7 @@ public class MetadataParser {
           readDataServicesAndReference(reader, element, provider, new ArrayList<EdmxReference>());
         }
       }
-    }.read(reader, null, provider, "Edmx");
-
+    }.read(reader, null, provider, "Edmx");    
     return provider;
   }  
   
@@ -776,6 +790,14 @@ public class MetadataParser {
     return null;
   }
 
+  private String attrNS(StartElement element, String ns, String name) {
+    Attribute attr = element.getAttributeByName(new QName(ns, name));
+    if (attr != null) {
+      return attr.getValue();
+    }
+    return null;
+  }  
+  
   private CsdlProperty readProperty(XMLEventReader reader, StartElement element)
       throws XMLStreamException {
     CsdlProperty property = new CsdlProperty();
@@ -1020,4 +1042,32 @@ public class MetadataParser {
     abstract void build(XMLEventReader reader, StartElement element, T t, String name)
         throws XMLStreamException;
   }
+  
+  class DefaultReferenceResolver implements ReferenceResolver{
+    @Override
+    public SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase) {
+      URL schemaURL = null;
+      try {
+        if (referenceUri.isAbsolute()) {
+          schemaURL = referenceUri.toURL();
+        } else {
+          if (xmlBase != null) {
+            schemaURL = new URL(xmlBase+referenceUri.toString());
+          } else {
+            throw new EdmException("No xml:base set to read the references from the metadata");
+          }        
+        }
+        
+        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+        XMLEventReader reader = xmlInputFactory.createXMLEventReader(schemaURL.openStream());
+        return buildEdmProvider(reader);
+      } catch (MalformedURLException e) {
+        throw new EdmException(e);
+      } catch (XMLStreamException e) {
+        throw new EdmException(e);
+      } catch (IOException e) {
+        throw new EdmException(e);
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
new file mode 100644
index 0000000..f7d5101
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ReferenceResolver.java
@@ -0,0 +1,32 @@
+/*
+ * 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.olingo.server.core;
+
+import java.net.URI;
+
+public interface ReferenceResolver {
+  /**
+   * Resolve the reference locally or from redirection from different source than defined
in the
+   * metadata document.  
+   * @param referenceUri reference URI for the schema file 
+   * @param xmlBase xml:base if provided by the metadata document; null otherwise
+   * @return
+   */
+  SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase);
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/801899a0/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
index 0612302..a2f23f6 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
@@ -19,8 +19,9 @@
 package org.apache.olingo.server.core;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.provider.CsdlAction;
@@ -41,11 +42,22 @@ import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
 import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
 import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition;
 import org.apache.olingo.commons.api.ex.ODataException;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
 
 public class SchemaBasedEdmProvider implements CsdlEdmProvider {
   private final List<CsdlSchema> edmSchemas = new ArrayList<CsdlSchema>();
+  private final Map<String, EdmxReference> references = new ConcurrentHashMap<String,
EdmxReference>();
+  private final Map<String, SchemaBasedEdmProvider> referenceSchemas 
+    = new ConcurrentHashMap<String, SchemaBasedEdmProvider>();
+  private String xmlBase;
+  private ReferenceResolver referenceResolver;
+  
+  public SchemaBasedEdmProvider(ReferenceResolver referenceResolver) {
+    this.referenceResolver = referenceResolver;
+  }
 
-  public void addSchema(CsdlSchema schema) {
+  void addSchema(CsdlSchema schema) {
     this.edmSchemas.add(schema);
   }
 
@@ -55,6 +67,39 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
         return s;
       }
     }
+    return getReferenceSchema(ns);
+  }
+
+  private CsdlSchema getReferenceSchema(String ns) {
+    if (ns == null) {
+      return null;
+    }
+    if (this.referenceSchemas.get(ns) == null) {
+      EdmxReference reference = this.references.get(ns);
+      if (reference != null) {
+        SchemaBasedEdmProvider provider = this.referenceResolver.resolveReference(reference.getUri(),
xmlBase);
+        for (EdmxReferenceInclude include : reference.getIncludes()) {
+          this.referenceSchemas.put(include.getNamespace(), provider);
+          if (include.getAlias() != null) {
+            CsdlSchema schema = provider.getSchema(include.getNamespace());
+            schema.setAlias(include.getAlias());
+            this.referenceSchemas.put(include.getAlias(), provider);
+          }
+        }
+      }
+    }
+    
+    if (this.referenceSchemas.get(ns) != null) {
+      return this.referenceSchemas.get(ns).getSchema(ns);  
+    }
+    
+    // it is possible that we may be looking for Reference schema of Reference
+    for (SchemaBasedEdmProvider provider:this.referenceSchemas.values()) {
+      CsdlSchema schema = provider.getSchema(ns);
+      if (schema != null) {
+        return schema;
+      }
+    }
     return null;
   }
 
@@ -220,22 +265,26 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
 
   @Override
   public List<CsdlAliasInfo> getAliasInfos() throws ODataException {
-    CsdlSchema schema = null;
+    ArrayList<CsdlAliasInfo> list = new ArrayList<CsdlAliasInfo>();
     for (CsdlSchema s : this.edmSchemas) {
-      if (s.getEntityContainer() != null) {
-        schema = s;
-        break;
+      if (s.getAlias() != null) {
+        CsdlAliasInfo ai = new CsdlAliasInfo();
+        ai.setAlias(s.getAlias());
+        ai.setNamespace(s.getNamespace());
+        list.add(ai);
       }
     }
-
-    if (schema == null) {
-      schema = this.edmSchemas.get(0);
+    for(EdmxReference reference:this.references.values()) {
+      for(EdmxReferenceInclude include:reference.getIncludes()) {
+        if (include.getAlias() != null) {
+          CsdlAliasInfo ai = new CsdlAliasInfo();
+          ai.setAlias(include.getAlias());
+          ai.setNamespace(include.getNamespace());
+          list.add(ai);          
+        }
+      }
     }
-
-    CsdlAliasInfo ai = new CsdlAliasInfo();
-    ai.setAlias(schema.getAlias());
-    ai.setNamespace(schema.getNamespace());
-    return Arrays.asList(ai);
+    return list;
   }
 
   @Override
@@ -304,6 +353,33 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
 
   @Override
   public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier)
throws ODataException {
+    CsdlSchema schema = getSchema(targetName.getNamespace());
+    if (schema != null) {
+      return schema.getAnnotationGroup(targetName.getName(), qualifier);
+    }
     return null;
   }
+
+  void addReferences(ArrayList<EdmxReference> references) {
+    if (references != null && !references.isEmpty()) {
+      for (EdmxReference ref:references) {
+        for (EdmxReferenceInclude include : ref.getIncludes()) {
+          if (include.getAlias() != null) {
+            this.references.put(include.getAlias(), ref);
+          }
+          this.references.put(include.getNamespace(), ref);
+        }
+      }
+    }
+  }
+
+  public void setXMLBase(String base) {
+    if (base != null) {
+      if (base.endsWith("/")) {
+        this.xmlBase = base;
+      } else {
+        this.xmlBase = base+"/";
+      }
+    }
+  }
 }


Mime
View raw message