OLINGO-880: Enable MetadataParser to load core vocabularies based on a perference setting, these are loaded loaded from local classpath, instead of making a web call
This commit is contained in:
parent
801899a085
commit
187c229b60
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.olingo.server.core;
|
package org.apache.olingo.server.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -95,38 +96,68 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
|
||||||
*/
|
*/
|
||||||
public class MetadataParser {
|
public class MetadataParser {
|
||||||
private boolean parseAnnotations = false;
|
private boolean parseAnnotations = false;
|
||||||
private final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
|
private static final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
|
||||||
private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
|
private ReferenceResolver defaultReferenceResolver = new DefaultReferenceResolver();
|
||||||
|
private boolean loadCoreVocabularies = false;
|
||||||
|
|
||||||
public void setParseAnnotations(boolean f) {
|
public MetadataParser parseAnnotations(boolean parse) {
|
||||||
this.parseAnnotations = true;
|
this.parseAnnotations = parse;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReferenceResolver(ReferenceResolver resolver) {
|
public MetadataParser referenceResolver(ReferenceResolver resolver) {
|
||||||
this.referenceResolver = resolver;
|
this.defaultReferenceResolver = resolver;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetadataParser loadCoreVocabularies(boolean load) {
|
||||||
|
this.loadCoreVocabularies = load;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
|
public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
|
||||||
|
SchemaBasedEdmProvider provider = buildEdmProvider(csdl,
|
||||||
|
this.defaultReferenceResolver, this.loadCoreVocabularies);
|
||||||
|
return new ServiceMetadataImpl(provider, provider.getReferences(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
|
||||||
|
return buildEdmProvider(csdl, this.defaultReferenceResolver, this.loadCoreVocabularies);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SchemaBasedEdmProvider buildEdmProvider(Reader csdl,
|
||||||
|
ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
|
||||||
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
||||||
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
|
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
|
||||||
|
return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SchemaBasedEdmProvider buildEdmProvider(InputStream csdl,
|
||||||
|
ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
|
||||||
|
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
||||||
|
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
|
||||||
|
return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader,
|
||||||
|
ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
|
||||||
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
|
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
|
||||||
final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
|
|
||||||
|
|
||||||
new ElementReader<SchemaBasedEdmProvider>() {
|
new ElementReader<SchemaBasedEdmProvider>() {
|
||||||
@Override
|
@Override
|
||||||
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
|
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
|
||||||
String name) throws XMLStreamException {
|
String name) throws XMLStreamException {
|
||||||
String version = attr(element, "Version");
|
|
||||||
String xmlBase = attrNS(element, XML_LINK_NS, "base");
|
String xmlBase = attrNS(element, XML_LINK_NS, "base");
|
||||||
provider.setXMLBase(xmlBase);
|
provider.setXMLBase(xmlBase);
|
||||||
|
String version = attr(element, "Version");
|
||||||
if ("4.0".equals(version)) {
|
if ("4.0".equals(version)) {
|
||||||
readDataServicesAndReference(reader, element, provider, references);
|
readDataServicesAndReference(reader, element, provider);
|
||||||
} else {
|
} else {
|
||||||
throw new XMLStreamException("Currently only V4 is supported.");
|
throw new XMLStreamException("Currently only V4 is supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.read(reader, null, provider, "Edmx");
|
}.read(reader, null, provider, "Edmx");
|
||||||
|
|
||||||
|
// make sure there is nothing left to read, due to parser error
|
||||||
if(reader.hasNext()) {
|
if(reader.hasNext()) {
|
||||||
XMLEvent event = reader.peek();
|
XMLEvent event = reader.peek();
|
||||||
throw new XMLStreamException(
|
throw new XMLStreamException(
|
||||||
|
@ -135,34 +166,33 @@ public class MetadataParser {
|
||||||
event.asStartElement().getName().getLocalPart() :
|
event.asStartElement().getName().getLocalPart() :
|
||||||
event.asEndElement().getName().getLocalPart()));
|
event.asEndElement().getName().getLocalPart()));
|
||||||
}
|
}
|
||||||
provider.addReferences(references);
|
|
||||||
return new ServiceMetadataImpl(provider, references, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
|
// load the core vocabularies
|
||||||
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
if (loadCoreVocabularies) {
|
||||||
XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
|
loadVocabularySchema(provider, "Org.OData.Core.V1", "Org.OData.Core.V1.xml");
|
||||||
return buildEdmProvider(reader);
|
loadVocabularySchema(provider, "Org.OData.Capabilities.V1", "Org.OData.Capabilities.V1.xml");
|
||||||
|
loadVocabularySchema(provider, "Org.OData.Measures.V1", "Org.OData.Measures.V1.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader) throws XMLStreamException {
|
|
||||||
SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(this.referenceResolver);
|
|
||||||
new ElementReader<SchemaBasedEdmProvider>() {
|
|
||||||
@Override
|
|
||||||
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
|
|
||||||
String name) throws XMLStreamException {
|
|
||||||
String version = attr(element, "Version");
|
|
||||||
if ("4.0".equals(version)) {
|
|
||||||
readDataServicesAndReference(reader, element, provider, new ArrayList<EdmxReference>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.read(reader, null, provider, "Edmx");
|
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadVocabularySchema(SchemaBasedEdmProvider provider, String namespace,
|
||||||
|
String resource) throws XMLStreamException {
|
||||||
|
CsdlSchema schema = provider.getSchema(namespace, false);
|
||||||
|
if (schema == null) {
|
||||||
|
InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);
|
||||||
|
if (is != null) {
|
||||||
|
SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false);
|
||||||
|
provider.addSchema(childProvider.getSchema(namespace, false));
|
||||||
|
} else {
|
||||||
|
throw new XMLStreamException("failed to load "+resource+" core vocabulary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readDataServicesAndReference(XMLEventReader reader,
|
private void readDataServicesAndReference(XMLEventReader reader,
|
||||||
StartElement element, SchemaBasedEdmProvider provider,
|
StartElement element, SchemaBasedEdmProvider provider) throws XMLStreamException {
|
||||||
final ArrayList<EdmxReference> references) throws XMLStreamException {
|
final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
|
||||||
new ElementReader<SchemaBasedEdmProvider>() {
|
new ElementReader<SchemaBasedEdmProvider>() {
|
||||||
@Override
|
@Override
|
||||||
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
|
void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
|
||||||
|
@ -174,6 +204,7 @@ public class MetadataParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.read(reader, element, provider, "DataServices", "Reference");
|
}.read(reader, element, provider, "DataServices", "Reference");
|
||||||
|
provider.addReferences(references);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readReference(XMLEventReader reader, StartElement element,
|
private void readReference(XMLEventReader reader, StartElement element,
|
||||||
|
@ -782,7 +813,7 @@ public class MetadataParser {
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String attr(StartElement element, String name) {
|
private static String attr(StartElement element, String name) {
|
||||||
Attribute attr = element.getAttributeByName(new QName(name));
|
Attribute attr = element.getAttributeByName(new QName(name));
|
||||||
if (attr != null) {
|
if (attr != null) {
|
||||||
return attr.getValue();
|
return attr.getValue();
|
||||||
|
@ -790,7 +821,7 @@ public class MetadataParser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String attrNS(StartElement element, String ns, String name) {
|
private static String attrNS(StartElement element, String ns, String name) {
|
||||||
Attribute attr = element.getAttributeByName(new QName(ns, name));
|
Attribute attr = element.getAttributeByName(new QName(ns, name));
|
||||||
if (attr != null) {
|
if (attr != null) {
|
||||||
return attr.getValue();
|
return attr.getValue();
|
||||||
|
@ -1043,9 +1074,9 @@ public class MetadataParser {
|
||||||
throws XMLStreamException;
|
throws XMLStreamException;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultReferenceResolver implements ReferenceResolver{
|
private static class DefaultReferenceResolver implements ReferenceResolver {
|
||||||
@Override
|
@Override
|
||||||
public SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase) {
|
public InputStream resolveReference(URI referenceUri, String xmlBase) {
|
||||||
URL schemaURL = null;
|
URL schemaURL = null;
|
||||||
try {
|
try {
|
||||||
if (referenceUri.isAbsolute()) {
|
if (referenceUri.isAbsolute()) {
|
||||||
|
@ -1057,14 +1088,9 @@ public class MetadataParser {
|
||||||
throw new EdmException("No xml:base set to read the references from the metadata");
|
throw new EdmException("No xml:base set to read the references from the metadata");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return schemaURL.openStream();
|
||||||
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
|
||||||
XMLEventReader reader = xmlInputFactory.createXMLEventReader(schemaURL.openStream());
|
|
||||||
return buildEdmProvider(reader);
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
throw new EdmException(e);
|
throw new EdmException(e);
|
||||||
} catch (XMLStreamException e) {
|
|
||||||
throw new EdmException(e);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new EdmException(e);
|
throw new EdmException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core;
|
package org.apache.olingo.server.core;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
public interface ReferenceResolver {
|
public interface ReferenceResolver {
|
||||||
|
@ -28,5 +29,5 @@ public interface ReferenceResolver {
|
||||||
* @param xmlBase xml:base if provided by the metadata document; null otherwise
|
* @param xmlBase xml:base if provided by the metadata document; null otherwise
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SchemaBasedEdmProvider resolveReference(URI referenceUri, String xmlBase);
|
InputStream resolveReference(URI referenceUri, String xmlBase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,15 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.core;
|
package org.apache.olingo.server.core;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmException;
|
||||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
|
import org.apache.olingo.commons.api.edm.provider.CsdlAction;
|
||||||
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
|
import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
|
||||||
|
@ -61,14 +65,25 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
|
||||||
this.edmSchemas.add(schema);
|
this.edmSchemas.add(schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CsdlSchema getSchema(String ns) {
|
List<EdmxReference> getReferences(){
|
||||||
|
return new ArrayList<EdmxReference>(references.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
CsdlSchema getSchema(String ns) {
|
||||||
|
return getSchema(ns, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
CsdlSchema getSchema(String ns, boolean checkReferences) {
|
||||||
for (CsdlSchema s : this.edmSchemas) {
|
for (CsdlSchema s : this.edmSchemas) {
|
||||||
if (s.getNamespace().equals(ns)) {
|
if (s.getNamespace().equals(ns)) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (checkReferences) {
|
||||||
return getReferenceSchema(ns);
|
return getReferenceSchema(ns);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private CsdlSchema getReferenceSchema(String ns) {
|
private CsdlSchema getReferenceSchema(String ns) {
|
||||||
if (ns == null) {
|
if (ns == null) {
|
||||||
|
@ -77,7 +92,23 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
|
||||||
if (this.referenceSchemas.get(ns) == null) {
|
if (this.referenceSchemas.get(ns) == null) {
|
||||||
EdmxReference reference = this.references.get(ns);
|
EdmxReference reference = this.references.get(ns);
|
||||||
if (reference != null) {
|
if (reference != null) {
|
||||||
SchemaBasedEdmProvider provider = this.referenceResolver.resolveReference(reference.getUri(), xmlBase);
|
SchemaBasedEdmProvider provider = null;
|
||||||
|
if (this.referenceResolver == null) {
|
||||||
|
throw new EdmException("Failed to load Reference "+reference.getUri());
|
||||||
|
} else {
|
||||||
|
InputStream is = this.referenceResolver.resolveReference(reference.getUri(), this.xmlBase);
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
MetadataParser parser = new MetadataParser();
|
||||||
|
provider = parser.buildEdmProvider(is, this.referenceResolver, false);
|
||||||
|
} catch (XMLStreamException e) {
|
||||||
|
throw new EdmException("Failed to load Reference "+reference.getUri()+" parsing failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new EdmException("Failed to load Reference "+reference.getUri()+" loading failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy references
|
||||||
for (EdmxReferenceInclude include : reference.getIncludes()) {
|
for (EdmxReferenceInclude include : reference.getIncludes()) {
|
||||||
this.referenceSchemas.put(include.getNamespace(), provider);
|
this.referenceSchemas.put(include.getNamespace(), provider);
|
||||||
if (include.getAlias() != null) {
|
if (include.getAlias() != null) {
|
||||||
|
|
|
@ -0,0 +1,388 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
OData Version 4.0 Plus Errata 02
|
||||||
|
OASIS Standard incorporating Approved Errata 02
|
||||||
|
30 October 2014
|
||||||
|
Copyright (c) OASIS Open 2014. All Rights Reserved.
|
||||||
|
Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Technical Committee:
|
||||||
|
OASIS Open Data Protocol (OData) TC
|
||||||
|
https://www.oasis-open.org/committees/odata
|
||||||
|
|
||||||
|
Chairs:
|
||||||
|
- Barbara Hartel (barbara.hartel@sap.com), SAP AG
|
||||||
|
- Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
|
||||||
|
|
||||||
|
Editors:
|
||||||
|
- Ralf Handl (ralf.handl@sap.com), SAP AG
|
||||||
|
- Michael Pizzo (mikep@microsoft.com), Microsoft
|
||||||
|
- Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
|
||||||
|
|
||||||
|
Additional artifacts:
|
||||||
|
This CSDL document is one component of a Work Product which consists of:
|
||||||
|
- OData Version 4.0 Part 1: Protocol
|
||||||
|
- OData Version 4.0 Part 2: URL Conventions
|
||||||
|
- OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
|
||||||
|
- OData ABNF Construction Rules Version 4.0
|
||||||
|
- OData ABNF Test Cases
|
||||||
|
- OData Core Vocabulary
|
||||||
|
- OData Capabilities Vocabulary (this document)
|
||||||
|
- OData Measures Vocabulary
|
||||||
|
- OData Metadata Service Entity Model
|
||||||
|
- OData EDMX XML Schema
|
||||||
|
- OData EDM XML Schema
|
||||||
|
|
||||||
|
Related work:
|
||||||
|
This work product is related to the following two Work Products, each of
|
||||||
|
which define alternate formats for OData payloads
|
||||||
|
- OData Atom Format Version 4.0
|
||||||
|
- OData JSON Format Version 4.0
|
||||||
|
This specification replaces or supersedes:
|
||||||
|
- None
|
||||||
|
|
||||||
|
Declared XML namespaces:
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edmx
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edm
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
The Open Data Protocol (OData) enables the creation of REST-based data
|
||||||
|
services, which allow resources, identified using Uniform Resource
|
||||||
|
Identifiers (URLs) and defined in a data model, to be published and
|
||||||
|
edited by Web clients using simple HTTP messages. This document defines
|
||||||
|
the URL syntax for requests and the serialization format for primitive
|
||||||
|
literals in request and response payloads.
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
This document contains terms describing capabilities of an OData service.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
|
||||||
|
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
|
||||||
|
<edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
|
||||||
|
</edmx:Reference>
|
||||||
|
<edmx:DataServices>
|
||||||
|
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Capabilities.V1" Alias="Capabilities">
|
||||||
|
<Annotation Term="Core.Description">
|
||||||
|
<String>
|
||||||
|
The Capabilities vocabulary aims to provide a way for service authors to describe
|
||||||
|
certain capabilities of an OData Service.
|
||||||
|
</String>
|
||||||
|
</Annotation>
|
||||||
|
<Annotation Term="Core.LongDescription">
|
||||||
|
<String>
|
||||||
|
There are some capabilities which are strongly recommended for services to support even
|
||||||
|
though they are optional. Support for $top and $skip is a good example as
|
||||||
|
supporting these query options helps with performance of a service and are essential. Such
|
||||||
|
capabilities are assumed to be default capabilities of an OData service even in
|
||||||
|
the case that a capabilities annotation doesn’t exist. Capabilities annotations are
|
||||||
|
mainly expected to be used to explicitly specify that a service doesn’t support such
|
||||||
|
capabilities. Capabilities annotations can as well be used to declaratively
|
||||||
|
specify the support of such capabilities.
|
||||||
|
|
||||||
|
On the other hand, there are some capabilities that a service may choose to support or
|
||||||
|
not support and in varying degrees. $filter and $orderby are such good examples.
|
||||||
|
This vocabulary aims to define terms to specify support or no support for such
|
||||||
|
capabilities.
|
||||||
|
|
||||||
|
A service is assumed to support by default the following capabilities even though an
|
||||||
|
annotation doesn’t exist:
|
||||||
|
- Countability ($count)
|
||||||
|
- Client pageability ($top, $skip)
|
||||||
|
- Expandability ($expand)
|
||||||
|
- Indexability by key
|
||||||
|
- Batch support ($batch)
|
||||||
|
- Navigability of navigation properties
|
||||||
|
|
||||||
|
A service is expected to support the following capabilities. If not supported, the
|
||||||
|
service is expected to call out the restrictions using annotations:
|
||||||
|
- Filterability ($filter)
|
||||||
|
- Sortability ($orderby)
|
||||||
|
- Queryability of top level entity sets
|
||||||
|
- Query functions
|
||||||
|
|
||||||
|
A client cannot assume that a service supports certain capabilities. A client can try, but
|
||||||
|
it needs to be prepared to handle an error in case the following capabilities are not
|
||||||
|
supported:
|
||||||
|
- Insertability
|
||||||
|
- Updatability
|
||||||
|
- Deletability
|
||||||
|
</String>
|
||||||
|
</Annotation>
|
||||||
|
|
||||||
|
<!-- Conformance Level -->
|
||||||
|
|
||||||
|
<Term Name="ConformanceLevel" Type="Capabilities.ConformanceLevelType" AppliesTo="EntityContainer" />
|
||||||
|
<EnumType Name="ConformanceLevelType">
|
||||||
|
<Member Name="Minimal" />
|
||||||
|
<Member Name="Intermediate" />
|
||||||
|
<Member Name="Advanced" />
|
||||||
|
</EnumType>
|
||||||
|
|
||||||
|
<!-- Request Capabilities -->
|
||||||
|
|
||||||
|
<Term Name="SupportedFormats" Type="Collection(Edm.String)">
|
||||||
|
<Annotation Term="Core.Description" String="Media types of supported formats, including format parameters" />
|
||||||
|
<Annotation Term="Core.IsMediaType" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="AcceptableEncodings" Type="Collection(Edm.String)" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="List of acceptable compression methods for ($batch) requests, e.g. gzip" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<!-- Supported Preferences -->
|
||||||
|
|
||||||
|
<Term Name="AsynchronousRequestsSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Service supports the asynchronous request preference" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="BatchContinueOnErrorSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Service supports the continue on error preference" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="IsolationSupported" Type="Capabilities.IsolationLevel" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Supported odata.isolation levels" />
|
||||||
|
</Term>
|
||||||
|
<EnumType Name="IsolationLevel" IsFlags="true">
|
||||||
|
<Member Name="Snapshot" Value="1" />
|
||||||
|
</EnumType>
|
||||||
|
|
||||||
|
<Term Name="CallbackSupported" Type="Capabilities.CallbackType" AppliesTo="EntityContainer EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Supports callbacks for the specified protocols" />
|
||||||
|
</Term>
|
||||||
|
<Term Name="CrossJoinSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Supports cross joins for the entity sets in this container" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="CallbackType">
|
||||||
|
<Property Name="CallbackProtocols" Type="Collection(Capabilities.CallbackProtocol)" />
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="A non-empty collection lists the full set of supported protocols. A empty collection means 'only HTTP is supported'" />
|
||||||
|
</ComplexType>
|
||||||
|
<ComplexType Name="CallbackProtocol">
|
||||||
|
<Property Name="Id" Type="Edm.String">
|
||||||
|
<Annotation Term="Core.Description" String="Protcol Identifier" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="UrlTemplate" Type="Edm.String">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="URL Template including parameters. Parameters are enclosed in curly braces {} as defined in RFC6570" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="DocumentationUrl" Type="Edm.String" Nullable="true">
|
||||||
|
<Annotation Term="Core.Description" String="Human readable description of the meaning of the URL Template parameters" />
|
||||||
|
<Annotation Term="Core.IsURL" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="ChangeTracking" Type="Capabilities.ChangeTrackingType" AppliesTo="EntityContainer EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Change tracking capabilities of this service or entity set" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="ChangeTrackingType">
|
||||||
|
<Property Name="Supported" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="This entity set supports the odata.track-changes preference" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="FilterableProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="Change tracking supports filters on these properties" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="ExpandableProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="Change tracking supports these properties expanded" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<!--Query Capabilities -->
|
||||||
|
|
||||||
|
<Term Name="CountRestrictions" Type="Capabilities.CountRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on /$count path suffix and $count=true system query option" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="CountRestrictionsType">
|
||||||
|
<Property Name="Countable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="Entities can be counted" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonCountableProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These collection properties do not allow /$count segments" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonCountableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These navigation properties do not allow /$count segments" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="NavigationRestrictions" Type="Capabilities.NavigationRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on navigating properties according to OData URL conventions" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="NavigationRestrictionsType">
|
||||||
|
<Property Name="Navigability" Type="Capabilities.NavigationType">
|
||||||
|
<Annotation Term="Core.Description" String="Supported Navigability" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="RestrictedProperties" Type="Collection(Capabilities.NavigationPropertyRestriction)" />
|
||||||
|
</ComplexType>
|
||||||
|
<ComplexType Name="NavigationPropertyRestriction">
|
||||||
|
<Property Name="NavigationProperty" Type="Edm.NavigationPropertyPath">
|
||||||
|
<Annotation Term="Core.Description" String="Navigation properties can be navigated" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="Navigability" Type="Capabilities.NavigationType">
|
||||||
|
<Annotation Term="Core.Description" String="Navigation properties can be navigated to this level" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
<EnumType Name="NavigationType">
|
||||||
|
<Member Name="Recursive">
|
||||||
|
<Annotation Term="Core.Description" String="Navigation properties can be recursively navigated" />
|
||||||
|
</Member>
|
||||||
|
<Member Name="Single">
|
||||||
|
<Annotation Term="Core.Description" String="Navigation properties can be navigated to a single level" />
|
||||||
|
</Member>
|
||||||
|
<Member Name="None">
|
||||||
|
<Annotation Term="Core.Description" String="Navigation properties are not navigable" />
|
||||||
|
</Member>
|
||||||
|
</EnumType>
|
||||||
|
|
||||||
|
<Term Name="IndexableByKey" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Supports key values according to OData URL conventions" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="TopSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Supports $top" />
|
||||||
|
</Term>
|
||||||
|
<Term Name="SkipSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Supports $skip" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="BatchSupported" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Supports $batch requests" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="FilterFunctions" Type="Collection(Edm.String)" AppliesTo="EntityContainer EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="List of functions supported in $filter" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="FilterRestrictions" Type="Capabilities.FilterRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on $filter expressions" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="FilterRestrictionsType">
|
||||||
|
<Property Name="Filterable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="$filter is supported" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="RequiresFilter" Type="Edm.Boolean" Nullable="true">
|
||||||
|
<Annotation Term="Core.Description" String="$filter is required" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="RequiredProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="These properties must be specified in the $filter clause (properties of derived types are not allowed here)" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonFilterableProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These properties cannot be used in $filter expressions" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="SortRestrictions" Type="Capabilities.SortRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on $orderby expressions" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="SortRestrictionsType">
|
||||||
|
<Property Name="Sortable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="$orderby is supported" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="AscendingOnlyProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These properties can only be used for sorting in Ascending order" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="DescendingOnlyProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These properties can only be used for sorting in Descending order" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonSortableProperties" Type="Collection(Edm.PropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These properties cannot be used in $orderby expressions" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="ExpandRestrictions" Type="Capabilities.ExpandRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on $expand expressions" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="ExpandRestrictionsType">
|
||||||
|
<Property Name="Expandable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="$expand is supported" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonExpandableProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These properties cannot be used in $expand expressions" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="SearchRestrictions" Type="Capabilities.SearchRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on $search expressions" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="SearchRestrictionsType">
|
||||||
|
<Property Name="Searchable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="$search is supported" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="UnsupportedExpressions" Type="Capabilities.SearchExpressions" DefaultValue="none">
|
||||||
|
<Annotation Term="Core.Description" String="Expressions supported in $search" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
<EnumType Name="SearchExpressions" IsFlags="true">
|
||||||
|
<Member Name="none" Value="0" />
|
||||||
|
<Member Name="AND" Value="1" />
|
||||||
|
<Member Name="OR" Value="2" />
|
||||||
|
<Member Name="NOT" Value="4" />
|
||||||
|
<Member Name="phrase" Value="8" />
|
||||||
|
<Member Name="group" Value="16" />
|
||||||
|
</EnumType>
|
||||||
|
|
||||||
|
<!-- Data Modification Capabilities -->
|
||||||
|
|
||||||
|
<Term Name="InsertRestrictions" Type="Capabilities.InsertRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on insert operations" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="InsertRestrictionsType">
|
||||||
|
<Property Name="Insertable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="Entities can be inserted" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonInsertableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These navigation properties do not allow deep inserts" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="UpdateRestrictions" Type="Capabilities.UpdateRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on update operations" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="UpdateRestrictionsType">
|
||||||
|
<Property Name="Updatable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="Entities can be updated" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonUpdatableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These navigation properties do not allow rebinding" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
<Term Name="DeleteRestrictions" Type="Capabilities.DeleteRestrictionsType" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description" String="Restrictions on delete operations" />
|
||||||
|
</Term>
|
||||||
|
<ComplexType Name="DeleteRestrictionsType">
|
||||||
|
<Property Name="Deletable" Type="Edm.Boolean" DefaultValue="true">
|
||||||
|
<Annotation Term="Core.Description" String="Entities can be deleted" />
|
||||||
|
</Property>
|
||||||
|
<Property Name="NonDeletableNavigationProperties" Type="Collection(Edm.NavigationPropertyPath)">
|
||||||
|
<Annotation Term="Core.Description" String="These navigation properties do not allow DeleteLink requests" />
|
||||||
|
</Property>
|
||||||
|
</ComplexType>
|
||||||
|
|
||||||
|
</Schema>
|
||||||
|
</edmx:DataServices>
|
||||||
|
</edmx:Edmx>
|
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
OData Version 4.0 Plus Errata 02
|
||||||
|
OASIS Standard incorporating Approved Errata 02
|
||||||
|
30 October 2014
|
||||||
|
Copyright (c) OASIS Open 2014. All Rights Reserved.
|
||||||
|
Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Technical Committee:
|
||||||
|
OASIS Open Data Protocol (OData) TC
|
||||||
|
https://www.oasis-open.org/committees/odata
|
||||||
|
|
||||||
|
Chairs:
|
||||||
|
- Barbara Hartel (barbara.hartel@sap.com), SAP AG
|
||||||
|
- Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
|
||||||
|
|
||||||
|
Editors:
|
||||||
|
- Ralf Handl (ralf.handl@sap.com), SAP AG
|
||||||
|
- Michael Pizzo (mikep@microsoft.com), Microsoft
|
||||||
|
- Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
|
||||||
|
|
||||||
|
Additional artifacts:
|
||||||
|
This CSDL document is one component of a Work Product which consists of:
|
||||||
|
- OData Version 4.0 Part 1: Protocol
|
||||||
|
- OData Version 4.0 Part 2: URL Conventions
|
||||||
|
- OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
|
||||||
|
- OData ABNF Construction Rules Version 4.0
|
||||||
|
- OData ABNF Test Cases
|
||||||
|
- OData Core Vocabulary (this document)
|
||||||
|
- OData Capabilities Vocabulary
|
||||||
|
- OData Measures Vocabulary
|
||||||
|
- OData Metadata Service Entity Model
|
||||||
|
- OData EDMX XML Schema
|
||||||
|
- OData EDM XML Schema
|
||||||
|
|
||||||
|
Related work:
|
||||||
|
This work product is related to the following two Work Products, each of
|
||||||
|
which define alternate formats for OData payloads
|
||||||
|
- OData Atom Format Version 4.0
|
||||||
|
- OData JSON Format Version 4.0
|
||||||
|
This specification replaces or supersedes:
|
||||||
|
- None
|
||||||
|
|
||||||
|
Declared XML namespaces:
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edmx
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edm
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
The Open Data Protocol (OData) enables the creation of REST-based data
|
||||||
|
services, which allow resources, identified using Uniform Resource
|
||||||
|
Identifiers (URLs) and defined in a data model, to be published and
|
||||||
|
edited by Web clients using simple HTTP messages. This document defines
|
||||||
|
the URL syntax for requests and the serialization format for primitive
|
||||||
|
literals in request and response payloads.
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
This document contains Core terms needed to write vocabularies.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
|
||||||
|
<edmx:DataServices>
|
||||||
|
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Core.V1" Alias="Core">
|
||||||
|
<Annotation Term="Core.Description">
|
||||||
|
<String>Core terms needed to write vocabularies</String>
|
||||||
|
</Annotation>
|
||||||
|
|
||||||
|
<!--Documentation -->
|
||||||
|
|
||||||
|
<Term Name="Description" Type="Edm.String">
|
||||||
|
<Annotation Term="Core.Description" String="A brief description of a model element" />
|
||||||
|
<Annotation Term="Core.IsLanguageDependent" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="LongDescription" Type="Edm.String">
|
||||||
|
<Annotation Term="Core.Description" String="A lengthy description of a model element" />
|
||||||
|
<Annotation Term="Core.IsLanguageDependent" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<!-- Localization -->
|
||||||
|
|
||||||
|
<Term Name="IsLanguageDependent" Type="Core.Tag" DefaultValue="true" AppliesTo="Term Property">
|
||||||
|
<Annotation Term="Core.Description" String="Properties and terms annotated with this term are language-dependent" />
|
||||||
|
<Annotation Term="Core.RequiresType" String="Edm.String" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<!-- Term Restrictions -->
|
||||||
|
|
||||||
|
<TypeDefinition Name="Tag" UnderlyingType="Edm.Boolean">
|
||||||
|
<Annotation Term="Core.Description" String="This is the type to use for all tagging terms" />
|
||||||
|
</TypeDefinition>
|
||||||
|
|
||||||
|
<Term Name="RequiresType" Type="Edm.String" AppliesTo="Term">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="Terms annotated with this term can only be applied to elements that have a type that is identical to or derived from the given type name" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<!--Resource Paths -->
|
||||||
|
|
||||||
|
<Term Name="ResourcePath" Type="Edm.String" AppliesTo="EntitySet Singleton ActionImport FunctionImport">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="Resource path for entity container child, can be relative to xml:base and the request URL" />
|
||||||
|
<Annotation Term="Core.IsUrl" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="DereferenceableIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Entity-ids are URLs that locate the identified entity" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="ConventionalIDs" Type="Core.Tag" DefaultValue="true" AppliesTo="EntityContainer">
|
||||||
|
<Annotation Term="Core.Description" String="Entity-ids follow OData URL conventions" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<!-- Permissions -->
|
||||||
|
|
||||||
|
<Term Name="Permissions" Type="Core.Permission" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description" String="Permissions available for a property.The value of 2 is reserved for future use." />
|
||||||
|
</Term>
|
||||||
|
<EnumType Name="Permission" IsFlags="true">
|
||||||
|
<Member Name="None" Value="0" />
|
||||||
|
<Member Name="Read" Value="1" />
|
||||||
|
<Member Name="ReadWrite" Value="3" />
|
||||||
|
</EnumType>
|
||||||
|
|
||||||
|
<!-- Metadata Extensions -->
|
||||||
|
|
||||||
|
<Term Name="Immutable" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="A value for this non-key property can be provided on insert and remains unchanged on update" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="Computed" Type="Core.Tag" DefaultValue="true" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description" String="A value for this property is generated on both insert and update" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="IsURL" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
|
||||||
|
<Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid URL" />
|
||||||
|
<Annotation Term="Core.RequiresType" String="Edm.String" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="AcceptableMediaTypes" Type="Collection(Edm.String)" AppliesTo="EntityType Property">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="Lists the MIME types acceptable for the annotated entity type marked with HasStream="true" or the annotated stream property" />
|
||||||
|
<Annotation Term="Core.IsMediaType" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="MediaType" Type="Edm.String" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.IsMediaType" />
|
||||||
|
<Annotation Term="Core.RequiresType" String="Edm.Binary" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="IsMediaType" Type="Core.Tag" DefaultValue="true" AppliesTo="Property Term">
|
||||||
|
<Annotation Term="Core.Description" String="Properties and terms annotated with this term MUST contain a valid MIME type" />
|
||||||
|
<Annotation Term="Core.RequiresType" String="Edm.String" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="OptimisticConcurrency" Type="Collection(Edm.PropertyPath)" AppliesTo="EntitySet">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="Data modification requires the use of Etags. A non-empty collection contains the set of properties that are used to compute the ETag" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
</Schema>
|
||||||
|
</edmx:DataServices>
|
||||||
|
</edmx:Edmx>
|
|
@ -0,0 +1,110 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
OData Version 4.0 Plus Errata 02
|
||||||
|
OASIS Standard incorporating Approved Errata 02
|
||||||
|
30 October 2014
|
||||||
|
Copyright (c) OASIS Open 2014. All Rights Reserved.
|
||||||
|
Source: http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/vocabularies/
|
||||||
|
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Technical Committee:
|
||||||
|
OASIS Open Data Protocol (OData) TC
|
||||||
|
https://www.oasis-open.org/committees/odata
|
||||||
|
|
||||||
|
Chairs:
|
||||||
|
- Barbara Hartel (barbara.hartel@sap.com), SAP AG
|
||||||
|
- Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
|
||||||
|
|
||||||
|
Editors:
|
||||||
|
- Ralf Handl (ralf.handl@sap.com), SAP AG
|
||||||
|
- Michael Pizzo (mikep@microsoft.com), Microsoft
|
||||||
|
- Martin Zurmuehl (martin.zurmuehl@sap.com), SAP AG
|
||||||
|
|
||||||
|
Additional artifacts:
|
||||||
|
This CSDL document is one component of a Work Product which consists of:
|
||||||
|
- OData Version 4.0 Part 1: Protocol
|
||||||
|
- OData Version 4.0 Part 2: URL Conventions
|
||||||
|
- OData Version 4.0 Part 3: Common Schema Definition Language (CSDL)
|
||||||
|
- OData ABNF Construction Rules Version 4.0
|
||||||
|
- OData ABNF Test Cases
|
||||||
|
- OData Core Vocabulary
|
||||||
|
- OData Capabilities Vocabulary
|
||||||
|
- OData Measures Vocabulary (this document)
|
||||||
|
- OData Metadata Service Entity Model
|
||||||
|
- OData EDMX XML Schema
|
||||||
|
- OData EDM XML Schema
|
||||||
|
|
||||||
|
Related work:
|
||||||
|
This work product is related to the following two Work Products, each of
|
||||||
|
which define alternate formats for OData payloads
|
||||||
|
- OData Atom Format Version 4.0
|
||||||
|
- OData JSON Format Version 4.0
|
||||||
|
This specification replaces or supersedes:
|
||||||
|
- None
|
||||||
|
|
||||||
|
Declared XML namespaces:
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edmx
|
||||||
|
- http://docs.oasis-open.org/odata/ns/edm
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
The Open Data Protocol (OData) enables the creation of REST-based data
|
||||||
|
services, which allow resources, identified using Uniform Resource
|
||||||
|
Identifiers (URLs) and defined in a data model, to be published and
|
||||||
|
edited by Web clients using simple HTTP messages. This document defines
|
||||||
|
the URL syntax for requests and the serialization format for primitive
|
||||||
|
literals in request and response payloads.
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
This document contains terms describing monetary amounts and measured quantities.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
|
||||||
|
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
|
||||||
|
<edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
|
||||||
|
</edmx:Reference>
|
||||||
|
<edmx:DataServices>
|
||||||
|
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Org.OData.Measures.V1" Alias="Measures">
|
||||||
|
<Annotation Term="Core.Description">
|
||||||
|
<String>Terms describing monetary amounts and measured quantities</String>
|
||||||
|
</Annotation>
|
||||||
|
|
||||||
|
<Term Name="ISOCurrency" Type="Edm.String" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description" String="The currency for this monetary amount as an ISO 4217 currency code" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="Scale" Type="Edm.Byte" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description"
|
||||||
|
String="The number of significant decimal places in the scale part (less than or equal to the number declared in the Scale facet)" />
|
||||||
|
<Annotation Term="Core.RequiresType" String="Edm.Decimal" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
<Term Name="Unit" Type="Edm.String" AppliesTo="Property">
|
||||||
|
<Annotation Term="Core.Description" String="The unit of measure for this measured quantity, e.g. cm for centimeters or % for percentages" />
|
||||||
|
</Term>
|
||||||
|
|
||||||
|
</Schema>
|
||||||
|
</edmx:DataServices>
|
||||||
|
</edmx:Edmx>
|
|
@ -51,7 +51,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class MetadataParserAnnotationsTest {
|
public class MetadataParserAnnotationsTest {
|
||||||
final String NS = "Org.OData.Core.V1";
|
final String NS = "Org.OData.AnnoatationTest";
|
||||||
final FullQualifiedName NSF = new FullQualifiedName(NS);
|
final FullQualifiedName NSF = new FullQualifiedName(NS);
|
||||||
|
|
||||||
CsdlEdmProvider provider = null;
|
CsdlEdmProvider provider = null;
|
||||||
|
@ -59,7 +59,8 @@ public class MetadataParserAnnotationsTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MetadataParser parser = new MetadataParser();
|
MetadataParser parser = new MetadataParser();
|
||||||
parser.setParseAnnotations(true);
|
parser.parseAnnotations(true);
|
||||||
|
parser.loadCoreVocabularies(true);
|
||||||
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/annotations.xml"));
|
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/annotations.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,4 +206,10 @@ public class MetadataParserAnnotationsTest {
|
||||||
CsdlTerm term = this.provider.getTerm(new FullQualifiedName(NS, "IsURI"));
|
CsdlTerm term = this.provider.getTerm(new FullQualifiedName(NS, "IsURI"));
|
||||||
assertEquals(Arrays.asList("Property", "PropertyPath"), term.getAppliesTo());
|
assertEquals(Arrays.asList("Property", "PropertyPath"), term.getAppliesTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkCoreVocabularies() throws ODataException {
|
||||||
|
CsdlTerm term = this.provider.getTerm(new FullQualifiedName("Org.OData.Core.V1", "Description"));
|
||||||
|
assertEquals("Edm.String", term.getType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class MetadataParserTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MetadataParser parser = new MetadataParser();
|
MetadataParser parser = new MetadataParser();
|
||||||
parser.setParseAnnotations(true);
|
parser.parseAnnotations(true);
|
||||||
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
|
provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class TripPinServlet extends HttpServlet {
|
||||||
ServiceMetadata metadata = null;
|
ServiceMetadata metadata = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
parser.parseAnnotations(true);
|
||||||
|
parser.loadCoreVocabularies(true);
|
||||||
metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
|
metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
|
||||||
} catch (XMLStreamException e) {
|
} catch (XMLStreamException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
Version="4.0">
|
Version="4.0">
|
||||||
<edmx:DataServices>
|
<edmx:DataServices>
|
||||||
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
|
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
|
||||||
Namespace="Org.OData.Core.V1" Alias="Core">
|
Namespace="Org.OData.AnnoatationTest" Alias="test">
|
||||||
|
|
||||||
<Annotation Term="Core.Description">
|
<Annotation Term="Core.Description">
|
||||||
<String>Core terms needed to write vocabularies</String>
|
<String>Core terms needed to write vocabularies</String>
|
||||||
|
|
Loading…
Reference in New Issue