[OLINGO-205, OLINGO-200] provided atom v4 deserialization for entity type/set + entity set request

This commit is contained in:
fmartelli 2014-03-24 09:50:23 +01:00
parent 4780fc513b
commit 9aefb95905
51 changed files with 2151 additions and 1095 deletions

View File

@ -19,8 +19,8 @@
package org.apache.olingo.fit;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.XMLUtilities;
import org.apache.olingo.fit.utils.JSONUtilities;
import org.apache.olingo.fit.utils.AbstractXMLUtilities;
import org.apache.olingo.fit.utils.AbstractJSONUtilities;
import org.apache.olingo.fit.utils.ODataVersion;
import org.apache.olingo.fit.utils.FSManager;
@ -70,13 +70,18 @@ public abstract class AbstractServices {
private static Set<ODataVersion> initialized = EnumSet.noneOf(ODataVersion.class);
protected abstract ODataVersion getVersion();
protected final XMLUtilities xml;
protected final AbstractXMLUtilities xml;
protected final JSONUtilities json;
protected final AbstractJSONUtilities json;
public AbstractServices() throws Exception {
this.xml = new XMLUtilities(getVersion());
this.json = new JSONUtilities(getVersion());
if (ODataVersion.v3 == getVersion()) {
this.xml = new org.apache.olingo.fit.utils.v3.XMLUtilities();
this.json = new org.apache.olingo.fit.utils.v3.JSONUtilities();
} else {
this.xml = new org.apache.olingo.fit.utils.v4.XMLUtilities();
this.json = new org.apache.olingo.fit.utils.v4.JSONUtilities();
}
if (!initialized.contains(getVersion())) {
xml.retrieveLinkInfoFromMetadata();
@ -135,7 +140,7 @@ public abstract class AbstractServices {
return xml.
createResponse(FSManager.instance(getVersion()).readFile(filename, Accept.XML), null, Accept.XML);
} catch (Exception e) {
return xml.createFaultResponse(Accept.XML.toString(), e);
return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
}
}
@ -547,7 +552,7 @@ public abstract class AbstractServices {
return xml.createResponse(null, null, null, Response.Status.NO_CONTENT);
} catch (Exception e) {
return xml.createFaultResponse(Accept.XML.toString(), e);
return xml.createFaultResponse(Accept.XML.toString(getVersion()), e);
}
}
@ -749,7 +754,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
return xml.createFaultResponse(Accept.JSON.toString(), e);
return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
}
}
@ -775,7 +780,7 @@ public abstract class AbstractServices {
@QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
final String changes) {
if (xml.isMediaContent(entitySetName + "/" + path)) {
return replaceMediaProperty(prefer, entitySetName, entityId, path, format, changes);
return replaceMediaProperty(prefer, entitySetName, entityId, path, changes);
} else {
return replaceProperty(accept, prefer, entitySetName, entityId, path, format, changes, false);
}
@ -786,7 +791,6 @@ public abstract class AbstractServices {
final String entitySetName,
final String entityId,
final String path,
final String format,
final String value) {
try {
final AbstractUtilities utils = getUtilities(null);
@ -809,7 +813,7 @@ public abstract class AbstractServices {
} catch (Exception e) {
LOG.error("Error retrieving entity", e);
return xml.createFaultResponse(Accept.JSON.toString(), e);
return xml.createFaultResponse(Accept.JSON.toString(getVersion()), e);
}
}

View File

@ -41,9 +41,9 @@ import javax.ws.rs.NotFoundException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
public class JSONUtilities extends AbstractUtilities {
public abstract class AbstractJSONUtilities extends AbstractUtilities {
public JSONUtilities(final ODataVersion version) throws Exception {
public AbstractJSONUtilities(final ODataVersion version) throws Exception {
super(version);
}

View File

@ -384,7 +384,7 @@ public abstract class AbstractUtilities {
}
if (accept != null) {
builder.header("Content-Type", accept.toString());
builder.header("Content-Type", accept.toString(version));
} else {
builder.header("Content-Type", "*/*");
}
@ -423,7 +423,6 @@ public abstract class AbstractUtilities {
public Response createFaultResponse(final String accept, final Exception e) {
LOG.debug("Create fault response about .... ", e);
e.printStackTrace();
final Response.ResponseBuilder builder = Response.serverError();
if (version == ODataVersion.v3) {

View File

@ -55,103 +55,17 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
public class XMLUtilities extends AbstractUtilities {
public abstract class AbstractXMLUtilities extends AbstractUtilities {
protected static XMLInputFactory ifactory = null;
protected static XMLOutputFactory ofactory = null;
public XMLUtilities(final ODataVersion version) throws Exception {
public AbstractXMLUtilities(final ODataVersion version) throws Exception {
super(version);
}
public void retrieveLinkInfoFromMetadata() throws Exception {
final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
Commons.linkInfo.put(version, metadataLinkInfo);
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
final XMLEventReader reader = getEventReader(metadata);
int initialDepth = 0;
try {
while (true) {
Map.Entry<Integer, XmlElement> entityType =
extractElement(reader, null, Collections.<String>singletonList("EntityType"),
null, false, initialDepth, 4, 4);
initialDepth = entityType.getKey();
final String entitySetName =
entityType.getValue().getStart().getAttributeByName(new QName("Name")).getValue();
final XMLEventReader entityReader = getEventReader(entityType.getValue().toStream());
int size = 0;
try {
while (true) {
final XmlElement navProperty =
extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
null, false, 0, -1, -1).getValue();
final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
metadataLinkInfo.addLink(
entitySetName,
linkName,
target.getKey(),
target.getValue());
size++;
}
} catch (Exception e) {
} finally {
entityReader.close();
}
if (size == 0) {
metadataLinkInfo.addEntitySet(entitySetName);
}
}
} catch (Exception e) {
} finally {
reader.close();
}
}
private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
throws Exception {
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
XMLEventReader reader = getEventReader(metadata);
final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
final Map.Entry<Integer, XmlElement> association = extractElement(
reader, null, Collections.<String>singletonList("Association"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
"Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
0, 4, 4);
reader.close();
IOUtils.closeQuietly(metadata);
final InputStream associationContent = association.getValue().toStream();
reader = getEventReader(associationContent);
final Map.Entry<Integer, XmlElement> associationEnd = extractElement(
reader, null, Collections.<String>singletonList("End"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
false, 0, -1, -1);
reader.close();
IOUtils.closeQuietly(associationContent);
final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("Type")).getValue();
final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
new QName("Multiplicity")).getValue().equals("*");
return new SimpleEntry<String, Boolean>(target, feed);
}
public abstract void retrieveLinkInfoFromMetadata() throws Exception;
@Override
protected Accept getDefaultFormat() {

View File

@ -28,24 +28,35 @@ public enum Accept {
TEXT(ContentType.TEXT_PLAIN.getMimeType(), ".txt"),
XML(ContentType.APPLICATION_XML.getMimeType(), ".xml"),
ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType(), ".xml"),
JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata", ".full.json"),
JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata", ".full.json"),
JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata", ".full.json");
JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata",
ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal", ".full.json"),
JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata",
ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none", ".full.json"),
JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata",
ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full", ".full.json");
private final String contentType;
private final String contentTypeV3;
private final String contentTypeV4;
private final String fileExtension;
private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
Accept(final String contentType, final String fileExtension) {
this.contentType = contentType;
Accept(final String contentTypeV3, final String fileExtension) {
this.contentTypeV3 = contentTypeV3;
this.contentTypeV4 = contentTypeV3;
this.fileExtension = fileExtension;
}
@Override
public String toString() {
return contentType;
Accept(final String contentTypeV3, final String contentTypeV4, final String fileExtension) {
this.contentTypeV3 = contentTypeV3;
this.contentTypeV4 = contentTypeV4;
this.fileExtension = fileExtension;
}
public String toString(final ODataVersion version) {
return ODataVersion.v3 == version ? contentTypeV3 : contentTypeV4;
}
public String getExtension() {
@ -53,23 +64,30 @@ public enum Accept {
}
public static Accept parse(final String contentType, final ODataVersion version) {
return parse(contentType, version, ODataVersion.v3 == version ? ATOM : JSON_NOMETA);
final Accept def;
if (ODataVersion.v3 == version) {
def = ATOM;
} else {
def = JSON_NOMETA;
}
return parse(contentType, version, def);
}
public static Accept parse(final String contentType, final ODataVersion version, final Accept def) {
if (StringUtils.isBlank(contentType) || allTypesPattern.matcher(contentType).matches()) {
return def;
} else if (JSON_NOMETA.toString().equals(contentType)) {
} else if (JSON_NOMETA.toString(version).equals(contentType)) {
return JSON_NOMETA;
} else if (JSON.toString().equals(contentType) || "application/json".equals(contentType)) {
} else if (JSON.toString(version).equals(contentType) || "application/json".equals(contentType)) {
return JSON;
} else if (JSON_FULLMETA.toString().equals(contentType)) {
} else if (JSON_FULLMETA.toString(version).equals(contentType)) {
return JSON_FULLMETA;
} else if (XML.toString().equals(contentType)) {
} else if (XML.toString(version).equals(contentType)) {
return XML;
} else if (ATOM.toString().equals(contentType)) {
} else if (ATOM.toString(version).equals(contentType)) {
return ATOM;
} else if (TEXT.toString().equals(contentType)) {
} else if (TEXT.toString(version).equals(contentType)) {
return TEXT;
} else {
throw new UnsupportedMediaTypeException("Unsupported media type");

View File

@ -74,6 +74,10 @@ public abstract class Commons {
mediaContent.put("Car/Photo", null);
}
public static Map<ODataVersion, MetadataLinkInfo> getLinkInfo() {
return linkInfo;
}
public static String getEntityURI(final String entitySetName, final String entityKey) {
return entitySetName + "(" + entityKey + ")";
}
@ -230,7 +234,7 @@ public abstract class Commons {
break;
default:
throw new UnsupportedOperationException(target.toString());
throw new UnsupportedOperationException(target.name());
}
for (String field : toBeRemoved) {

View File

@ -0,0 +1,28 @@
/*
* 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.fit.utils.v3;
import org.apache.olingo.fit.utils.ODataVersion;
public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
public JSONUtilities() throws Exception {
super(ODataVersion.v3);
}
}

View File

@ -0,0 +1,191 @@
/*
* 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.fit.utils.v3;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.AbstractMap.SimpleEntry;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.StartElement;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.MetadataLinkInfo;
import org.apache.olingo.fit.utils.ODataVersion;
import org.apache.olingo.fit.utils.XmlElement;
public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
public XMLUtilities() throws Exception {
super(ODataVersion.v3);
}
@Override
public void retrieveLinkInfoFromMetadata() throws Exception {
final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
Commons.getLinkInfo().put(version, metadataLinkInfo);
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
final XMLEventReader reader = getEventReader(metadata);
try {
while (true) {
final Map.Entry<Integer, XmlElement> entitySetElement =
extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
null, false, 0, -1, -1);
retrieveLinks(entitySetElement.getValue(), metadataLinkInfo);
}
} catch (Exception e) {
} finally {
reader.close();
}
}
private void retrieveLinks(final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo)
throws Exception {
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(metadata, bos);
IOUtils.closeQuietly(metadata);
final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
final String entityType = entitySetElement.getStart().getAttributeByName(new QName("EntityType")).getValue().trim();
final Collection<Map.Entry<String, String>> filter = new HashSet<Map.Entry<String, String>>();
filter.add(new SimpleEntry<String, String>(
"Name", entityType.substring(entityType.lastIndexOf(".") + 1, entityType.length())));
filter.add(new SimpleEntry<String, String>("BaseType", entityType));
final XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
final Map.Entry<Integer, XmlElement> entityTypeElement = extractElement(
reader, null, Collections.<String>singletonList("EntityType"), filter, true, 0, -1, -1);
final XMLEventReader entityReader = entityTypeElement.getValue().getContentReader();
int size = 0;
try {
while (true) {
final XmlElement navProperty =
extractElement(entityReader, null, Collections.<String>singletonList("NavigationProperty"),
null, false, 0, -1, -1).getValue();
final String linkName = navProperty.getStart().getAttributeByName(new QName("Name")).getValue();
final Map.Entry<String, Boolean> target = getTargetInfo(navProperty.getStart(), linkName);
metadataLinkInfo.addLink(
entitySetName,
linkName,
target.getKey(),
target.getValue());
size++;
}
} catch (Exception e) {
} finally {
entityReader.close();
}
if (size == 0) {
metadataLinkInfo.addEntitySet(entitySetName);
}
}
private Map.Entry<String, Boolean> getTargetInfo(final StartElement element, final String linkName)
throws Exception {
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(metadata, bos);
IOUtils.closeQuietly(metadata);
// ------------------------------------
// Retrieve association
// ------------------------------------
XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
final String associationName = element.getAttributeByName(new QName("Relationship")).getValue();
final Map.Entry<Integer, XmlElement> association = extractElement(
reader, null, Collections.<String>singletonList("Association"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
"Name", associationName.substring(associationName.lastIndexOf(".") + 1))), false,
0, 4, 4);
reader.close();
// ------------------------------------
// ------------------------------------
// check for feed or not from Association role
// ------------------------------------
InputStream associationContent = association.getValue().toStream();
reader = getEventReader(associationContent);
Map.Entry<Integer, XmlElement> associationEnd = extractElement(
reader, null, Collections.<String>singletonList("End"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
false, 0, -1, -1);
reader.close();
IOUtils.closeQuietly(associationContent);
final boolean feed = associationEnd.getValue().getStart().getAttributeByName(
new QName("Multiplicity")).getValue().equals("*");
// ------------------------------------
// ------------------------------------
// Retrieve target association set name
// ------------------------------------
reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
final Map.Entry<Integer, XmlElement> associationSet = extractElement(
reader, null, Collections.<String>singletonList("AssociationSet"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>(
"Association", associationName)), false, 0, -1, -1);
reader.close();
associationContent = associationSet.getValue().toStream();
reader = getEventReader(associationContent);
associationEnd = extractElement(
reader, null, Collections.<String>singletonList("End"),
Collections.<Map.Entry<String, String>>singleton(new SimpleEntry<String, String>("Role", linkName)),
false, 0, -1, -1);
reader.close();
IOUtils.closeQuietly(associationContent);
final String target = associationEnd.getValue().getStart().getAttributeByName(new QName("EntitySet")).getValue();
// ------------------------------------
return new SimpleEntry<String, Boolean>(target, feed);
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.fit.utils.v4;
import org.apache.olingo.fit.utils.ODataVersion;
public class JSONUtilities extends org.apache.olingo.fit.utils.AbstractJSONUtilities {
public JSONUtilities() throws Exception {
super(ODataVersion.v4);
}
}

View File

@ -0,0 +1,142 @@
/*
* 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.fit.utils.v4;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.Commons;
import org.apache.olingo.fit.utils.Constants;
import org.apache.olingo.fit.utils.MetadataLinkInfo;
import org.apache.olingo.fit.utils.ODataVersion;
import org.apache.olingo.fit.utils.XmlElement;
public class XMLUtilities extends org.apache.olingo.fit.utils.AbstractXMLUtilities {
public XMLUtilities() throws Exception {
super(ODataVersion.v4);
}
@Override
public void retrieveLinkInfoFromMetadata() throws Exception {
final MetadataLinkInfo metadataLinkInfo = new MetadataLinkInfo();
Commons.getLinkInfo().put(version, metadataLinkInfo);
final InputStream metadata = fsManager.readFile(Constants.METADATA, Accept.XML);
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(metadata, bos);
IOUtils.closeQuietly(metadata);
XMLEventReader reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
final Set<String> singletons = new HashSet<String>();
try {
while (true) {
final Map.Entry<Integer, XmlElement> entitySetElement =
extractElement(reader, null, Collections.<String>singletonList("Singleton"),
null, false, 0, -1, -1);
final String entitySetName =
entitySetElement.getValue().getStart().getAttributeByName(new QName("Name")).getValue().trim();
singletons.add(entitySetName);
}
} catch (Exception e) {
} finally {
reader.close();
}
reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
try {
while (true) {
final Map.Entry<Integer, XmlElement> entitySetElement =
extractElement(reader, null, Collections.<String>singletonList("EntitySet"),
null, false, 0, -1, -1);
retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
}
} catch (Exception e) {
} finally {
reader.close();
}
reader = getEventReader(new ByteArrayInputStream(bos.toByteArray()));
try {
while (true) {
final Map.Entry<Integer, XmlElement> entitySetElement =
extractElement(reader, null, Collections.<String>singletonList("Singleton"),
null, false, 0, -1, -1);
retrieveLinks(entitySetElement.getValue(), metadataLinkInfo, singletons);
}
} catch (Exception e) {
} finally {
reader.close();
}
}
private void retrieveLinks(
final XmlElement entitySetElement, final MetadataLinkInfo metadataLinkInfo, final Set<String> singletons)
throws Exception {
final String entitySetName = entitySetElement.getStart().getAttributeByName(new QName("Name")).getValue().trim();
final XMLEventReader entityReader = entitySetElement.getContentReader();
int size = 0;
try {
while (true) {
final XmlElement navProperty =
extractElement(entityReader, null, Collections.<String>singletonList("NavigationPropertyBinding"),
null, false, 0, -1, -1).getValue();
final String linkName = navProperty.getStart().getAttributeByName(new QName("Path")).getValue();
final String target = navProperty.getStart().getAttributeByName(new QName("Target")).getValue();
final boolean feed = !singletons.contains(target);
metadataLinkInfo.addLink(
entitySetName,
linkName,
target,
feed);
size++;
}
} catch (Exception e) {
} finally {
entityReader.close();
}
if (size == 0) {
metadataLinkInfo.addEntitySet(entitySetName);
}
}
}

View File

@ -0,0 +1,332 @@
{
"@odata.context": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People",
"value":
[
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)",
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
"PersonID": 1,
"FirstName": "Bob",
"LastName": "Cat",
"MiddleName": null,
"HomeAddress":
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
"Street": "1 Microsoft Way",
"City": "London",
"PostalCode": "98052",
"FamilyName": "Cats"
},
"Home@odata.type": "#GeographyPoint",
"Home":
{
"type": "Point",
"coordinates":
[
23.1,
32.1
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Numbers@odata.type": "#Collection(String)",
"Numbers":
[
"111-111-1111"
],
"Emails@odata.type": "#Collection(String)",
"Emails":
[
"abc@abc.com"
],
"City": "London",
"Birthday@odata.type": "#DateTimeOffset",
"Birthday": "1957-04-03T00:00:00Z",
"TimeBetweenLastTwoOrders@odata.type": "#Duration",
"TimeBetweenLastTwoOrders": "PT0.0000001S",
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
"Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
"Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
"Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
"Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
},
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
},
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Customer",
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)",
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer",
"PersonID": 2,
"FirstName": "Jill",
"LastName": "Jones",
"MiddleName": null,
"HomeAddress": null,
"Home@odata.type": "#GeographyPoint",
"Home":
{
"type": "Point",
"coordinates":
[
161.8,
15
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Numbers@odata.type": "#Collection(String)",
"Numbers":
[
],
"Emails@odata.type": "#Collection(String)",
"Emails":
[
],
"City": "Sydney",
"Birthday@odata.type": "#DateTimeOffset",
"Birthday": "1983-01-15T00:00:00Z",
"TimeBetweenLastTwoOrders@odata.type": "#Duration",
"TimeBetweenLastTwoOrders": "PT0.0000002S",
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent/$ref",
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent",
"Orders@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders/$ref",
"Orders@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders",
"Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company/$ref",
"Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company",
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
},
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
},
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)",
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
"PersonID": 3,
"FirstName": "Jacob",
"LastName": "Zip",
"MiddleName": null,
"HomeAddress":
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Address",
"Street": "1 Microsoft Way",
"City": "Sydney",
"PostalCode": "98052"
},
"Home@odata.type": "#GeographyPoint",
"Home":
{
"type": "Point",
"coordinates":
[
161.8,
15
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Numbers@odata.type": "#Collection(String)",
"Numbers":
[
"333-333-3333"
],
"Emails@odata.type": "#Collection(String)",
"Emails":
[
null
],
"DateHired@odata.type": "#DateTimeOffset",
"DateHired": "2010-12-13T00:00:00Z",
"Office@odata.type": "#GeographyPoint",
"Office":
{
"type": "Point",
"coordinates":
[
162,
15
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
"Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
"Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
},
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
},
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Employee",
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)",
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee",
"PersonID": 4,
"FirstName": "Elmo",
"LastName": "Rogers",
"MiddleName": null,
"HomeAddress": null,
"Home@odata.type": "#GeographyPoint",
"Home":
{
"type": "Point",
"coordinates":
[
-61.8,
-15
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Numbers@odata.type": "#Collection(String)",
"Numbers":
[
"444-444-4444",
"555-555-5555",
"666-666-6666"
],
"Emails@odata.type": "#Collection(String)",
"Emails":
[
"def@def.org",
"lmn@lmn.com"
],
"DateHired@odata.type": "#DateTimeOffset",
"DateHired": "2008-03-27T00:00:00Z",
"Office@odata.type": "#GeographyPoint",
"Office":
{
"type": "Point",
"coordinates":
[
-62,
-15
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent/$ref",
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent",
"Company@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company/$ref",
"Company@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company",
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
},
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
},
{
"@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Person",
"@odata.id": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
"@odata.editLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)",
"PersonID": 5,
"FirstName": "Peter",
"LastName": "Bee",
"MiddleName": null,
"HomeAddress": null,
"Home@odata.type": "#GeographyPoint",
"Home":
{
"type": "Point",
"coordinates":
[
-261.8,
-16
],
"crs":
{
"type": "name",
"properties":
{
"name": "EPSG:4326"
}
}
},
"Numbers@odata.type": "#Collection(String)",
"Numbers":
[
"555-555-5555"
],
"Emails@odata.type": "#Collection(String)",
"Emails":
[
"def@test.msn"
],
"Parent@odata.associationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent/$ref",
"Parent@odata.navigationLink": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent",
"#Microsoft.Test.OData.Services.ODataWCFService.ResetAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.ResetAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress"
},
"#Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress":
{
"title": "Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress",
"target": "http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Microsoft.Test.OData.Services.ODataWCFService.GetHomeAddress"
}
}
]
}

View File

@ -0,0 +1,218 @@
<?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.
-->
<feed xml:base="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/"
xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data"
xmlns:m="http://docs.oasis-open.org/odata/ns/metadata"
xmlns:georss="http://www.georss.org/georss"
xmlns:gml="http://www.opengis.net/gml"
m:context="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/$metadata#People">
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People</id>
<title />
<updated>2014-03-20T14:31:00Z</updated>
<entry>
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)</id>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(1)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
<title />
<updated>2014-03-20T14:31:00Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:PersonID m:type="Int32">1</d:PersonID>
<d:FirstName>Bob</d:FirstName>
<d:LastName>Cat</d:LastName>
<d:MiddleName m:null="true" />
<d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
<d:Street>1 Microsoft Way</d:Street>
<d:City>London</d:City>
<d:PostalCode>98052</d:PostalCode>
<d:FamilyName>Cats</d:FamilyName>
</d:HomeAddress>
<d:Home m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>32.1 23.1</gml:pos>
</gml:Point>
</d:Home>
<d:Numbers m:type="#Collection(String)">
<m:element>111-111-1111</m:element>
</d:Numbers>
<d:Emails m:type="#Collection(String)">
<m:element>abc@abc.com</m:element>
</d:Emails>
<d:City>London</d:City>
<d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
<d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
</m:properties>
</content>
</entry>
<entry>
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)</id>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Parent" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(2)/Microsoft.Test.OData.Services.ODataWCFService.Customer/Company" />
<title />
<updated>2014-03-20T14:31:00Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:PersonID m:type="Int32">2</d:PersonID>
<d:FirstName>Jill</d:FirstName>
<d:LastName>Jones</d:LastName>
<d:MiddleName m:null="true" />
<d:HomeAddress m:null="true" />
<d:Home m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>15 161.8</gml:pos>
</gml:Point>
</d:Home>
<d:Numbers m:type="#Collection(String)" />
<d:Emails m:type="#Collection(String)" />
<d:City>Sydney</d:City>
<d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday>
<d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders>
</m:properties>
</content>
</entry>
<entry>
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)</id>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(3)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
<title />
<updated>2014-03-20T14:31:00Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:PersonID m:type="Int32">3</d:PersonID>
<d:FirstName>Jacob</d:FirstName>
<d:LastName>Zip</d:LastName>
<d:MiddleName m:null="true" />
<d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.Address">
<d:Street>1 Microsoft Way</d:Street>
<d:City>Sydney</d:City>
<d:PostalCode>98052</d:PostalCode>
</d:HomeAddress>
<d:Home m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>15 161.8</gml:pos>
</gml:Point>
</d:Home>
<d:Numbers m:type="#Collection(String)">
<m:element>333-333-3333</m:element>
</d:Numbers>
<d:Emails m:type="#Collection(String)">
<m:element m:null="true" />
</d:Emails>
<d:DateHired m:type="DateTimeOffset">2010-12-13T00:00:00Z</d:DateHired>
<d:Office m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>15 162</gml:pos>
</gml:Point>
</d:Office>
</m:properties>
</content>
</entry>
<entry>
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)</id>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Employee" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Parent" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(4)/Microsoft.Test.OData.Services.ODataWCFService.Employee/Company" />
<title />
<updated>2014-03-20T14:31:00Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:PersonID m:type="Int32">4</d:PersonID>
<d:FirstName>Elmo</d:FirstName>
<d:LastName>Rogers</d:LastName>
<d:MiddleName m:null="true" />
<d:HomeAddress m:null="true" />
<d:Home m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>-15 -61.8</gml:pos>
</gml:Point>
</d:Home>
<d:Numbers m:type="#Collection(String)">
<m:element>444-444-4444</m:element>
<m:element>555-555-5555</m:element>
<m:element>666-666-6666</m:element>
</d:Numbers>
<d:Emails m:type="#Collection(String)">
<m:element>def@def.org</m:element>
<m:element>lmn@lmn.com</m:element>
</d:Emails>
<d:DateHired m:type="DateTimeOffset">2008-03-27T00:00:00Z</d:DateHired>
<d:Office m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>-15 -62</gml:pos>
</gml:Point>
</d:Office>
</m:properties>
</content>
</entry>
<entry>
<id>http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)</id>
<category term="#Microsoft.Test.OData.Services.ODataWCFService.Person" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
<link rel="edit" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)" />
<link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://localhost:${cargo.servlet.port}/StaticService/V40/Static.svc/People(5)/Parent" />
<title />
<updated>2014-03-20T14:31:00Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:PersonID m:type="Int32">5</d:PersonID>
<d:FirstName>Peter</d:FirstName>
<d:LastName>Bee</d:LastName>
<d:MiddleName m:null="true" />
<d:HomeAddress m:null="true" />
<d:Home m:type="GeographyPoint">
<gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
<gml:pos>-16 -261.8</gml:pos>
</gml:Point>
</d:Home>
<d:Numbers m:type="#Collection(String)">
<m:element>555-555-5555</m:element>
</d:Numbers>
<d:Emails m:type="#Collection(String)">
<m:element>def@test.msn</m:element>
</d:Emails>
</m:properties>
</content>
</entry>
</feed>

View File

@ -21,499 +21,418 @@
-->
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="NorthwindModel" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<!-- EnumType with values -->
<EnumType Name="FileAccess" UnderlyingType="Edm.Int32" IsFlags="true">
<Member Name="Read" Value="1" />
<Member Name="Write" Value="2" />
<Member Name="Create" Value="4" />
<Member Name="Delete" Value="8" />
</EnumType>
<!-- EnumType without any values -->
<EnumType Name="ShippingMethod">
<Member Name="FirstClass" />
<Member Name="TwoDay" />
<Member Name="Overnight" />
</EnumType>
<!-- ComplexType -->
<ComplexType Name="Dimensions">
<Property Name="Height" Nullable="false" Type="Edm.Decimal" />
<Property Name="Weight" Nullable="false" Type="Edm.Decimal" />
<Property Name="Length" Nullable="false" Type="Edm.Decimal" />
<Schema Namespace="Microsoft.Test.OData.Services.ODataWCFService" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<ComplexType Name="Address">
<Property Name="Street" Type="Edm.String" Nullable="false" />
<Property Name="City" Type="Edm.String" Nullable="false" />
<Property Name="PostalCode" Type="Edm.String" Nullable="false" />
</ComplexType>
<!-- ComplexType with enum property -->
<ComplexType Name="ACL">
<Property Name="Filename" Nullable="false" Type="Edm.String" />
<Property Name="Access" Nullable="false" Type="NorthwindModel.FileAccess" />
<ComplexType Name="HomeAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
<Property Name="FamilyName" Type="Edm.String" />
</ComplexType>
<EntityType Name="Category">
<ComplexType Name="CompanyAddress" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Address">
<Property Name="CompanyName" Type="Edm.String" Nullable="false" />
</ComplexType>
<EnumType Name="AccessLevel" IsFlags="true">
<Member Name="None" Value="0" />
<Member Name="Read" Value="1" />
<Member Name="Write" Value="2" />
<Member Name="Execute" Value="4" />
<Member Name="ReadWrite" Value="3" />
</EnumType>
<EnumType Name="Color">
<Member Name="Red" Value="1" />
<Member Name="Green" Value="2" />
<Member Name="Blue" Value="4" />
</EnumType>
<EnumType Name="CompanyCategory">
<Member Name="IT" Value="0" />
<Member Name="Communication" Value="1" />
<Member Name="Electronics" Value="2" />
<Member Name="Others" Value="4" />
</EnumType>
<EntityType Name="Person">
<Key>
<PropertyRef Name="CategoryID" />
<PropertyRef Name="PersonID" />
</Key>
<Property Name="CategoryID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="Description" Type="Edm.String" MaxLength="max" />
<Property Name="Picture" Type="Edm.Binary" MaxLength="max" />
<NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Category" />
<Property Name="PersonID" Type="Edm.Int32" Nullable="false" />
<Property Name="FirstName" Type="Edm.String" Nullable="false" />
<Property Name="LastName" Type="Edm.String" Nullable="false" />
<Property Name="MiddleName" Type="Edm.String" />
<Property Name="HomeAddress" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
<Property Name="Home" Type="Edm.GeographyPoint" SRID="4326" />
<Property Name="Numbers" Type="Collection(Edm.String)" Nullable="false" />
<Property Name="Emails" Type="Collection(Edm.String)" />
<NavigationProperty Name="Parent" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
</EntityType>
<EntityType Name="CustomerDemographic">
<Key>
<PropertyRef Name="CustomerTypeID" />
</Key>
<Property Name="CustomerTypeID" Type="Edm.String" Nullable="false" MaxLength="10" />
<Property Name="CustomerDesc" Type="Edm.String" MaxLength="max" />
<NavigationProperty Name="Customers" Type="Collection(NorthwindModel.Customer)" Partner="CustomerDemographics" />
<EntityType Name="Customer" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
<Property Name="City" Type="Edm.String" Nullable="false" />
<Property Name="Birthday" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="TimeBetweenLastTwoOrders" Type="Edm.Duration" Nullable="false" />
<NavigationProperty Name="Orders" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Order)" />
<NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="VipCustomer" />
</EntityType>
<EntityType Name="Customer">
<Key>
<PropertyRef Name="CustomerID" />
</Key>
<Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="5" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ContactName" Type="Edm.String" MaxLength="30" />
<Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
<Property Name="Address" Type="Edm.String" MaxLength="60" />
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="Region" Type="Edm.String" MaxLength="15" />
<Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="Country" Type="Edm.String" MaxLength="15" />
<Property Name="Phone" Type="Edm.String" MaxLength="24" />
<Property Name="Fax" Type="Edm.String" MaxLength="24" />
<!-- EnumType attribute -->
<Property Name="FileAccess" Type="NorthwindModel.FileAccess" />
<NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Customer" />
<NavigationProperty Name="CustomerDemographics" Type="Collection(NorthwindModel.CustomerDemographic)" Partner="Customers" />
</EntityType>
<EntityType Name="Employee">
<Key>
<PropertyRef Name="EmployeeID" />
</Key>
<Property Name="EmployeeID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="LastName" Type="Edm.String" Nullable="false" MaxLength="20" />
<Property Name="FirstName" Type="Edm.String" Nullable="false" MaxLength="10" />
<Property Name="Title" Type="Edm.String" MaxLength="30" />
<Property Name="TitleOfCourtesy" Type="Edm.String" MaxLength="25" />
<Property Name="BirthDate" Type="Edm.DateTimeOffset" />
<Property Name="HireDate" Type="Edm.DateTimeOffset" />
<Property Name="Address" Type="Edm.String" MaxLength="60" />
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="Region" Type="Edm.String" MaxLength="15" />
<Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="Country" Type="Edm.String" MaxLength="15" />
<Property Name="HomePhone" Type="Edm.String" MaxLength="24" />
<Property Name="Extension" Type="Edm.String" MaxLength="4" />
<Property Name="Photo" Type="Edm.Binary" MaxLength="max" />
<Property Name="Notes" Type="Edm.String" MaxLength="max" />
<Property Name="ReportsTo" Type="Edm.Int32" />
<Property Name="PhotoPath" Type="Edm.String" MaxLength="255" />
<NavigationProperty Name="Employees1" Type="Collection(NorthwindModel.Employee)" Partner="Employee1" />
<NavigationProperty Name="Employee1" Type="NorthwindModel.Employee" Partner="Employees1">
<ReferentialConstraint Property="ReportsTo" ReferencedProperty="EmployeeID" />
</NavigationProperty>
<NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Employee" />
<NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Employees" />
</EntityType>
<EntityType Name="Order_Detail">
<Key>
<PropertyRef Name="OrderID" />
<PropertyRef Name="ProductID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
<Property Name="Discount" Type="Edm.Single" Nullable="false" />
<NavigationProperty Name="Order" Type="NorthwindModel.Order" Nullable="false" Partner="Order_Details">
<ReferentialConstraint Property="OrderID" ReferencedProperty="OrderID" />
</NavigationProperty>
<NavigationProperty Name="Product" Type="NorthwindModel.Product" Nullable="false" Partner="Order_Details">
<ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
</NavigationProperty>
</EntityType>
<EntityType Name="Order">
<Key>
<PropertyRef Name="OrderID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
<Property Name="EmployeeID" Type="Edm.Int32" />
<Property Name="OrderDate" Type="Edm.DateTimeOffset" />
<Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
<Property Name="ShipVia" Type="Edm.Int32" />
<Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="ShipName" Type="Edm.String" MaxLength="40" />
<Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
<Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
<Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
<Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
<NavigationProperty Name="Customer" Type="NorthwindModel.Customer" Partner="Orders">
<ReferentialConstraint Property="CustomerID" ReferencedProperty="CustomerID" />
</NavigationProperty>
<NavigationProperty Name="Employee" Type="NorthwindModel.Employee" Partner="Orders">
<ReferentialConstraint Property="EmployeeID" ReferencedProperty="EmployeeID" />
</NavigationProperty>
<NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Order" />
<NavigationProperty Name="Shipper" Type="NorthwindModel.Shipper" Partner="Orders">
<ReferentialConstraint Property="ShipVia" ReferencedProperty="ShipperID" />
</NavigationProperty>
<EntityType Name="Employee" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Person">
<Property Name="DateHired" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="Office" Type="Edm.GeographyPoint" SRID="4326" />
<NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Employees" />
</EntityType>
<EntityType Name="Product">
<Key>
<PropertyRef Name="ProductID" />
</Key>
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="SupplierID" Type="Edm.Int32" />
<Property Name="CategoryID" Type="Edm.Int32" />
<Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
<Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="UnitsInStock" Type="Edm.Int16" />
<Property Name="UnitsOnOrder" Type="Edm.Int16" />
<Property Name="ReorderLevel" Type="Edm.Int16" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
<Property Name="QuantityPerUnit" Type="Edm.String" Nullable="false" />
<Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
<Property Name="QuantityInStock" Type="Edm.Int32" Nullable="false" />
<Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
<!-- ComplexType attributes -->
<Property Name="ProductDimensions" Type="NorthwindModel.Dimensions" />
<Property Name="ShippingDimensions" Type="NorthwindModel.Dimensions" />
<NavigationProperty Name="Category" Type="NorthwindModel.Category" Partner="Products">
<ReferentialConstraint Property="CategoryID" ReferencedProperty="CategoryID" />
</NavigationProperty>
<NavigationProperty Name="Order_Details" Type="Collection(NorthwindModel.Order_Detail)" Partner="Product" />
<NavigationProperty Name="Supplier" Type="NorthwindModel.Supplier" Partner="Products">
<ReferentialConstraint Property="SupplierID" ReferencedProperty="SupplierID" />
<Property Name="UserAccess" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
<Property Name="SkinColor" Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
<Property Name="CoverColors" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Color)" Nullable="false" />
<NavigationProperty Name="Details" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)">
<ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
</NavigationProperty>
</EntityType>
<EntityType Name="Region">
<EntityType Name="ProductDetail">
<Key>
<PropertyRef Name="RegionID" />
</Key>
<Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
<Property Name="RegionDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
<NavigationProperty Name="Territories" Type="Collection(NorthwindModel.Territory)" Partner="Region" />
</EntityType>
<EntityType Name="Shipper">
<Key>
<PropertyRef Name="ShipperID" />
</Key>
<Property Name="ShipperID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="Phone" Type="Edm.String" MaxLength="24" />
<NavigationProperty Name="Orders" Type="Collection(NorthwindModel.Order)" Partner="Shipper" />
</EntityType>
<EntityType Name="Supplier">
<Key>
<PropertyRef Name="SupplierID" />
</Key>
<Property Name="SupplierID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ContactName" Type="Edm.String" MaxLength="30" />
<Property Name="ContactTitle" Type="Edm.String" MaxLength="30" />
<Property Name="Address" Type="Edm.String" MaxLength="60" />
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="Region" Type="Edm.String" MaxLength="15" />
<Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="Country" Type="Edm.String" MaxLength="15" />
<Property Name="Phone" Type="Edm.String" MaxLength="24" />
<Property Name="Fax" Type="Edm.String" MaxLength="24" />
<Property Name="HomePage" Type="Edm.String" MaxLength="max" />
<NavigationProperty Name="Products" Type="Collection(NorthwindModel.Product)" Partner="Supplier" />
</EntityType>
<EntityType Name="Territory">
<Key>
<PropertyRef Name="TerritoryID" />
</Key>
<Property Name="TerritoryID" Type="Edm.String" Nullable="false" MaxLength="20" />
<Property Name="TerritoryDescription" Type="Edm.String" Nullable="false" MaxLength="50" />
<Property Name="RegionID" Type="Edm.Int32" Nullable="false" />
<NavigationProperty Name="Region" Type="NorthwindModel.Region" Nullable="false" Partner="Territories">
<ReferentialConstraint Property="RegionID" ReferencedProperty="RegionID" />
</NavigationProperty>
<NavigationProperty Name="Employees" Type="Collection(NorthwindModel.Employee)" Partner="Territories" />
</EntityType>
<EntityType Name="Alphabetical_list_of_product">
<Key>
<PropertyRef Name="CategoryName" />
<PropertyRef Name="Discontinued" />
<PropertyRef Name="ProductID" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="ProductDetailID" />
</Key>
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="SupplierID" Type="Edm.Int32" />
<Property Name="CategoryID" Type="Edm.Int32" />
<Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
<Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="UnitsInStock" Type="Edm.Int16" />
<Property Name="UnitsOnOrder" Type="Edm.Int16" />
<Property Name="ReorderLevel" Type="Edm.Int16" />
<Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" />
<Property Name="Description" Type="Edm.String" Nullable="false" />
<NavigationProperty Name="RelatedProduct" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" />
<NavigationProperty Name="Reviews" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductReview)">
<ReferentialConstraint Property="ProductID" ReferencedProperty="ProductID" />
<ReferentialConstraint Property="ProductDetailID" ReferencedProperty="ProductDetailID" />
</NavigationProperty>
</EntityType>
<EntityType Name="Category_Sales_for_1997">
<Key>
<PropertyRef Name="CategoryName" />
</Key>
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="CategorySales" Type="Edm.Decimal" Precision="19" Scale="4" />
</EntityType>
<EntityType Name="Current_Product_List">
<EntityType Name="ProductReview">
<Key>
<PropertyRef Name="ProductID" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="ProductDetailID" />
<PropertyRef Name="ReviewTitle" />
<PropertyRef Name="RevisionID" />
</Key>
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" p5:StoreGeneratedPattern="Identity" xmlns:p5="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductDetailID" Type="Edm.Int32" Nullable="false" />
<Property Name="ReviewTitle" Type="Edm.String" Nullable="false" />
<Property Name="RevisionID" Type="Edm.Int32" Nullable="false" />
<Property Name="Comment" Type="Edm.String" Nullable="false" />
<Property Name="Author" Type="Edm.String" Nullable="false" />
</EntityType>
<EntityType Name="Customer_and_Suppliers_by_City">
<EntityType Name="Order">
<Key>
<PropertyRef Name="CompanyName" />
<PropertyRef Name="Relationship" />
</Key>
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ContactName" Type="Edm.String" MaxLength="30" />
<Property Name="Relationship" Type="Edm.String" Nullable="false" MaxLength="9" Unicode="false" />
</EntityType>
<EntityType Name="Invoice">
<Key>
<PropertyRef Name="CustomerName" />
<PropertyRef Name="Discount" />
<PropertyRef Name="OrderID" />
<PropertyRef Name="ProductID" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="Quantity" />
<PropertyRef Name="Salesperson" />
<PropertyRef Name="ShipperName" />
<PropertyRef Name="UnitPrice" />
</Key>
<Property Name="ShipName" Type="Edm.String" MaxLength="40" />
<Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
<Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
<Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
<Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
<Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
<Property Name="CustomerName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="Address" Type="Edm.String" MaxLength="60" />
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="Region" Type="Edm.String" MaxLength="15" />
<Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="Country" Type="Edm.String" MaxLength="15" />
<Property Name="Salesperson" Type="Edm.String" Nullable="false" MaxLength="31" />
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="OrderDate" Type="Edm.DateTimeOffset" />
<Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
<Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
<Property Name="Discount" Type="Edm.Single" Nullable="false" />
<Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="OrderDate" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="ShelfLife" Type="Edm.Duration" />
<Property Name="OrderShelfLifes" Type="Collection(Edm.Duration)" />
<NavigationProperty Name="LoggedInEmployee" Type="Microsoft.Test.OData.Services.ODataWCFService.Employee" Nullable="false" />
<NavigationProperty Name="CustomerForOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" />
<NavigationProperty Name="OrderDetails" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.OrderDetail)" />
</EntityType>
<EntityType Name="Order_Details_Extended">
<EntityType Name="OrderDetail">
<Key>
<PropertyRef Name="Discount" />
<PropertyRef Name="OrderID" />
<PropertyRef Name="ProductID" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="Quantity" />
<PropertyRef Name="UnitPrice" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductID" Type="Edm.Int32" Nullable="false" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="UnitPrice" Type="Edm.Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="Quantity" Type="Edm.Int16" Nullable="false" />
<Property Name="Discount" Type="Edm.Single" Nullable="false" />
<Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="OrderPlaced" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="Quantity" Type="Edm.Int32" Nullable="false" />
<Property Name="UnitPrice" Type="Edm.Single" Nullable="false" />
<NavigationProperty Name="ProductOrdered" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" />
<NavigationProperty Name="AssociatedOrder" Type="Microsoft.Test.OData.Services.ODataWCFService.Order" Nullable="false" />
</EntityType>
<EntityType Name="Order_Subtotal">
<EntityType Name="Department">
<Key>
<PropertyRef Name="OrderID" />
<PropertyRef Name="DepartmentID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="DepartmentID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" Nullable="false" />
<NavigationProperty Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" Partner="Departments" />
</EntityType>
<EntityType Name="Orders_Qry">
<EntityType Name="Company">
<Key>
<PropertyRef Name="CompanyName" />
<PropertyRef Name="OrderID" />
<PropertyRef Name="CompanyID" />
</Key>
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="CustomerID" Type="Edm.String" MaxLength="5" />
<Property Name="EmployeeID" Type="Edm.Int32" />
<Property Name="OrderDate" Type="Edm.DateTimeOffset" />
<Property Name="RequiredDate" Type="Edm.DateTimeOffset" />
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
<Property Name="ShipVia" Type="Edm.Int32" />
<Property Name="Freight" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="ShipName" Type="Edm.String" MaxLength="40" />
<Property Name="ShipAddress" Type="Edm.String" MaxLength="60" />
<Property Name="ShipCity" Type="Edm.String" MaxLength="15" />
<Property Name="ShipRegion" Type="Edm.String" MaxLength="15" />
<Property Name="ShipPostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="ShipCountry" Type="Edm.String" MaxLength="15" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="Address" Type="Edm.String" MaxLength="60" />
<Property Name="City" Type="Edm.String" MaxLength="15" />
<Property Name="Region" Type="Edm.String" MaxLength="15" />
<Property Name="PostalCode" Type="Edm.String" MaxLength="10" />
<Property Name="Country" Type="Edm.String" MaxLength="15" />
<Property Name="CompanyID" Type="Edm.Int32" Nullable="false" />
<Property Name="CompanyCategory" Type="Microsoft.Test.OData.Services.ODataWCFService.CompanyCategory" />
<Property Name="Revenue" Type="Edm.Int64" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" />
<NavigationProperty Name="Employees" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Employee)" Partner="Company" />
<NavigationProperty Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer" Nullable="false" Partner="Company" />
<NavigationProperty Name="Departments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Department)" Partner="Company" />
<NavigationProperty Name="CoreDepartment" Type="Microsoft.Test.OData.Services.ODataWCFService.Department" Nullable="false" />
</EntityType>
<EntityType Name="Product_Sales_for_1997">
<EntityType Name="PublicCompany" BaseType="Microsoft.Test.OData.Services.ODataWCFService.Company">
<Property Name="StockExchange" Type="Edm.String" />
<NavigationProperty Name="Assets" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Asset)" ContainsTarget="true" />
<NavigationProperty Name="Club" Type="Microsoft.Test.OData.Services.ODataWCFService.Club" Nullable="false" ContainsTarget="true" />
<NavigationProperty Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" Nullable="false" />
</EntityType>
<EntityType Name="Asset">
<Key>
<PropertyRef Name="CategoryName" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="AssetID" />
</Key>
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="AssetID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Number" Type="Edm.Int32" Nullable="false" />
</EntityType>
<EntityType Name="Products_Above_Average_Price">
<EntityType Name="Club">
<Key>
<PropertyRef Name="ProductName" />
<PropertyRef Name="ClubID" />
</Key>
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="UnitPrice" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="ClubID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
</EntityType>
<EntityType Name="Products_by_Category">
<EntityType Name="LabourUnion">
<Key>
<PropertyRef Name="CategoryName" />
<PropertyRef Name="Discontinued" />
<PropertyRef Name="ProductName" />
<PropertyRef Name="LabourUnionID" />
</Key>
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="QuantityPerUnit" Type="Edm.String" MaxLength="20" />
<Property Name="UnitsInStock" Type="Edm.Int16" />
<Property Name="Discontinued" Type="Edm.Boolean" Nullable="false" />
<Property Name="LabourUnionID" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
</EntityType>
<EntityType Name="Sales_by_Category">
<Key>
<PropertyRef Name="CategoryID" />
<PropertyRef Name="CategoryName" />
<PropertyRef Name="ProductName" />
</Key>
<Property Name="CategoryID" Type="Edm.Int32" Nullable="false" />
<Property Name="CategoryName" Type="Edm.String" Nullable="false" MaxLength="15" />
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ProductSales" Type="Edm.Decimal" Precision="19" Scale="4" />
</EntityType>
<EntityType Name="Sales_Totals_by_Amount">
<Key>
<PropertyRef Name="CompanyName" />
<PropertyRef Name="OrderID" />
</Key>
<Property Name="SaleAmount" Type="Edm.Decimal" Precision="19" Scale="4" />
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="40" />
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
</EntityType>
<EntityType Name="Summary_of_Sales_by_Quarter">
<Key>
<PropertyRef Name="OrderID" />
</Key>
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
</EntityType>
<EntityType Name="Summary_of_Sales_by_Year">
<Key>
<PropertyRef Name="OrderID" />
</Key>
<Property Name="ShippedDate" Type="Edm.DateTimeOffset" />
<Property Name="OrderID" Type="Edm.Int32" Nullable="false" />
<Property Name="Subtotal" Type="Edm.Decimal" Precision="19" Scale="4" />
</EntityType>
<Annotations Target="ODataWebExperimental.Northwind.Model.NorthwindEntities">
<Annotation Term="Com.Microsoft.OData.Service.Conventions.V1.UrlConventions" String="KeyAsSegment" />
</Annotations>
<!-- Function -->
<Function Name="TopSellingProducts" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products">
<Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
</Function>
<Function Name="TopSellingProducts2" ReturnType="Collection(NorthwindModel.Product)" IsComposable="true" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
<Parameter Name="Product" Type="NorthwindModel.Product" />
<Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
</Function>
<!-- Action -->
<Action Name="TopSellingProducts" EntitySetPath="ODataWebExperimental.Northwind.Model.Products" IsBound="true">
<Parameter Name="Product" Type="NorthwindModel.Product" />
<Parameter Name="Year" Type="Edm.Decimal" Precision="4" Scale="0" />
<Action Name="AddAccessRight" IsBound="true">
<Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
<Parameter Name="accessRight" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
</Action>
</Schema>
<Schema Namespace="ODataWebExperimental.Northwind.Model" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="NorthwindEntities" p4:LazyLoadingEnabled="true" xmlns:p4="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
<EntitySet Name="Categories" EntityType="NorthwindModel.Category">
<NavigationPropertyBinding Path="Products" Target="Products" />
<Action Name="IncreaseRevenue" IsBound="true">
<Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
<Parameter Name="IncreaseValue" Type="Edm.Int64" />
<ReturnType Type="Edm.Int64" Nullable="false" />
</Action>
<Action Name="ResetAddress" IsBound="true" EntitySetPath="person">
<Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
<Parameter Name="addresses" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Address)" Nullable="false" />
<Parameter Name="index" Type="Edm.Int32" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
</Action>
<Action Name="Discount" IsBound="true" EntitySetPath="products">
<Parameter Name="products" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
<Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
<ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
</Action>
<Action Name="Discount">
<Parameter Name="percentage" Type="Edm.Int32" Nullable="false" />
</Action>
<Action Name="ResetBossEmail">
<Parameter Name="emails" Type="Collection(Edm.String)" Nullable="false" />
<ReturnType Type="Collection(Edm.String)" Nullable="false" />
</Action>
<Action Name="ResetBossAddress">
<Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
</Action>
<Function Name="GetEmployeesCount" IsBound="true">
<Parameter Name="p" Type="Microsoft.Test.OData.Services.ODataWCFService.Company" Nullable="false" />
<ReturnType Type="Edm.Int32" Nullable="false" />
</Function>
<Function Name="GetProductDetails" IsBound="true" EntitySetPath="product/Details" IsComposable="true">
<Parameter Name="product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
<Parameter Name="count" Type="Edm.Int32" />
<ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.ProductDetail)" Nullable="false" />
</Function>
<Function Name="GetRelatedProduct" IsBound="true" EntitySetPath="productDetail/Products" IsComposable="true">
<Parameter Name="productDetail" Type="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />
</Function>
<Function Name="GetDefaultColor" IsComposable="true">
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Color" />
</Function>
<Function Name="GetPerson" IsComposable="true">
<Parameter Name="address" Type="Microsoft.Test.OData.Services.ODataWCFService.Address" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
</Function>
<Function Name="GetPerson2" IsComposable="true">
<Parameter Name="city" Type="Edm.String" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
</Function>
<Function Name="GetAllProducts" IsComposable="true">
<ReturnType Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Product)" Nullable="false" />
</Function>
<Function Name="GetBossEmails">
<Parameter Name="start" Type="Edm.Int32" Nullable="false" />
<Parameter Name="count" Type="Edm.Int32" Nullable="false" />
<ReturnType Type="Collection(Edm.String)" Nullable="false" />
</Function>
<Function Name="GetProductsByAccessLevel">
<Parameter Name="accessLevel" Type="Microsoft.Test.OData.Services.ODataWCFService.AccessLevel" />
<ReturnType Type="Collection(Edm.String)" Nullable="false" />
</Function>
<Function Name="GetActualAmount" IsBound="true">
<Parameter Name="giftcard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" Nullable="false" />
<Parameter Name="bonusRate" Type="Edm.Double" />
<ReturnType Type="Edm.Double" Nullable="false" />
</Function>
<Function Name="GetDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
<Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
</Function>
<Action Name="RefreshDefaultPI" IsBound="true" EntitySetPath="account/MyPaymentInstruments">
<Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
<Parameter Name="newDate" Type="Edm.DateTimeOffset" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" />
</Action>
<Function Name="GetHomeAddress" IsBound="true" IsComposable="true">
<Parameter Name="person" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.HomeAddress" Nullable="false" />
</Function>
<Function Name="GetAccountInfo" IsBound="true" IsComposable="true">
<Parameter Name="account" Type="Microsoft.Test.OData.Services.ODataWCFService.Account" Nullable="false" />
<ReturnType Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" Nullable="false" />
</Function>
<ComplexType Name="AccountInfo" OpenType="true">
<Property Name="FirstName" Type="Edm.String" Nullable="false" />
<Property Name="LastName" Type="Edm.String" Nullable="false" />
</ComplexType>
<EntityType Name="Account">
<Key>
<PropertyRef Name="AccountID" />
</Key>
<Property Name="AccountID" Type="Edm.Int32" Nullable="false" />
<Property Name="Country" Type="Edm.String" Nullable="false" />
<Property Name="AccountInfo" Type="Microsoft.Test.OData.Services.ODataWCFService.AccountInfo" />
<NavigationProperty Name="MyGiftCard" Type="Microsoft.Test.OData.Services.ODataWCFService.GiftCard" ContainsTarget="true" />
<NavigationProperty Name="MyPaymentInstruments" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument)" ContainsTarget="true" />
<NavigationProperty Name="ActiveSubscriptions" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" ContainsTarget="true" />
<NavigationProperty Name="AvailableSubscriptionTemplatess" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Subscription)" />
</EntityType>
<EntityType Name="GiftCard">
<Key>
<PropertyRef Name="GiftCardID" />
</Key>
<Property Name="GiftCardID" Type="Edm.Int32" Nullable="false" />
<Property Name="GiftCardNO" Type="Edm.String" Nullable="false" />
<Property Name="Amount" Type="Edm.Double" Nullable="false" />
<Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
<EntityType Name="PaymentInstrument">
<Key>
<PropertyRef Name="PaymentInstrumentID" />
</Key>
<Property Name="PaymentInstrumentID" Type="Edm.Int32" Nullable="false" />
<Property Name="FriendlyName" Type="Edm.String" Nullable="false" />
<Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
<NavigationProperty Name="TheStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
<NavigationProperty Name="BillingStatements" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.Statement)" ContainsTarget="true" />
<NavigationProperty Name="BackupStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" Nullable="false" />
</EntityType>
<EntityType Name="CreditCardPI" BaseType="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument">
<Property Name="CardNumber" Type="Edm.String" Nullable="false" />
<Property Name="CVV" Type="Edm.String" Nullable="false" />
<Property Name="HolderName" Type="Edm.String" Nullable="false" />
<Property Name="Balance" Type="Edm.Double" Nullable="false" />
<Property Name="ExperationDate" Type="Edm.DateTimeOffset" Nullable="false" />
<NavigationProperty Name="CreditRecords" Type="Collection(Microsoft.Test.OData.Services.ODataWCFService.CreditRecord)" ContainsTarget="true" />
</EntityType>
<EntityType Name="StoredPI">
<Key>
<PropertyRef Name="StoredPIID" />
</Key>
<Property Name="StoredPIID" Type="Edm.Int32" Nullable="false" />
<Property Name="PIName" Type="Edm.String" Nullable="false" />
<Property Name="PIType" Type="Edm.String" Nullable="false" />
<Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
<EntityType Name="Statement">
<Key>
<PropertyRef Name="StatementID" />
</Key>
<Property Name="StatementID" Type="Edm.Int32" Nullable="false" />
<Property Name="TransactionType" Type="Edm.String" Nullable="false" />
<Property Name="TransactionDescription" Type="Edm.String" Nullable="false" />
<Property Name="Amount" Type="Edm.Double" Nullable="false" />
</EntityType>
<EntityType Name="CreditRecord">
<Key>
<PropertyRef Name="CreditRecordID" />
</Key>
<Property Name="CreditRecordID" Type="Edm.Int32" Nullable="false" />
<Property Name="IsGood" Type="Edm.Boolean" Nullable="false" />
<Property Name="Reason" Type="Edm.String" Nullable="false" />
<Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
<EntityType Name="Subscription">
<Key>
<PropertyRef Name="SubscriptionID" />
</Key>
<Property Name="SubscriptionID" Type="Edm.Int32" Nullable="false" />
<Property Name="TemplateGuid" Type="Edm.String" Nullable="false" />
<Property Name="Title" Type="Edm.String" Nullable="false" />
<Property Name="Category" Type="Edm.String" Nullable="false" />
<Property Name="CreatedDate" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
<EntityContainer Name="InMemoryEntities">
<EntitySet Name="People" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Person">
<NavigationPropertyBinding Path="Parent" Target="People" />
</EntitySet>
<EntitySet Name="CustomerDemographics" EntityType="NorthwindModel.CustomerDemographic">
<NavigationPropertyBinding Path="Customers" Target="Customers" />
</EntitySet>
<EntitySet Name="Customers" EntityType="NorthwindModel.Customer">
<NavigationPropertyBinding Path="CustomerDemographics" Target="CustomerDemographics" />
<Singleton Name="Boss" Type="Microsoft.Test.OData.Services.ODataWCFService.Person" />
<EntitySet Name="Customers" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Customer">
<NavigationPropertyBinding Path="Orders" Target="Orders" />
</EntitySet>
<EntitySet Name="Employees" EntityType="NorthwindModel.Employee">
<NavigationPropertyBinding Path="Employees1" Target="Employees" />
<NavigationPropertyBinding Path="Employee1" Target="Employees" />
<Singleton Name="VipCustomer" Type="Microsoft.Test.OData.Services.ODataWCFService.Customer">
<NavigationPropertyBinding Path="Orders" Target="Orders" />
<NavigationPropertyBinding Path="Territories" Target="Territories" />
</EntitySet>
<EntitySet Name="Order_Details" EntityType="NorthwindModel.Order_Detail">
<NavigationPropertyBinding Path="Order" Target="Orders" />
<NavigationPropertyBinding Path="Product" Target="Products" />
</EntitySet>
<EntitySet Name="Orders" EntityType="NorthwindModel.Order">
<NavigationPropertyBinding Path="Customer" Target="Customers" />
<NavigationPropertyBinding Path="Employee" Target="Employees" />
<NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
<NavigationPropertyBinding Path="Shipper" Target="Shippers" />
</EntitySet>
<EntitySet Name="Products" EntityType="NorthwindModel.Product">
<NavigationPropertyBinding Path="Category" Target="Categories" />
<NavigationPropertyBinding Path="Order_Details" Target="Order_Details" />
<NavigationPropertyBinding Path="Supplier" Target="Suppliers" />
</EntitySet>
<EntitySet Name="Regions" EntityType="NorthwindModel.Region">
<NavigationPropertyBinding Path="Territories" Target="Territories" />
</EntitySet>
<EntitySet Name="Shippers" EntityType="NorthwindModel.Shipper">
<NavigationPropertyBinding Path="Orders" Target="Orders" />
</EntitySet>
<EntitySet Name="Suppliers" EntityType="NorthwindModel.Supplier">
<NavigationPropertyBinding Path="Products" Target="Products" />
</EntitySet>
<EntitySet Name="Territories" EntityType="NorthwindModel.Territory">
<NavigationPropertyBinding Path="Employees" Target="Employees" />
<NavigationPropertyBinding Path="Region" Target="Regions" />
</EntitySet>
<EntitySet Name="Alphabetical_list_of_products" EntityType="NorthwindModel.Alphabetical_list_of_product" />
<EntitySet Name="Category_Sales_for_1997" EntityType="NorthwindModel.Category_Sales_for_1997" />
<EntitySet Name="Current_Product_Lists" EntityType="NorthwindModel.Current_Product_List" />
<EntitySet Name="Customer_and_Suppliers_by_Cities" EntityType="NorthwindModel.Customer_and_Suppliers_by_City" />
<EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice" />
<EntitySet Name="Order_Details_Extendeds" EntityType="NorthwindModel.Order_Details_Extended" />
<EntitySet Name="Order_Subtotals" EntityType="NorthwindModel.Order_Subtotal" />
<EntitySet Name="Orders_Qries" EntityType="NorthwindModel.Orders_Qry" />
<EntitySet Name="Product_Sales_for_1997" EntityType="NorthwindModel.Product_Sales_for_1997" />
<EntitySet Name="Products_Above_Average_Prices" EntityType="NorthwindModel.Products_Above_Average_Price" />
<EntitySet Name="Products_by_Categories" EntityType="NorthwindModel.Products_by_Category" />
<EntitySet Name="Sales_by_Categories" EntityType="NorthwindModel.Sales_by_Category" />
<EntitySet Name="Sales_Totals_by_Amounts" EntityType="NorthwindModel.Sales_Totals_by_Amount" />
<EntitySet Name="Summary_of_Sales_by_Quarters" EntityType="NorthwindModel.Summary_of_Sales_by_Quarter" />
<EntitySet Name="Summary_of_Sales_by_Years" EntityType="NorthwindModel.Summary_of_Sales_by_Year" />
<!-- Singleton -->
<Singleton Name="Contoso" Type="NorthwindModel.Supplier">
<NavigationPropertyBinding Path="Products" Target="Products"/>
<NavigationPropertyBinding Path="Company" Target="Company" />
</Singleton>
<!-- FunctionImport -->
<FunctionImport Name="TopSellingProducts" EntitySet="Products" Function="NorthwindModel.TopSellingProducts"/>
<EntitySet Name="Employees" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Employee">
<NavigationPropertyBinding Path="Company" Target="Company" />
</EntitySet>
<EntitySet Name="Products" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Product">
<NavigationPropertyBinding Path="Details" Target="ProductDetails" />
</EntitySet>
<EntitySet Name="ProductDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductDetail">
<NavigationPropertyBinding Path="RelatedProduct" Target="Products" />
<NavigationPropertyBinding Path="Reviews" Target="ProductReviews" />
</EntitySet>
<EntitySet Name="ProductReviews" EntityType="Microsoft.Test.OData.Services.ODataWCFService.ProductReview" />
<EntitySet Name="Orders" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Order">
<NavigationPropertyBinding Path="LoggedInEmployee" Target="Employees" />
<NavigationPropertyBinding Path="CustomerForOrder" Target="Customers" />
<NavigationPropertyBinding Path="OrderDetails" Target="OrderDetails" />
</EntitySet>
<EntitySet Name="OrderDetails" EntityType="Microsoft.Test.OData.Services.ODataWCFService.OrderDetail">
<NavigationPropertyBinding Path="AssociatedOrder" Target="Orders" />
<NavigationPropertyBinding Path="ProductOrdered" Target="Products" />
</EntitySet>
<EntitySet Name="Departments" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Department">
<NavigationPropertyBinding Path="Company" Target="Company" />
</EntitySet>
<Singleton Name="Company" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
<NavigationPropertyBinding Path="Employees" Target="Employees" />
<NavigationPropertyBinding Path="VipCustomer" Target="VipCustomer" />
<NavigationPropertyBinding Path="Departments" Target="Departments" />
<NavigationPropertyBinding Path="CoreDepartment" Target="Departments" />
</Singleton>
<Singleton Name="PublicCompany" Type="Microsoft.Test.OData.Services.ODataWCFService.Company">
<NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PublicCompany/LabourUnion" Target="LabourUnion" />
</Singleton>
<Singleton Name="LabourUnion" Type="Microsoft.Test.OData.Services.ODataWCFService.LabourUnion" />
<ActionImport Name="Discount" Action="Microsoft.Test.OData.Services.ODataWCFService.Discount" />
<ActionImport Name="ResetBossEmail" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossEmail" />
<ActionImport Name="ResetBossAddress" Action="Microsoft.Test.OData.Services.ODataWCFService.ResetBossAddress" />
<FunctionImport Name="GetDefaultColor" Function="Microsoft.Test.OData.Services.ODataWCFService.GetDefaultColor" />
<FunctionImport Name="GetPerson" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson" EntitySet="People" />
<FunctionImport Name="GetPerson2" Function="Microsoft.Test.OData.Services.ODataWCFService.GetPerson2" EntitySet="People" />
<FunctionImport Name="GetAllProducts" Function="Microsoft.Test.OData.Services.ODataWCFService.GetAllProducts" EntitySet="Products" />
<FunctionImport Name="GetBossEmails" Function="Microsoft.Test.OData.Services.ODataWCFService.GetBossEmails" />
<FunctionImport Name="GetProductsByAccessLevel" Function="Microsoft.Test.OData.Services.ODataWCFService.GetProductsByAccessLevel" />
<EntitySet Name="Accounts" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Account">
<NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/TheStoredPI" Target="StoredPIs" />
<NavigationPropertyBinding Path="AvailableSubscriptionTemplatess" Target="SubscriptionTemplates" />
<NavigationPropertyBinding Path="Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument/BackupStoredPI" Target="DefaultStoredPI" />
</EntitySet>
<EntitySet Name="StoredPIs" EntityType="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
<EntitySet Name="SubscriptionTemplates" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Subscription" />
<Singleton Name="DefaultStoredPI" Type="Microsoft.Test.OData.Services.ODataWCFService.StoredPI" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -20,6 +20,7 @@ package org.apache.olingo.client.api.communication.request;
import java.util.concurrent.Future;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.client.api.format.Format;
/**
* Basic OData request.
@ -27,7 +28,7 @@ import org.apache.olingo.client.api.communication.response.ODataResponse;
* @param <V> OData response type corresponding to the request implementation.
* @param <T> Accepted content-type formats by the request in object.
*/
public interface ODataBasicRequest<V extends ODataResponse, T extends Enum<T>> extends ODataRequest {
public interface ODataBasicRequest<V extends ODataResponse, T extends Format> extends ODataRequest {
/**
* Request execute.

View File

@ -20,9 +20,10 @@ package org.apache.olingo.client.api.communication.request.retrieve;
import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.format.Format;
/**
* This is an abstract representation of an OData retrieve query request returning one or more result item.
*/
public interface ODataRetrieveRequest<V, T extends Enum<T>> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
public interface ODataRetrieveRequest<V, T extends Format> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
}

View File

@ -20,7 +20,6 @@ package org.apache.olingo.client.api.domain;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.olingo.client.api.format.ODataPubFormat;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
@ -31,11 +30,11 @@ public enum ODataLinkType {
/**
* Entity navigation link.
*/
ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
ENTITY_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=entry"),
/**
* Entity set navigation link.
*/
ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
ENTITY_SET_NAVIGATION(ContentType.APPLICATION_ATOM_XML.getMimeType() + ";type=feed"),
/**
* Association link.
*/
@ -57,7 +56,8 @@ public enum ODataLinkType {
}
/**
* Gets <code>LinkType</code> instance from the given rel and type.
* Gets
* <code>LinkType</code> instance from the given rel and type.
*
* @param client OData client.
* @param rel rel.

View File

@ -0,0 +1,26 @@
/*
* 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.client.api.format;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
public interface Format {
String toString(ODataServiceVersion version);
}

View File

@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats to be used in various contexts.
*/
public enum ODataFormat {
public enum ODataFormat implements Format{
/**
* JSON format with no metadata.
@ -94,4 +95,9 @@ public enum ODataFormat {
return result;
}
@Override
public String toString(final ODataServiceVersion version) {
return this.toString();
}
}

View File

@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for media.
*/
public enum ODataMediaFormat {
public enum ODataMediaFormat implements Format{
CHARSET_PARAMETER("charset"),
MEDIA_TYPE_WILDCARD("*"),
@ -68,4 +69,9 @@ public enum ODataMediaFormat {
return result;
}
@Override
public String toString(final ODataServiceVersion version) {
return this.toString();
}
}

View File

@ -18,34 +18,49 @@
*/
package org.apache.olingo.client.api.format;
import java.util.EnumMap;
import org.apache.http.entity.ContentType;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for AtomPub exchange.
*/
public enum ODataPubFormat {
public enum ODataPubFormat implements Format {
/**
* JSON format with no metadata.
*/
JSON_NO_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata"),
JSON_NO_METADATA(),
/**
* JSON format with minimal metadata (default).
*/
JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata"),
JSON(),
/**
* JSON format with no metadata.
*/
JSON_FULL_METADATA(ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata"),
JSON_FULL_METADATA(),
/**
* Atom format.
*/
ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType());
ATOM();
private final String format;
final static EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>> formatPerVersion =
new EnumMap<ODataServiceVersion, EnumMap<ODataPubFormat, String>>(ODataServiceVersion.class);
ODataPubFormat(final String format) {
this.format = format;
static {
final EnumMap<ODataPubFormat, String> v3 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
v3.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=nometadata");
v3.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata=minimalmetadata");
v3.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata=fullmetadata");
v3.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
formatPerVersion.put(ODataServiceVersion.V30, v3);
final EnumMap<ODataPubFormat, String> v4 = new EnumMap<ODataPubFormat, String>(ODataPubFormat.class);
v4.put(JSON_NO_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none");
v4.put(JSON, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal");
v4.put(JSON_FULL_METADATA, ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full");
v4.put(ATOM, ContentType.APPLICATION_ATOM_XML.getMimeType());
formatPerVersion.put(ODataServiceVersion.V40, v4);
}
/**
@ -53,9 +68,18 @@ public enum ODataPubFormat {
*
* @return format as a string.
*/
@Override
public String toString(final ODataServiceVersion version) {
if (version.ordinal() < ODataServiceVersion.V30.ordinal()) {
throw new IllegalArgumentException("Unsupported version " + version);
}
return ODataPubFormat.formatPerVersion.get(version).get(this);
}
@Override
public String toString() {
return format;
throw new UnsupportedOperationException();
}
/**
@ -72,7 +96,7 @@ public enum ODataPubFormat {
final String[] parts = format.split(";");
_format.append(parts[0].trim());
if (ContentType.APPLICATION_JSON.getMimeType().equals(parts[0].trim())) {
if (parts.length > 1 && parts[1].startsWith("odata=")) {
if (parts.length > 1 && parts[1].startsWith("odata")) {
_format.append(';').append(parts[1].trim());
} else {
result = ODataPubFormat.JSON;
@ -82,7 +106,8 @@ public enum ODataPubFormat {
if (result == null) {
final String candidate = _format.toString();
for (ODataPubFormat value : values()) {
if (candidate.equals(value.toString())) {
if (candidate.equals(value.toString(ODataServiceVersion.V30))
|| candidate.equals(value.toString(ODataServiceVersion.V40))) {
result = value;
}
}

View File

@ -19,11 +19,12 @@
package org.apache.olingo.client.api.format;
import org.apache.http.entity.ContentType;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
/**
* Available formats for property values.
*/
public enum ODataValueFormat {
public enum ODataValueFormat implements Format{
/**
* Application octet stream.
@ -73,4 +74,9 @@ public enum ODataValueFormat {
return result;
}
@Override
public String toString(final ODataServiceVersion version) {
return this.toString();
}
}

View File

@ -31,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
/**
@ -39,88 +40,87 @@ import org.apache.olingo.client.api.http.HttpMethod;
* @param <V> OData response type corresponding to the request implementation.
* @param <T> OData format being used.
*/
public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Enum<T>>
public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Format>
extends ODataRequestImpl<T>
implements ODataBasicRequest<V, T> {
/**
* Constructor.
*
* @param odataClient client instance getting this request
* @param formatRef reference class for the format being used
* @param method request method.
* @param uri OData request URI.
*/
public AbstractODataBasicRequest(final CommonODataClient odataClient,
final Class<T> formatRef, final HttpMethod method, final URI uri) {
/**
* Constructor.
*
* @param odataClient client instance getting this request
* @param formatRef reference class for the format being used
* @param method request method.
* @param uri OData request URI.
*/
public AbstractODataBasicRequest(final CommonODataClient odataClient,
final Class<T> formatRef, final HttpMethod method, final URI uri) {
super(odataClient, formatRef, method, uri);
super(odataClient, formatRef, method, uri);
}
/**
* {@inheritDoc}
*/
@Override
public void setFormat(final T format) {
if (format != null) {
setAccept(format.toString(odataClient.getServiceVersion()));
setContentType(format.toString(odataClient.getServiceVersion()));
}
}
/**
* {@inheritDoc}
*/
@Override
public void setFormat(final T format) {
if (format != null) {
setAccept(format.toString());
setContentType(format.toString());
}
}
/**
* {@inheritDoc}
*/
@Override
public final Future<V> asyncExecute() {
return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
@Override
public V call() throws Exception {
return execute();
}
});
}
/**
* Gets payload as an InputStream.
*
* @return InputStream for entire payload.
*/
protected abstract InputStream getPayload();
/**
* Serializes the full request into the given batch request.
*
* @param req destination batch request.
*/
public void batch(final ODataBatchRequest req) {
batch(req, null);
}
/**
* Serializes the full request into the given batch request.
* <p>
* This method have to be used to serialize a changeset item with the specified contentId.
*
* @param req destination batch request.
* @param contentId contentId of the changeset item.
*/
public void batch(final ODataBatchRequest req, final String contentId) {
try {
req.rawAppend(toByteArray());
if (StringUtils.isNotBlank(contentId)) {
req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
req.rawAppend(ODataStreamer.CRLF);
}
req.rawAppend(ODataStreamer.CRLF);
final InputStream payload = getPayload();
if (payload != null) {
req.rawAppend(IOUtils.toByteArray(getPayload()));
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
/**
* {@inheritDoc}
*/
@Override
public final Future<V> asyncExecute() {
return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
@Override
public V call() throws Exception {
return execute();
}
});
}
/**
* Gets payload as an InputStream.
*
* @return InputStream for entire payload.
*/
protected abstract InputStream getPayload();
/**
* Serializes the full request into the given batch request.
*
* @param req destination batch request.
*/
public void batch(final ODataBatchRequest req) {
batch(req, null);
}
/**
* Serializes the full request into the given batch request.
* <p>
* This method have to be used to serialize a changeset item with the specified contentId.
*
* @param req destination batch request.
* @param contentId contentId of the changeset item.
*/
public void batch(final ODataBatchRequest req, final String contentId) {
try {
req.rawAppend(toByteArray());
if (StringUtils.isNotBlank(contentId)) {
req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
req.rawAppend(ODataStreamer.CRLF);
}
req.rawAppend(ODataStreamer.CRLF);
final InputStream payload = getPayload();
if (payload != null) {
req.rawAppend(IOUtils.toByteArray(getPayload()));
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}

View File

@ -42,6 +42,10 @@ import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
import org.apache.olingo.client.api.communication.header.ODataHeaders;
import org.apache.olingo.client.api.communication.request.ODataRequest;
import org.apache.olingo.client.api.communication.request.ODataStreamer;
import org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory;
import org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory;
import org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory;
import org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.client.api.format.ODataMediaFormat;
import org.apache.olingo.client.api.format.ODataPubFormat;
@ -51,6 +55,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.data.JSONErrorImpl;
import org.apache.olingo.client.core.data.XMLErrorImpl;
import org.apache.olingo.client.api.data.ODataError;
import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.slf4j.Logger;
@ -66,7 +71,7 @@ import org.slf4j.LoggerFactory;
* @see InvokeRequestFactory
* @see StreamedRequestFactory
*/
public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
public class ODataRequestImpl<T extends Format> implements ODataRequest {
/**
* Logger.
@ -251,7 +256,7 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
@Override
public String getAccept() {
final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString() : acceptHead;
return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString(odataClient.getServiceVersion()) : acceptHead;
}
/**
@ -284,7 +289,8 @@ public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
@Override
public String getContentType() {
final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
return StringUtils.isBlank(contentTypeHead) ? getDefaultFormat().toString() : contentTypeHead;
return StringUtils.isBlank(contentTypeHead)
? getDefaultFormat().toString(odataClient.getServiceVersion()) : contentTypeHead;
}
/**

View File

@ -100,7 +100,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
public void setFormat(final ODataPubFormat format) {
final String _format = (reference.isAssignableFrom(ODataProperty.class) && format == ODataPubFormat.ATOM)
? ODataFormat.XML.toString()
: format.toString();
: format.toString(odataClient.getServiceVersion());
setAccept(_format);
setContentType(_format);
}
@ -163,7 +163,7 @@ public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
} else if (this.method == HttpMethod.POST) {
((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
setContentType(ODataPubFormat.JSON.toString());
setContentType(ODataPubFormat.JSON.toString(odataClient.getServiceVersion()));
}
}

View File

@ -26,6 +26,7 @@ import org.apache.olingo.client.api.CommonODataClient;
import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.format.Format;
import org.apache.olingo.client.api.http.HttpMethod;
import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
@ -33,7 +34,7 @@ import org.apache.olingo.client.core.communication.response.AbstractODataRespons
/**
* This is an abstract representation of an OData retrieve query request returning one or more result item.
*/
public abstract class AbstractODataRetrieveRequest<V, T extends Enum<T>>
public abstract class AbstractODataRetrieveRequest<V, T extends Format>
extends AbstractODataBasicRequest<ODataRetrieveResponse<V>, T>
implements ODataRetrieveRequest<V, T>, ODataBatchableRequest {

View File

@ -92,7 +92,7 @@ public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
this.close();
}
}
return odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
}

View File

@ -48,7 +48,7 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
public AbstractODataStreamedEntityRequest(final CommonODataClient odataClient, final HttpMethod method,
URI uri) {
super(odataClient, method, uri);
setAccept(getFormat().toString());
setAccept(getFormat().toString(odataClient.getServiceVersion()));
}
/**
@ -65,6 +65,6 @@ public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse
@Override
public final void setFormat(final ODataPubFormat format) {
this.format = format;
setAccept(format.toString());
setAccept(format.toString(odataClient.getServiceVersion()));
}
}

View File

@ -57,7 +57,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
}
private ODataPropertyType guessPropertyType(final JsonNode node) {
ODataPropertyType type = null;
final ODataPropertyType type;
if (node.isValueNode() || node.isNull()) {
type = ODataPropertyType.PRIMITIVE;
@ -73,7 +73,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
}
private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
Value value = null;
final Value value;
if (node.isNull()) {
value = new NullValueImpl();
@ -172,5 +172,4 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
}
}
}

View File

@ -153,7 +153,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
throws XMLStreamException {
boolean foundEndProperties = false;
while (reader.hasNext() && !foundEndProperties) {
final XMLEvent event = reader.nextEvent();
@ -316,7 +315,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
boolean foundEndFeed = false;
while (reader.hasNext() && !foundEndFeed) {
final XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
if (countQName.equals(event.asStartElement().getName())) {
count(reader, event.asStartElement(), feed);

View File

@ -139,7 +139,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
}
}
ODataPropertyType type = null;
final ODataPropertyType type;
if (child == null) {
type = ODataPropertyType.PRIMITIVE;
} else {
@ -168,16 +168,19 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
property.setName(start.getName().getLocalPart());
final Attribute typeAttr = start.getAttributeByName(this.typeQName);
if (typeAttr != null) {
property.setType(typeAttr.getValue());
}
Value value;
final Attribute nullAttr = start.getAttributeByName(this.nullQName);
final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
if (nullAttr == null) {
final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
final EdmTypeInfo typeInfo = StringUtils.isBlank(typeAttrValue)
? null
: new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
: new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
if (typeInfo != null) {
property.setType(typeInfo.getTypeExpression());
}
final ODataPropertyType propType = typeInfo == null
? guessPropertyType(reader)
@ -207,6 +210,7 @@ class AtomPropertyDeserializer extends AbstractAtomDealer {
} else {
value = new NullValueImpl();
}
property.setValue(value);
return property;

View File

@ -60,7 +60,7 @@ class JSONGeoValueDeserializer {
private MultiPoint multipoint(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
MultiPoint multiPoint = null;
final MultiPoint multiPoint;
if (itor.hasNext()) {
final List<Point> points = new ArrayList<Point>();
@ -79,7 +79,7 @@ class JSONGeoValueDeserializer {
private LineString lineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
LineString lineString = null;
final LineString lineString;
if (itor.hasNext()) {
final List<Point> points = new ArrayList<Point>();
@ -98,7 +98,7 @@ class JSONGeoValueDeserializer {
private MultiLineString multiLineString(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
MultiLineString multiLineString = null;
final MultiLineString multiLineString;
if (itor.hasNext()) {
final List<LineString> lineStrings = new ArrayList<LineString>();
@ -147,7 +147,7 @@ class JSONGeoValueDeserializer {
private MultiPolygon multiPolygon(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
MultiPolygon multiPolygon = null;
final MultiPolygon multiPolygon;
if (itor.hasNext()) {
final List<Polygon> polygons = new ArrayList<Polygon>();
@ -166,7 +166,7 @@ class JSONGeoValueDeserializer {
private GeospatialCollection collection(final Iterator<JsonNode> itor, final EdmPrimitiveTypeKind type,
final String crs) {
GeospatialCollection collection = null;
final GeospatialCollection collection;
if (itor.hasNext()) {
final List<Geospatial> geospatials = new ArrayList<Geospatial>();
@ -262,5 +262,4 @@ class JSONGeoValueDeserializer {
return value;
}
}

View File

@ -19,7 +19,6 @@
package org.apache.olingo.client.core.edm;
import org.apache.olingo.client.api.edm.xml.v4.ActionImport;
import org.apache.olingo.client.core.edm.EdmTypeInfo;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmActionImport;

View File

@ -70,12 +70,12 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
@Override
public FullQualifiedName getBindingParameterTypeFqn() {
FullQualifiedName fqn = null;
FullQualifiedName bpfqn = null;
final EdmParameter bindingParam = getBindingParameter();
if (bindingParam != null) {
fqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
bpfqn = new FullQualifiedName(bindingParam.getType().getNamespace(), bindingParam.getType().getName());
}
return fqn;
return bpfqn;
}
@Override
@ -85,6 +85,6 @@ public abstract class EdmOperationImpl extends AbstractEdmOperation {
if (bindingParam != null) {
result = bindingParam.isCollection();
}
return null;
return result;
}
}

View File

@ -23,6 +23,7 @@ import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.slf4j.Logger;
@ -56,12 +57,11 @@ public class EdmTypeInfo {
}
public EdmTypeInfo build() {
return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1
return new EdmTypeInfo(edm, typeExpression.indexOf('.') == -1 && StringUtils.isNotBlank(defaultNamespace)
? defaultNamespace + "." + typeExpression
: typeExpression);
}
}
private final Edm edm;
private final String typeExpression;
@ -80,7 +80,6 @@ public class EdmTypeInfo {
private EdmTypeInfo(final Edm edm, final String typeExpression) {
this.edm = edm;
this.typeExpression = typeExpression;
String baseType;
final int collStartIdx = typeExpression.indexOf("Collection(");
@ -97,16 +96,30 @@ public class EdmTypeInfo {
baseType = typeExpression.substring(collStartIdx + 11, collEndIdx);
}
baseType = baseType.replaceAll("^#", "");
final String typeName;
final String namespace;
final int lastDotIdx = baseType.lastIndexOf('.');
if (lastDotIdx == -1) {
throw new IllegalArgumentException("Cannot find namespace or alias in " + typeExpression);
namespace = EdmPrimitiveType.EDM_NAMESPACE;
typeName = baseType;
baseType = new FullQualifiedName(EdmPrimitiveType.EDM_NAMESPACE, baseType).toString();
} else {
namespace = baseType.substring(0, lastDotIdx);
typeName = baseType.substring(lastDotIdx + 1);
}
final String namespace = baseType.substring(0, lastDotIdx);
final String typeName = baseType.substring(lastDotIdx + 1);
if (StringUtils.isBlank(typeName)) {
throw new IllegalArgumentException("Null or empty type name in " + typeExpression);
}
final StringBuilder exp = new StringBuilder();
exp.append(baseType);
this.typeExpression = (this.collection ? exp.insert(0, "Collection(").append(")") : exp).toString();
this.fullQualifiedName = new FullQualifiedName(namespace, typeName);
try {
@ -168,5 +181,4 @@ public class EdmTypeInfo {
public EdmEntityType getEntityType() {
return entityType;
}
}

View File

@ -268,7 +268,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
}
final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
final URI next = resource.getNext();
final ODataEntitySet entitySet = next == null
@ -282,7 +282,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
for (Entry entryResource : resource.getEntries()) {
entitySet.addEntity(getODataEntity(entryResource));
}
return entitySet;
}
@ -310,11 +310,11 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
if (StringUtils.isNotBlank(resource.getETag())) {
entity.setETag(resource.getETag());
}
if (resource.getEditLink() != null) {
entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
}
for (Link link : resource.getAssociationLinks()) {
entity.addLink(client.getObjectFactory().newAssociationLink(link.getTitle(), base, link.getHref()));
}

View File

@ -103,5 +103,4 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
}
}
}

View File

@ -148,7 +148,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
appendEntitySetSegment("Car").appendKeySegment(16);
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
req.setFormat(format.toString());
req.setFormat(format.toString(client.getServiceVersion()));
final ODataRawResponse res = req.execute();
assertNotNull(res);

View File

@ -138,7 +138,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
uriBuilder.appendEntitySetSegment("Car");
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
req.setFormat(format.toString());
req.setFormat(format.toString(client.getServiceVersion()));
final ODataRawResponse res = req.execute();
assertNotNull(res);

View File

@ -107,7 +107,8 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
final ODataRetrieveResponse<ODataEntity> res = req.execute();
assertNotNull(res);
assertTrue(res.getContentType().replaceAll(" ", "").startsWith(ODataPubFormat.JSON.toString()));
assertTrue(res.getContentType().replaceAll(" ", "").
startsWith(ODataPubFormat.JSON.toString(client.getServiceVersion())));
}
/**

View File

@ -35,8 +35,8 @@ public abstract class AbstractTestITCase extends org.apache.olingo.client.core.i
@BeforeClass
public static void setUpODataServiceRoot() throws IOException {
testStaticServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc";
testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc/large";
testStaticServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc";
testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V40/Static.svc/large";
testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc";
}

View File

@ -0,0 +1,152 @@
/*
* 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.client.core.it.v4;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ODataEntitySet;
import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
import org.apache.olingo.client.api.format.ODataPubFormat;
import org.apache.olingo.client.api.uri.CommonURIBuilder;
import org.apache.olingo.client.core.op.impl.ResourceFactory;
import static org.junit.Assert.assertNotNull;
import org.junit.Ignore;
import org.junit.Test;
/**
* This is the unit test class to check basic feed operations.
*/
public class EntitySetTestITCase extends AbstractTestITCase {
protected String getServiceRoot() {
return testStaticServiceRootURL;
}
@Test
public void rawRequestAsAtom() throws IOException {
rawRequest(ODataPubFormat.ATOM);
}
@Test
@Ignore
public void rawRequestAsJSON() throws IOException {
rawRequest(ODataPubFormat.JSON);
}
@Test
public void readODataEntitySetIteratorFromAtom() {
readODataEntitySetIterator(ODataPubFormat.ATOM);
}
@Test
@Ignore
public void readODataEntitySetIteratorFromJSON() {
readODataEntitySetIterator(ODataPubFormat.JSON);
}
@Test
@Ignore
public void readODataEntitySetIteratorFromJSONFullMeta() {
readODataEntitySetIterator(ODataPubFormat.JSON_FULL_METADATA);
}
@Test
@Ignore
public void readODataEntitySetIteratorFromJSONNoMeta() {
readODataEntitySetIterator(ODataPubFormat.JSON_NO_METADATA);
}
@Test
public void readODataEntitySetWithNextFromAtom() {
readEntitySetWithNextLink(ODataPubFormat.ATOM);
}
@Test
@Ignore
public void readODataEntitySetWithNextFromJSON() {
readEntitySetWithNextLink(ODataPubFormat.JSON_FULL_METADATA);
}
private void readEntitySetWithNextLink(final ODataPubFormat format) {
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
uriBuilder.appendEntitySetSegment("People");
final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest(uriBuilder.build());
req.setFormat(format);
final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
final ODataEntitySet feed = res.getBody();
assertNotNull(feed);
debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
ODataPubFormat.ATOM == format)), "Just retrieved feed");
assertEquals(5, feed.getEntities().size());
// assertNotNull(feed.getNext());
// final URI expected = URI.create(getServiceRoot() + "/Customer?$skiptoken=-9");
// final URI found = URIUtils.getURI(getServiceRoot(), feed.getNext().toASCIIString());
// assertEquals(expected, found);
}
private void readODataEntitySetIterator(final ODataPubFormat format) {
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
uriBuilder.appendEntitySetSegment("People");
final ODataEntitySetIteratorRequest req =
client.getRetrieveRequestFactory().getEntitySetIteratorRequest(uriBuilder.build());
req.setFormat(format);
final ODataRetrieveResponse<ODataEntitySetIterator> res = req.execute();
final ODataEntitySetIterator feedIterator = res.getBody();
assertNotNull(feedIterator);
int count = 0;
while (feedIterator.hasNext()) {
assertNotNull(feedIterator.next());
count++;
}
assertEquals(5, count);
// assertTrue(feedIterator.getNext().toASCIIString().endsWith("Customer?$skiptoken=-9"));
}
private void rawRequest(final ODataPubFormat format) {
final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot());
uriBuilder.appendEntitySetSegment("People");
final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
req.setFormat(format.toString(client.getServiceVersion()));
final ODataRawResponse res = req.execute();
assertNotNull(res);
final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
assertNotNull(entitySet);
}
}

View File

@ -26,92 +26,93 @@ import java.util.List;
* Interface representing a Entity Data Model as described in the Conceptual Schema Definition.
*/
public interface Edm {
/**
* This method DOES NOT support lazy loading. All schemas are loaded completely!
* @return all schemas defined for this EDM
*/
List<EdmSchema> getSchemas();
/**
* Get entity container by full qualified name.
* <br/>
* See {@link EdmEntityContainer} for more information.
*
* @param name
* @return {@link EdmEntityContainer}
*/
EdmEntityContainer getEntityContainer(FullQualifiedName name);
/**
* This method DOES NOT support lazy loading. All schemas are loaded completely!
*
* @return all schemas defined for this EDM
*/
List<EdmSchema> getSchemas();
/**
* Get enum type by full qualified name.
* <br/>
* See {@link EdmEnumType} for more information
*
* @param name
* @return {@link EdmEnumType}
*/
EdmEnumType getEnumType(FullQualifiedName name);
/**
* Get entity container by full qualified name.
* <br/>
* See {@link EdmEntityContainer} for more information.
*
* @param name
* @return {@link EdmEntityContainer}
*/
EdmEntityContainer getEntityContainer(FullQualifiedName name);
/**
* Get a type definition by full qualified name.
* <br/>
* See {@link EdmTypeDefinition} for more information
*
* @param name
* @return {@link EdmTypeDefinition}
*/
EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
/**
* Get enum type by full qualified name.
* <br/>
* See {@link EdmEnumType} for more information
*
* @param name
* @return {@link EdmEnumType}
*/
EdmEnumType getEnumType(FullQualifiedName name);
/**
* Get entity type by full qualified name.
* <br/>
* See {@link EdmEntityType} for more information.
*
* @param name
* @return {@link EdmEntityType}
*/
EdmEntityType getEntityType(FullQualifiedName name);
/**
* Get a type definition by full qualified name.
* <br/>
* See {@link EdmTypeDefinition} for more information
*
* @param name
* @return {@link EdmTypeDefinition}
*/
EdmTypeDefinition getTypeDefinition(FullQualifiedName name);
/**
* Get complex type by full qualified name..
* <br/>
* See {@link EdmComplexType} for more information.
*
* @param name
* @return {@link EdmComplexType}
*/
EdmComplexType getComplexType(FullQualifiedName name);
/**
* Get entity type by full qualified name.
* <br/>
* See {@link EdmEntityType} for more information.
*
* @param name
* @return {@link EdmEntityType}
*/
EdmEntityType getEntityType(FullQualifiedName name);
/**
* Get Action by full qualified name and binding parameter type.
*
* @param actionName must not be null
* @param bindingParameterTypeName may be null if it is an unbound action
* @param isBindingParameterCollection may be null if it is an unbound action
* @return {@link EdmAction}
*/
EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
Boolean isBindingParameterCollection);
/**
* Get complex type by full qualified name..
* <br/>
* See {@link EdmComplexType} for more information.
*
* @param name
* @return {@link EdmComplexType}
*/
EdmComplexType getComplexType(FullQualifiedName name);
/**
* Get Function by full qualified name and binding parameter type and binding parameter names.
*
* @param functionName
* @param bindingParameterTypeName may be null if it is an unbound function
* @param isBindingParameterCollection may be null if it is an unbound function
* @param parameterNames may be null if it is an unbound function
* @return {@link EdmFunction}
*/
EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
Boolean isBindingParameterCollection, List<String> parameterNames);
/**
* Get Action by full qualified name and binding parameter type.
*
* @param actionName must not be null
* @param bindingParameterTypeName may be null if it is an unbound action
* @param isBindingParameterCollection may be null if it is an unbound action
* @return {@link EdmAction}
*/
EdmAction getAction(FullQualifiedName actionName, FullQualifiedName bindingParameterTypeName,
Boolean isBindingParameterCollection);
/**
* Get service metadata.
* <br/>
* See {@link EdmServiceMetadata} for more information.
*
* @return {@link EdmServiceMetadata}
*/
EdmServiceMetadata getServiceMetadata();
/**
* Get Function by full qualified name and binding parameter type and binding parameter names.
*
* @param functionName
* @param bindingParameterTypeName may be null if it is an unbound function
* @param isBindingParameterCollection may be null if it is an unbound function
* @param parameterNames may be null if it is an unbound function
* @return {@link EdmFunction}
*/
EdmFunction getFunction(FullQualifiedName functionName, FullQualifiedName bindingParameterTypeName,
Boolean isBindingParameterCollection, List<String> parameterNames);
/**
* Get service metadata.
* <br/>
* See {@link EdmServiceMetadata} for more information.
*
* @return {@link EdmServiceMetadata}
*/
EdmServiceMetadata getServiceMetadata();
}

View File

@ -23,5 +23,5 @@ package org.apache.olingo.commons.api.edm;
*/
public interface EdmActionImport extends EdmOperationImport {
EdmAction getAction();
EdmAction getAction();
}

View File

@ -40,8 +40,6 @@ public enum ODataServiceVersion {
public static final String NS_METADATA = "metadata";
public static final String NS_DATA = "data";
public static final String NS_SCHEME = "scheme";
public static final String NAVIGATION_LINK_REL = "navigationLinkRel";
@ -70,8 +68,11 @@ public enum ODataServiceVersion {
{
put(NS_METADATA, "http://docs.oasis-open.org/odata/ns/metadata");
put(NS_DATA, "http://docs.oasis-open.org/odata/ns/data");
put(NS_DATASERVICES, "http://docs.oasis-open.org/odata/ns/data");
put(NS_SCHEME, "http://docs.oasis-open.org/odata/ns/scheme");
put(NAVIGATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/related/");
put(ASSOCIATION_LINK_REL, "http://docs.oasis-open.org/odata/ns/relatedlinks/");
put(MEDIA_EDIT_LINK_REL, "http://docs.oasis-open.org/odata/ns/edit-media/");
}
});

View File

@ -27,24 +27,29 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmComplexType extends AbstractEdmStructuredType implements EdmComplexType {
public AbstractEdmComplexType(final Edm edm, final FullQualifiedName fqn, final FullQualifiedName baseTypeName) {
super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
}
@Override
protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
EdmComplexType baseType = null;
if (baseTypeName != null) {
baseType = edm.getComplexType(baseTypeName);
if (baseType == null) {
throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: " + getName());
}
public AbstractEdmComplexType(
final Edm edm,
final FullQualifiedName fqn,
final FullQualifiedName baseTypeName) {
super(edm, fqn, EdmTypeKind.COMPLEX, baseTypeName);
}
return baseType;
}
@Override
public EdmComplexType getBaseType() {
return (EdmComplexType) baseType;
}
@Override
protected EdmStructuredType buildBaseType(final FullQualifiedName baseTypeName) {
// TODO: check for comment
EdmComplexType baseType = null;
if (baseTypeName != null) {
baseType = edm.getComplexType(baseTypeName);
if (baseType == null) {
throw new EdmException("Can't find base type with name: " + baseTypeName + " for complex type: "
+ getName());
}
}
return baseType;
}
@Override
public EdmComplexType getBaseType() {
return (EdmComplexType) baseType;
}
}

View File

@ -33,119 +33,123 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
public abstract class AbstractEdmEntityContainer extends EdmNamedImpl implements EdmEntityContainer {
protected final FullQualifiedName entityContainerName;
protected final FullQualifiedName entityContainerName;
protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
private boolean allSingletonsLoaded = false;
protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
private boolean allEntitySetsLoaded = false;
private boolean allSingletonsLoaded = false;
protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
private boolean allActionImportsLoaded = false;
protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
private boolean allFunctionImportsLoaded = false;
private boolean allEntitySetsLoaded = false;
public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
super(edm, entityContainerName.getName());
this.entityContainerName = entityContainerName;
}
protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
@Override
public String getNamespace() {
return entityContainerName.getNamespace();
}
private boolean allActionImportsLoaded = false;
protected abstract EdmSingleton createSingleton(String singletonName);
protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
@Override
public EdmSingleton getSingleton(final String singletonName) {
EdmSingleton singleton = singletons.get(singletonName);
if (singleton == null) {
singleton = createSingleton(singletonName);
singletons.put(singletonName, singleton);
private boolean allFunctionImportsLoaded = false;
public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName) {
super(edm, entityContainerName.getName());
this.entityContainerName = entityContainerName;
}
return singleton;
}
protected abstract EdmEntitySet createEntitySet(String entitySetName);
@Override
public EdmEntitySet getEntitySet(final String entitySetName) {
EdmEntitySet entitySet = entitySets.get(entitySetName);
if (entitySet == null) {
entitySet = createEntitySet(entitySetName);
entitySets.put(entitySetName, entitySet);
@Override
public String getNamespace() {
return entityContainerName.getNamespace();
}
return entitySet;
}
protected abstract EdmActionImport createActionImport(String actionImportName);
protected abstract EdmSingleton createSingleton(String singletonName);
@Override
public EdmActionImport getActionImport(final String actionImportName) {
EdmActionImport actionImport = actionImports.get(actionImportName);
if (actionImport == null) {
actionImport = createActionImport(actionImportName);
actionImports.put(actionImportName, actionImport);
@Override
public EdmSingleton getSingleton(final String singletonName) {
EdmSingleton singleton = singletons.get(singletonName);
if (singleton == null) {
singleton = createSingleton(singletonName);
singletons.put(singletonName, singleton);
}
return singleton;
}
return actionImport;
}
protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
protected abstract EdmEntitySet createEntitySet(String entitySetName);
@Override
public EdmFunctionImport getFunctionImport(final String functionImportName) {
EdmFunctionImport functionImport = functionImports.get(functionImportName);
if (functionImport == null) {
functionImport = createFunctionImport(functionImportName);
functionImports.put(functionImportName, functionImport);
@Override
public EdmEntitySet getEntitySet(final String entitySetName) {
EdmEntitySet entitySet = entitySets.get(entitySetName);
if (entitySet == null) {
entitySet = createEntitySet(entitySetName);
entitySets.put(entitySetName, entitySet);
}
return entitySet;
}
return functionImport;
}
@Override
public List<EdmEntitySet> getEntitySets() {
if (!allEntitySetsLoaded) {
loadAllEntitySets();
allEntitySetsLoaded = true;
protected abstract EdmActionImport createActionImport(String actionImportName);
@Override
public EdmActionImport getActionImport(final String actionImportName) {
EdmActionImport actionImport = actionImports.get(actionImportName);
if (actionImport == null) {
actionImport = createActionImport(actionImportName);
actionImports.put(actionImportName, actionImport);
}
return actionImport;
}
return new ArrayList<EdmEntitySet>(entitySets.values());
}
protected abstract void loadAllEntitySets();
protected abstract EdmFunctionImport createFunctionImport(String functionImportName);
@Override
public List<EdmFunctionImport> getFunctionImports() {
if (!allFunctionImportsLoaded) {
loadAllFunctionImports();
allFunctionImportsLoaded = true;
@Override
public EdmFunctionImport getFunctionImport(final String functionImportName) {
EdmFunctionImport functionImport = functionImports.get(functionImportName);
if (functionImport == null) {
functionImport = createFunctionImport(functionImportName);
functionImports.put(functionImportName, functionImport);
}
return functionImport;
}
return new ArrayList<EdmFunctionImport>(functionImports.values());
}
protected abstract void loadAllFunctionImports();
@Override
public List<EdmSingleton> getSingletons() {
if (!allSingletonsLoaded) {
loadAllSingletons();
allSingletonsLoaded = true;
@Override
public List<EdmEntitySet> getEntitySets() {
if (!allEntitySetsLoaded) {
loadAllEntitySets();
allEntitySetsLoaded = true;
}
return new ArrayList<EdmEntitySet>(entitySets.values());
}
return new ArrayList<EdmSingleton>(singletons.values());
}
protected abstract void loadAllSingletons();
protected abstract void loadAllEntitySets();
@Override
public List<EdmActionImport> getActionImports() {
if (!allActionImportsLoaded) {
loadAllActionImports();
allActionImportsLoaded = true;
@Override
public List<EdmFunctionImport> getFunctionImports() {
if (!allFunctionImportsLoaded) {
loadAllFunctionImports();
allFunctionImportsLoaded = true;
}
return new ArrayList<EdmFunctionImport>(functionImports.values());
}
return new ArrayList<EdmActionImport>(actionImports.values());
}
protected abstract void loadAllActionImports();
protected abstract void loadAllFunctionImports();
@Override
public List<EdmSingleton> getSingletons() {
if (!allSingletonsLoaded) {
loadAllSingletons();
allSingletonsLoaded = true;
}
return new ArrayList<EdmSingleton>(singletons.values());
}
protected abstract void loadAllSingletons();
@Override
public List<EdmActionImport> getActionImports() {
if (!allActionImportsLoaded) {
loadAllActionImports();
allActionImportsLoaded = true;
}
return new ArrayList<EdmActionImport>(actionImports.values());
}
protected abstract void loadAllActionImports();
}

View File

@ -35,80 +35,83 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmOperation extends EdmTypeImpl implements EdmOperation {
private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
private final Map<String, EdmParameter> parameters = new LinkedHashMap<String, EdmParameter>();
private String entitySetPath;
private String entitySetPath;
private boolean isBound;
private boolean isBound;
private EdmReturnType returnType;
private EdmReturnType returnType;
private List<String> parameterNames;
private List<String> parameterNames;
protected AbstractEdmOperation(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
super(edm, fqn, kind);
}
protected void setParameters(final List<EdmParameter> _parameters) {
for (EdmParameter parameter : _parameters) {
parameters.put(parameter.getName(), parameter);
protected AbstractEdmOperation(
final Edm edm,
final FullQualifiedName fqn,
final EdmTypeKind kind) {
super(edm, fqn, kind);
}
}
protected void setEntitySetPath(final String entitySetPath) {
this.entitySetPath = entitySetPath;
}
protected void setIsBound(final boolean isBound) {
this.isBound = isBound;
}
protected void setReturnType(final EdmReturnType returnType) {
this.returnType = returnType;
}
@Override
public EdmParameter getParameter(final String name) {
return parameters.get(name);
}
@Override
public List<String> getParameterNames() {
if (parameterNames == null) {
parameterNames = new ArrayList<String>(parameters.size());
for (String parameterName : parameters.keySet()) {
parameterNames.add(parameterName);
}
protected void setParameters(final List<EdmParameter> _parameters) {
for (EdmParameter parameter : _parameters) {
parameters.put(parameter.getName(), parameter);
}
}
return parameterNames;
}
@Override
public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
EdmEntitySet returnedEntitySet = null;
if (bindingParameterEntitySet != null && entitySetPath != null) {
final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
getRelatedBindingTarget(entitySetPath);
if (relatedBindingTarget == null) {
throw new EdmException("Cannot find entity set with path: " + entitySetPath);
}
if (relatedBindingTarget instanceof EdmEntitySet) {
returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
} else {
throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName() + " must be an entity set");
}
protected void setEntitySetPath(final String entitySetPath) {
this.entitySetPath = entitySetPath;
}
return returnedEntitySet;
}
@Override
public EdmReturnType getReturnType() {
return returnType;
}
protected void setIsBound(final boolean isBound) {
this.isBound = isBound;
}
@Override
public boolean isBound() {
return isBound;
}
protected void setReturnType(final EdmReturnType returnType) {
this.returnType = returnType;
}
@Override
public EdmParameter getParameter(final String name) {
return parameters.get(name);
}
@Override
public List<String> getParameterNames() {
if (parameterNames == null) {
parameterNames = new ArrayList<String>(parameters.size());
for (String parameterName : parameters.keySet()) {
parameterNames.add(parameterName);
}
}
return parameterNames;
}
@Override
public EdmEntitySet getReturnedEntitySet(final EdmEntitySet bindingParameterEntitySet) {
EdmEntitySet returnedEntitySet = null;
if (bindingParameterEntitySet != null && entitySetPath != null) {
final EdmBindingTarget relatedBindingTarget = bindingParameterEntitySet.
getRelatedBindingTarget(entitySetPath);
if (relatedBindingTarget == null) {
throw new EdmException("Cannot find entity set with path: " + entitySetPath);
}
if (relatedBindingTarget instanceof EdmEntitySet) {
returnedEntitySet = (EdmEntitySet) relatedBindingTarget;
} else {
throw new EdmException("BindingTarget with name: " + relatedBindingTarget.getName()
+ " must be an entity set");
}
}
return returnedEntitySet;
}
@Override
public EdmReturnType getReturnType() {
return returnType;
}
@Override
public boolean isBound() {
return isBound;
}
}

View File

@ -27,37 +27,40 @@ import org.apache.olingo.commons.api.edm.Target;
public abstract class AbstractEdmOperationImport extends EdmNamedImpl implements EdmOperationImport {
protected final EdmEntityContainer container;
protected final EdmEntityContainer container;
private final Target entitySet;
private final Target entitySet;
private EdmEntitySet returnedEntitySet;
private EdmEntitySet returnedEntitySet;
public AbstractEdmOperationImport(final Edm edm, final EdmEntityContainer container, final String name,
final Target entitySet) {
public AbstractEdmOperationImport(
final Edm edm,
final EdmEntityContainer container,
final String name,
final Target entitySet) {
super(edm, name);
this.container = container;
this.entitySet = entitySet;
}
@Override
public EdmEntitySet getReturnedEntitySet() {
if (entitySet != null && returnedEntitySet == null) {
EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
if (entityContainer == null) {
throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
}
returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
if (returnedEntitySet == null) {
throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
}
super(edm, name);
this.container = container;
this.entitySet = entitySet;
}
return returnedEntitySet;
}
@Override
public EdmEntityContainer getEntityContainer() {
return container;
}
@Override
public EdmEntitySet getReturnedEntitySet() {
if (entitySet != null && returnedEntitySet == null) {
EdmEntityContainer entityContainer = edm.getEntityContainer(entitySet.getEntityContainer());
if (entityContainer == null) {
throw new EdmException("Can´t find entity container with name: " + entitySet.getEntityContainer());
}
returnedEntitySet = entityContainer.getEntitySet(entitySet.getTargetName());
if (returnedEntitySet == null) {
throw new EdmException("Can´t find entity set with name: " + entitySet.getTargetName());
}
}
return returnedEntitySet;
}
@Override
public EdmEntityContainer getEntityContainer() {
return container;
}
}

View File

@ -34,96 +34,99 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmStructuredType extends EdmTypeImpl implements EdmStructuredType {
protected EdmStructuredType baseType;
protected EdmStructuredType baseType;
private List<String> propertyNames;
private List<String> propertyNames;
private List<String> navigationPropertyNames;
private List<String> navigationPropertyNames;
public AbstractEdmStructuredType(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind,
final FullQualifiedName baseTypeName) {
public AbstractEdmStructuredType(
final Edm edm,
final FullQualifiedName fqn,
final EdmTypeKind kind,
final FullQualifiedName baseTypeName) {
super(edm, fqn, kind);
}
protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
protected abstract Map<String, EdmProperty> getProperties();
protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
@Override
public List<String> getPropertyNames() {
if (propertyNames == null) {
propertyNames = new ArrayList<String>();
if (baseType != null) {
propertyNames.addAll(baseType.getPropertyNames());
}
propertyNames.addAll(getProperties().keySet());
}
return propertyNames;
}
@Override
public List<String> getNavigationPropertyNames() {
if (navigationPropertyNames == null) {
navigationPropertyNames = new ArrayList<String>();
if (baseType != null) {
navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
}
navigationPropertyNames.addAll(getNavigationProperties().keySet());
}
return navigationPropertyNames;
}
@Override
public EdmElement getProperty(final String name) {
EdmElement property = getStructuralProperty(name);
if (property == null) {
property = getNavigationProperty(name);
}
return property;
}
@Override
public EdmProperty getStructuralProperty(final String name) {
EdmProperty property = null;
if (baseType != null) {
property = baseType.getStructuralProperty(name);
}
if (property == null) {
property = getProperties().get(name);
}
return property;
}
@Override
public EdmNavigationProperty getNavigationProperty(final String name) {
EdmNavigationProperty property = null;
if (baseType != null) {
property = baseType.getNavigationProperty(name);
}
if (property == null) {
property = getNavigationProperties().get(name);
}
return property;
}
@Override
public boolean compatibleTo(final EdmType targetType) {
EdmStructuredType sourceType = this;
if (targetType == null) {
throw new EdmException("Target type must not be null");
}
while (!sourceType.getName().equals(targetType.getName())
|| !sourceType.getNamespace().equals(targetType.getNamespace())) {
sourceType = sourceType.getBaseType();
if (sourceType == null) {
return false;
}
super(edm, fqn, kind);
}
return true;
}
protected abstract EdmStructuredType buildBaseType(FullQualifiedName baseTypeName);
protected abstract Map<String, EdmProperty> getProperties();
protected abstract Map<String, EdmNavigationProperty> getNavigationProperties();
@Override
public List<String> getPropertyNames() {
if (propertyNames == null) {
propertyNames = new ArrayList<String>();
if (baseType != null) {
propertyNames.addAll(baseType.getPropertyNames());
}
propertyNames.addAll(getProperties().keySet());
}
return propertyNames;
}
@Override
public List<String> getNavigationPropertyNames() {
if (navigationPropertyNames == null) {
navigationPropertyNames = new ArrayList<String>();
if (baseType != null) {
navigationPropertyNames.addAll(baseType.getNavigationPropertyNames());
}
navigationPropertyNames.addAll(getNavigationProperties().keySet());
}
return navigationPropertyNames;
}
@Override
public EdmElement getProperty(final String name) {
EdmElement property = getStructuralProperty(name);
if (property == null) {
property = getNavigationProperty(name);
}
return property;
}
@Override
public EdmProperty getStructuralProperty(final String name) {
EdmProperty property = null;
if (baseType != null) {
property = baseType.getStructuralProperty(name);
}
if (property == null) {
property = getProperties().get(name);
}
return property;
}
@Override
public EdmNavigationProperty getNavigationProperty(final String name) {
EdmNavigationProperty property = null;
if (baseType != null) {
property = baseType.getNavigationProperty(name);
}
if (property == null) {
property = getNavigationProperties().get(name);
}
return property;
}
@Override
public boolean compatibleTo(final EdmType targetType) {
EdmStructuredType sourceType = this;
if (targetType == null) {
throw new EdmException("Target type must not be null");
}
while (!sourceType.getName().equals(targetType.getName())
|| !sourceType.getNamespace().equals(targetType.getNamespace())) {
sourceType = sourceType.getBaseType();
if (sourceType == null) {
return false;
}
}
return true;
}
}

View File

@ -23,18 +23,17 @@ import org.apache.olingo.commons.api.edm.EdmNamed;
public abstract class EdmNamedImpl implements EdmNamed {
protected final Edm edm;
protected final Edm edm;
private final String name;
private final String name;
public EdmNamedImpl(final Edm edm, final String name) {
this.edm = edm;
this.name = name;
}
@Override
public String getName() {
return name;
}
public EdmNamedImpl(final Edm edm, final String name) {
this.edm = edm;
this.name = name;
}
@Override
public String getName() {
return name;
}
}

View File

@ -25,24 +25,23 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public class EdmTypeImpl extends EdmNamedImpl implements EdmType {
protected final FullQualifiedName fqn;
protected final FullQualifiedName fqn;
protected final EdmTypeKind kind;
protected final EdmTypeKind kind;
public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
super(edm, fqn.getName());
this.fqn = fqn;
this.kind = kind;
}
public EdmTypeImpl(final Edm edm, final FullQualifiedName fqn, final EdmTypeKind kind) {
super(edm, fqn.getName());
this.fqn = fqn;
this.kind = kind;
}
@Override
public String getNamespace() {
return fqn.getNamespace();
}
@Override
public EdmTypeKind getKind() {
return kind;
}
@Override
public String getNamespace() {
return fqn.getNamespace();
}
@Override
public EdmTypeKind getKind() {
return kind;
}
}