You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2018/04/05 17:42:15 UTC
olingo-odata4 git commit: OLINGO-1252: adding ability load reference
schemas recursively, but locallized to the schema they represent
Repository: olingo-odata4
Updated Branches:
refs/heads/master d9aff6300 -> fd8bfa33d
OLINGO-1252: adding ability load reference schemas recursively, but locallized to the schema they represent
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/fd8bfa33
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/fd8bfa33
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/fd8bfa33
Branch: refs/heads/master
Commit: fd8bfa33d485e6ea158025d468a009cd8bfc19ff
Parents: d9aff63
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Thu Apr 5 12:41:42 2018 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Thu Apr 5 12:41:42 2018 -0500
----------------------------------------------------------------------
.../olingo/server/core/MetadataParser.java | 59 ++++++++++------
.../server/core/SchemaBasedEdmProvider.java | 48 +++++++------
.../olingo/server/core/MetadataParserTest.java | 73 ++++++++++++++++----
3 files changed, 122 insertions(+), 58 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fd8bfa33/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 88b8ad2..63b33d7 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
@@ -27,6 +27,8 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
@@ -100,7 +102,8 @@ public class MetadataParser {
private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
private boolean useLocalCoreVocabularies = true;
private boolean implicitlyLoadCoreVocabularies = false;
- private boolean recusivelyLoadReferences = false;
+ private boolean recursivelyLoadReferences = false;
+ private Map<String, SchemaBasedEdmProvider> globalReferenceMap = new HashMap<String, SchemaBasedEdmProvider>();
/**
* Avoid reading the annotations in the $metadata
@@ -138,7 +141,7 @@ public class MetadataParser {
* @return
*/
public MetadataParser recursivelyLoadReferences(boolean load) {
- this.recusivelyLoadReferences = load;
+ this.recursivelyLoadReferences = load;
return this;
}
@@ -154,35 +157,37 @@ public class MetadataParser {
public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
SchemaBasedEdmProvider provider = buildEdmProvider(csdl, this.referenceResolver,
- this.implicitlyLoadCoreVocabularies, this.useLocalCoreVocabularies, true);
+ this.implicitlyLoadCoreVocabularies, this.useLocalCoreVocabularies, true, null);
return new ServiceMetadataImpl(provider, provider.getReferences(), null);
}
public SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
- return buildEdmProvider(reader, this.referenceResolver,
- this.implicitlyLoadCoreVocabularies, this.useLocalCoreVocabularies, true);
+ return buildEdmProvider(reader, this.referenceResolver, this.implicitlyLoadCoreVocabularies,
+ this.useLocalCoreVocabularies, true, null);
}
- protected SchemaBasedEdmProvider buildEdmProvider(Reader csdl,
- ReferenceResolver resolver, boolean loadCore, boolean useLocal, boolean loadReferenceSchemas)
- throws XMLStreamException {
+ protected SchemaBasedEdmProvider buildEdmProvider(Reader csdl, ReferenceResolver resolver,
+ boolean loadCore, boolean useLocal,
+ boolean loadReferenceSchemas, String namespace)
+ throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
- XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
- return buildEdmProvider(reader, resolver, loadCore, useLocal, loadReferenceSchemas);
+ XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
+ return buildEdmProvider(reader, resolver, loadCore, useLocal, loadReferenceSchemas, namespace);
}
-
- protected SchemaBasedEdmProvider buildEdmProvider(InputStream csdl,
- ReferenceResolver resolver, boolean loadCore, boolean useLocal, boolean loadReferenceSchemas)
- throws XMLStreamException {
+
+ protected SchemaBasedEdmProvider buildEdmProvider(InputStream csdl, ReferenceResolver resolver,
+ boolean loadCore, boolean useLocal,
+ boolean loadReferenceSchemas, String namespace)
+ throws XMLStreamException {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
- return buildEdmProvider(reader, resolver, loadCore, useLocal, loadReferenceSchemas);
+ return buildEdmProvider(reader, resolver, loadCore, useLocal, loadReferenceSchemas, namespace);
}
protected SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader,
- ReferenceResolver resolver, boolean loadCore, boolean useLocal, boolean loadReferenceSchemas)
+ ReferenceResolver resolver, boolean loadCore, boolean useLocal, boolean loadReferenceSchemas, String namespace)
throws XMLStreamException {
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
@@ -220,7 +225,11 @@ public class MetadataParser {
loadCoreVocabulary(provider, "Org.OData.Capabilities.V1");
loadCoreVocabulary(provider, "Org.OData.Measures.V1");
}
-
+
+ if (namespace != null && !namespace.equals("") && !globalReferenceMap.containsKey(namespace)) {
+ globalReferenceMap.put(namespace, provider);
+ }
+
// load all the reference schemas
if (resolver != null && loadReferenceSchemas) {
loadReferencesSchemas(provider, xmlBase.length() == 0 ? null
@@ -239,8 +248,8 @@ public class MetadataParser {
for (EdmxReferenceInclude include : reference.getIncludes()) {
- // check if the schema is already loaded before.
- if (provider.getSchema(include.getNamespace()) != null) {
+ // check if the schema is already loaded before in current provider.
+ if (provider.getSchemaDirectly(include.getNamespace()) != null) {
continue;
}
@@ -248,15 +257,19 @@ public class MetadataParser {
loadCoreVocabulary(provider, include.getNamespace());
continue;
}
-
+
+ // check if the schema is already loaded before in parent providers
+ refProvider = this.globalReferenceMap.get(include.getNamespace());
+
if (refProvider == null) {
InputStream is = this.referenceResolver.resolveReference(reference.getUri(), xmlBase);
if (is == null) {
throw new EdmException("Failed to load Reference "+reference.getUri()+" loading failed");
} else {
// do not implicitly load core vocabularies any more. But if the
- // references loading the core vocabularies try to use local if we can
- refProvider = buildEdmProvider(is, resolver, false, useLocal, this.recusivelyLoadReferences);
+ // references loading the core vocabularies try to use local if we can
+ refProvider = buildEdmProvider(is, resolver, false, useLocal,
+ this.recursivelyLoadReferences, include.getNamespace());
}
}
@@ -308,7 +321,7 @@ public class MetadataParser {
if (schema == null) {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);
if (is != null) {
- SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false, false, true);
+ SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false, false, true, "");
provider.addVocabularySchema(namespace, childProvider);
} else {
throw new XMLStreamException("failed to load "+resource+" core vocabulary");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fd8bfa33/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 128aecb..e11cffc 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,10 @@
package org.apache.olingo.server.core;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
@@ -88,38 +90,44 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
}
CsdlSchema getSchema(String ns, boolean checkReferences) {
+ if (checkReferences) {
+ return getSchemaRecursively(ns, new HashSet<String>());
+ } else {
+ return getSchemaDirectly(ns);
+ }
+ }
+
+ CsdlSchema getSchemaDirectly(String ns) {
for (CsdlSchema s : this.edmSchemas) {
if (s.getNamespace().equals(ns)) {
return s;
}
}
- CsdlSchema s = null;
- if (checkReferences) {
- s = getReferenceSchema(ns);
- if (s == null) {
- s = getVocabularySchema(ns);
- }
- }
- return s;
+ return null;
}
- CsdlSchema getReferenceSchema(String ns) {
- if (ns == null) {
- return null;
- }
-
- if (this.referenceSchemas.get(ns) != null) {
- return this.referenceSchemas.get(ns).getSchema(ns);
+ CsdlSchema getSchemaRecursively(String ns, Set<String> parsedPath) {
+ // find the schema by namespace in current provider
+ CsdlSchema schema = getSchemaDirectly(ns);
+ if (schema != null) {
+ return schema;
}
-
- // it is possible that we may be looking for Reference schema of Reference
- for (SchemaBasedEdmProvider provider:this.referenceSchemas.values()) {
- CsdlSchema schema = provider.getSchema(ns);
+
+ // find the schema by namespace in the reference schema provider
+ for (Map.Entry<String, SchemaBasedEdmProvider> entry : this.referenceSchemas.entrySet()) {
+ String namespace = entry.getKey();
+ if (parsedPath.contains(namespace)) {
+ continue;
+ }
+ SchemaBasedEdmProvider provider = entry.getValue();
+ parsedPath.add(namespace);
+ schema = provider.getSchemaRecursively(ns, parsedPath);
if (schema != null) {
return schema;
}
}
- return null;
+
+ return getVocabularySchema(ns);
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fd8bfa33/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
index a0e6aeb..c3e67e0 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
@@ -46,6 +46,7 @@ import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlSingleton;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -56,6 +57,21 @@ public class MetadataParserTest {
CsdlEdmProvider provider = null;
+ ReferenceResolver testReferenceResolver = new ReferenceResolver() {
+ @Override
+ public InputStream resolveReference(URI uri, String xmlBase) {
+ String str = uri.toASCIIString();
+ if (str.startsWith("http://localhost/")) {
+ try {
+ return new FileInputStream("src/test/resources/"+str.substring(17));
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+ };
+
@Before
public void setUp() throws Exception {
MetadataParser parser = new MetadataParser();
@@ -197,20 +213,47 @@ public class MetadataParserTest {
public void testReferenceLoad() throws Exception {
MetadataParser parser = new MetadataParser();
parser.recursivelyLoadReferences(false);
- parser.referenceResolver(new ReferenceResolver() {
- @Override
- public InputStream resolveReference(URI uri, String xmlBase) {
- String str = uri.toASCIIString();
- if (str.startsWith("http://localhost/")) {
- try {
- return new FileInputStream("src/test/resources/"+str.substring(17));
- } catch (FileNotFoundException e) {
- return null;
- }
- }
- return null;
- }
- });
+ parser.referenceResolver(this.testReferenceResolver);
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/test.xml"));
- }
+ }
+
+ @Test
+ public void testReferenceLoadRecursively() throws Exception {
+ MetadataParser parser = new MetadataParser();
+ parser.recursivelyLoadReferences(true);
+ parser.referenceResolver(testReferenceResolver);
+ SchemaBasedEdmProvider providerTest = parser.buildEdmProvider(new FileReader("src/test/resources/test.xml"));
+
+ Assert.assertNotNull(providerTest.getSchema("Microsoft.OData.SampleService.Models.TripPin", false));
+
+ Assert.assertNull(providerTest.getSchema("org.apache.olingo.a", false));
+ Assert.assertNull(providerTest.getSchema("org.apache.olingo.b", false));
+
+ Assert.assertNotNull(providerTest.getSchema("org.apache.olingo.a", true));
+ Assert.assertNotNull(providerTest.getSchema("org.apache.olingo.b", true));
+ }
+
+ @Test
+ public void testCircleReferenceShouldNotStackOverflow() throws Exception {
+ MetadataParser parser = new MetadataParser();
+ parser.recursivelyLoadReferences(true);
+ parser.referenceResolver(testReferenceResolver);
+ SchemaBasedEdmProvider providerTest = parser.buildEdmProvider(new FileReader("src/test/resources/test.xml"));
+
+ Assert.assertNull(providerTest.getSchema("Not Found", true));
+
+
+ }
+
+ @Test
+ public void testLoadCoreVocabulary() throws Exception {
+ MetadataParser parser = new MetadataParser();
+ parser.implicitlyLoadCoreVocabularies(true);
+ parser.referenceResolver(testReferenceResolver);
+ SchemaBasedEdmProvider provider = parser.buildEdmProvider(new FileReader("src/test/resources/test.xml"));
+
+ Assert.assertNotNull(provider.getVocabularySchema("Org.OData.Core.V1"));
+ Assert.assertNotNull(provider.getSchema("Org.OData.Core.V1"));
+
+ }
}