[OLINGO-209] Methods added to Edm interfaces, with default implementations compliant to OData 4.0 specs

This commit is contained in:
Francesco Chicchiriccò 2014-04-03 10:45:46 +02:00
parent 809519f9d8
commit aeb66aa82a
16 changed files with 284 additions and 56 deletions

View File

@ -124,18 +124,6 @@ public abstract class AbstractServices {
return getMetadata(Constants.get(getVersion(), ConstantKey.METADATA));
}
/**
* Provide sample lartge metadata.
*
* @return metadata.
*/
@GET
@Path("/large/$metadata")
@Produces("application/xml")
public Response getLargeMetadata() {
return getMetadata("large" + StringUtils.capitalize(Constants.get(getVersion(), ConstantKey.METADATA)));
}
protected Response getMetadata(final String filename) {
try {
return xml.createResponse(FSManager.instance(getVersion()).readFile(filename, Accept.XML), null, Accept.XML);
@ -176,7 +164,7 @@ public abstract class AbstractServices {
return utils.getValue().createResponse(
FSManager.instance(getVersion()).readFile(Constants.get(getVersion(), ConstantKey.REF)
+ File.separatorChar + filename, utils.getKey()),
+ File.separatorChar + filename, utils.getKey()),
null,
utils.getKey());
} catch (Exception e) {

View File

@ -18,10 +18,16 @@
*/
package org.apache.olingo.fit;
import javax.ws.rs.GET;
import org.apache.olingo.fit.utils.ODataVersion;
import org.apache.olingo.fit.utils.XHTTPMethodInterceptor;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.olingo.fit.utils.ConstantKey;
import org.apache.olingo.fit.utils.Constants;
@Path("/V30/Static.svc")
@InInterceptors(classes = XHTTPMethodInterceptor.class)
@ -35,4 +41,29 @@ public class V3Services extends AbstractServices {
protected ODataVersion getVersion() {
return ODataVersion.v3;
}
/**
* Provide sample large metadata.
*
* @return metadata.
*/
@GET
@Path("/large/$metadata")
@Produces("application/xml")
public Response getLargeMetadata() {
return getMetadata("large" + StringUtils.capitalize(Constants.get(getVersion(), ConstantKey.METADATA)));
}
/**
* Provide sample large metadata.
*
* @return metadata.
*/
@GET
@Path("/openType/$metadata")
@Produces("application/xml")
public Response getOpenTypeMetadata() {
return getMetadata("openType" + StringUtils.capitalize(Constants.get(getVersion(), ConstantKey.METADATA)));
}
}

View File

@ -0,0 +1,67 @@
<?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.
-->
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="Microsoft.Test.OData.Services.OpenTypesService" xmlns="http://schemas.microsoft.com/ado/2008/01/edm">
<ComplexType Name="ContactDetails">
<Property Name="FirstContacted" Type="Edm.Binary"/>
<Property Name="LastContacted" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="Contacted" Type="Edm.DateTime" Nullable="false"/>
<Property Name="GUID" Type="Edm.Guid" Nullable="false"/>
<Property Name="PreferedContactTime" Type="Edm.Time" Nullable="false"/>
<Property Name="Byte" Type="Edm.Byte" Nullable="false"/>
<Property Name="SignedByte" Type="Edm.SByte" Nullable="false"/>
<Property Name="Double" Type="Edm.Double" Nullable="false"/>
<Property Name="Single" Type="Edm.Single" Nullable="false"/>
<Property Name="Short" Type="Edm.Int16" Nullable="false"/>
<Property Name="Int" Type="Edm.Int32" Nullable="false"/>
<Property Name="Long" Type="Edm.Int64" Nullable="false"/>
</ComplexType>
<EntityType Name="Row" OpenType="true">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false"/>
</EntityType>
<EntityType Name="IndexedRow" BaseType="Microsoft.Test.OData.Services.OpenTypesService.Row" OpenType="true"/>
<EntityType Name="RowIndex" OpenType="true">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<NavigationProperty Name="Rows" Relationship="Microsoft.Test.OData.Services.OpenTypesService.RowIndex_Rows" ToRole="Rows" FromRole="RowIndex"/>
</EntityType>
<Association Name="RowIndex_Rows">
<End Type="Microsoft.Test.OData.Services.OpenTypesService.RowIndex" Role="RowIndex" Multiplicity="*"/>
<End Type="Microsoft.Test.OData.Services.OpenTypesService.IndexedRow" Role="Rows" Multiplicity="*"/>
</Association>
<EntityContainer Name="DefaultContainer" m:IsDefaultEntityContainer="true">
<EntitySet Name="Row" EntityType="Microsoft.Test.OData.Services.OpenTypesService.Row"/>
<EntitySet Name="RowIndex" EntityType="Microsoft.Test.OData.Services.OpenTypesService.RowIndex"/>
<AssociationSet Name="Index_Rows" Association="Microsoft.Test.OData.Services.OpenTypesService.RowIndex_Rows">
<End Role="RowIndex" EntitySet="RowIndex"/>
<End Role="Rows" EntitySet="Row"/>
</AssociationSet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -50,17 +50,18 @@ public class EdmEntityContainerImpl extends AbstractEdmEntityContainer {
public EdmEntityContainerImpl(final Edm edm, final FullQualifiedName entityContainerName,
final EntityContainer xmlEntityContainer, final List<? extends Schema> xmlSchemas) {
super(edm, entityContainerName, getFullQualifiedName(xmlEntityContainer.getExtends()));
super(edm, entityContainerName, xmlEntityContainer.getExtends() == null
? null : new FullQualifiedName(xmlEntityContainer.getExtends()));
this.xmlEntityContainer = xmlEntityContainer;
this.xmlSchemas = xmlSchemas;
}
private static FullQualifiedName getFullQualifiedName(String parent) {
if (parent != null) {
return new FullQualifiedName(parent);
}
return null;
@Override
public boolean isDefault() {
return xmlEntityContainer instanceof org.apache.olingo.client.api.edm.xml.v4.EntityContainer
? true
: xmlEntityContainer.isDefaultEntityContainer();
}
@Override

View File

@ -61,11 +61,14 @@ public class EdmEntityTypeImpl extends AbstractEdmEntityType {
return instance;
}
private final EntityType entityType;
private EdmEntityTypeImpl(final Edm edm, final FullQualifiedName fqn, final FullQualifiedName baseTypeName,
final EntityType entityType) {
super(edm, fqn, baseTypeName, entityType.isHasStream());
this.helper = new EdmStructuredTypeHelperImpl(edm, entityType);
this.entityType = entityType;
}
@Override
@ -78,4 +81,9 @@ public class EdmEntityTypeImpl extends AbstractEdmEntityType {
return helper.getNavigationProperties();
}
@Override
public boolean isOpenType() {
return entityType.isOpenType();
}
}

View File

@ -19,7 +19,9 @@
package org.apache.olingo.client.core.edm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.olingo.client.api.edm.xml.ComplexType;
import org.apache.olingo.client.api.edm.xml.EntityContainer;
@ -53,6 +55,10 @@ public class EdmSchemaImpl extends AbstractEdmSchemaImpl {
private final Schema schema;
private Map<FullQualifiedName, EdmEntityContainer> entityContainerByName;
private List<EdmEntityContainer> entityContainers;
public EdmSchemaImpl(final ODataServiceVersion version, final Edm edm,
final List<? extends Schema> xmlSchemas, final Schema schema) {
@ -65,8 +71,36 @@ public class EdmSchemaImpl extends AbstractEdmSchemaImpl {
}
@Override
protected EdmEntityContainer createEntityContainer() {
final EntityContainer defaultContainer = schema.getDefaultEntityContainer();
public List<EdmEntityContainer> getEntityContainers() {
if (entityContainers == null) {
if (schema instanceof org.apache.olingo.client.api.edm.xml.v4.Schema) {
entityContainers = super.getEntityContainers();
entityContainerByName = new HashMap<FullQualifiedName, EdmEntityContainer>();
entityContainerByName.put(
new FullQualifiedName(getEntityContainer().getNamespace(), getEntityContainer().getName()),
getEntityContainer());
} else {
entityContainers = new ArrayList<EdmEntityContainer>(schema.getEntityContainers().size());
for (EntityContainer entityContainer : schema.getEntityContainers()) {
final EdmEntityContainer edmContainer = createEntityContainer(entityContainer.getName());
final FullQualifiedName fqn = new FullQualifiedName(edmContainer.getNamespace(), edmContainer.getName());
entityContainers.add(edmContainer);
entityContainerByName.put(fqn, edmContainer);
}
}
}
return entityContainers;
}
@Override
public EdmEntityContainer getEntityContainer(final FullQualifiedName name) {
return entityContainerByName.get(name);
}
private EdmEntityContainer createEntityContainer(final String name) {
final EntityContainer defaultContainer = schema.getEntityContainer(name);
if (defaultContainer != null) {
final FullQualifiedName entityContainerName =
new FullQualifiedName(schema.getNamespace(), defaultContainer.getName());
@ -75,6 +109,15 @@ public class EdmSchemaImpl extends AbstractEdmSchemaImpl {
return null;
}
@Override
protected EdmEntityContainer createEntityContainer() {
final EntityContainer defaultContainer = schema.getDefaultEntityContainer();
if (defaultContainer != null) {
return createEntityContainer(defaultContainer.getName());
}
return null;
}
@Override
protected List<EdmTypeDefinition> createTypeDefinitions() {
final List<EdmTypeDefinition> typeDefinitions = new ArrayList<EdmTypeDefinition>();

View File

@ -150,10 +150,9 @@ public final class URIUtils {
final EdmEntityContainer entityContainer, final EdmFunctionImport functionImport) {
final StringBuilder result = new StringBuilder();
// TODO: https://issues.apache.org/jira/browse/OLINGO-209
// if (!entityContainer.isDefaultEntityContainer()) {
// result.append(entityContainer.getName()).append('.');
// }
if (!entityContainer.isDefault()) {
result.append(entityContainer.getName()).append('.');
}
result.append(functionImport.getName());
return result.toString();

View File

@ -83,13 +83,12 @@ public abstract class AbstractTestITCase {
protected static final String TEST_PRODUCT_TYPE = "Microsoft.Test.OData.Services.AstoriaDefaultService.Product";
protected static final String servicesODataServiceRootURL =
"http://services.odata.org/V3/(S(csquyjnoaywmz5xcdbfhlc1p))/OData/OData.svc/";
protected static ODataClient client;
protected static String testStaticServiceRootURL;
protected static String testOpenTypeServiceRootURL;
protected static String testLargeModelServiceRootURL;
protected static String testAuthServiceRootURL;
@ -97,6 +96,7 @@ public abstract class AbstractTestITCase {
@BeforeClass
public static void setUpODataServiceRoot() throws IOException {
testStaticServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc";
testOpenTypeServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc/openType";
testLargeModelServiceRootURL = "http://localhost:9080/StaticService/V30/Static.svc/large";
testAuthServiceRootURL = "http://localhost:9080/DefaultService.svc";
}

View File

@ -18,6 +18,10 @@
*/
package org.apache.olingo.client.core.it.v3;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -33,6 +37,7 @@ import org.apache.olingo.commons.api.domain.v3.ODataProperty;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmSchema;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.geo.Geospatial;
import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
import org.apache.olingo.commons.api.edm.geo.LineString;
@ -42,9 +47,6 @@ import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
import org.apache.olingo.commons.api.edm.geo.Point;
import org.apache.olingo.commons.api.edm.geo.Polygon;
import org.apache.olingo.commons.api.format.ODataPubFormat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Ignore;
import org.junit.Test;
@ -53,14 +55,13 @@ public class OpenTypeTestITCase extends AbstractTestITCase {
@Test
public void checkOpenTypeEntityTypesExist() {
final Edm metadata = client.getRetrieveRequestFactory().
getMetadataRequest(testStaticServiceRootURL).execute().getBody();
getMetadataRequest(testOpenTypeServiceRootURL).execute().getBody();
final EdmSchema schema = metadata.getSchemas().get(0);
// TODO: https://issues.apache.org/jira/browse/OLINGO-209
// assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "Row")).isOpenType());
// assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "IndexedRow")).isOpenType());
// assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "RowIndex")).isOpenType());
assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "Row")).isOpenType());
assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "IndexedRow")).isOpenType());
assertTrue(metadata.getEntityType(new FullQualifiedName(schema.getNamespace(), "RowIndex")).isOpenType());
}
private ODataEntity readRow(final ODataPubFormat format, final String uuid) {

View File

@ -22,7 +22,7 @@ import java.util.List;
/**
* A CSDL EntityContainer element.
*
*
* <br/>
* EdmEntityContainer hold the information of EntitySets, Singletons, ActionImports and FunctionImports contained
*/
@ -33,9 +33,18 @@ public interface EdmEntityContainer extends EdmNamed {
*/
String getNamespace();
/**
* Returns whether this container is the default container in the current schema.
* <br/>
* According to CSDL specifications, this method will always return <tt>true</tt> for OData 4.0.
*
* @return whether this container is the default container in the current schema, always <tt>true</tt> for OData 4.0
*/
boolean isDefault();
/**
* Get contained Singleton by name.
*
*
* @param name
* @return {@link EdmSingleton}
*/
@ -43,7 +52,7 @@ public interface EdmEntityContainer extends EdmNamed {
/**
* Get contained EntitySet by name.
*
*
* @param name
* @return {@link EdmEntitySet}
*/
@ -51,7 +60,7 @@ public interface EdmEntityContainer extends EdmNamed {
/**
* Get contained ActionImport by name.
*
*
* @param name
* @return {@link EdmActionImport}
*/
@ -59,7 +68,7 @@ public interface EdmEntityContainer extends EdmNamed {
/**
* Get contained FunctionImport by name.
*
*
* @param name
* @return {@link EdmFunctionImport}
*/
@ -67,24 +76,28 @@ public interface EdmEntityContainer extends EdmNamed {
/**
* This method <b>DOES NOT</b> support lazy loading
*
* @return returns all entity sets for this container.
*/
List<EdmEntitySet> getEntitySets();
/**
* This method <b>DOES NOT</b> support lazy loading
*
* @return returns all function imports for this container.
*/
List<EdmFunctionImport> getFunctionImports();
/**
* This method <b>DOES NOT</b> support lazy loading
*
* @return returns all singletons for this container.
*/
List<EdmSingleton> getSingletons();
/**
* This method <b>DOES NOT</b> support lazy loading
*
* @return returns all action imports for this container.
*/
List<EdmActionImport> getActionImports();

View File

@ -28,14 +28,14 @@ public interface EdmEntityType extends EdmStructuredType {
/**
* Gets all key predicate names. In case an alias is defined for a key predicate this will be returned.
*
* @return collection of key property names of type List<String>
* @return collection of key property names of type List&lt;String&gt;
*/
List<String> getKeyPredicateNames();
/**
* Get all key properties references as list of {@link EdmKeyPropertyRef}.
*
* @return collection of key properties of type List<EdmKeyPropertyRef>
* @return collection of key properties of type List&lt;EdmKeyPropertyRef&gt;
*/
List<EdmKeyPropertyRef> getKeyPropertyRefs();
@ -54,6 +54,13 @@ public interface EdmEntityType extends EdmStructuredType {
*/
boolean hasStream();
/**
* Indicates if the entity type is an open type.
*
* @return <code>true</code> if the entity type is open
*/
boolean isOpenType();
/*
* (non-Javadoc)
*

View File

@ -24,47 +24,65 @@ import java.util.List;
* A csdl schema element
*/
public interface EdmSchema {
/**
* @return the namespace for this schema
*/
String getNamespace();
/**
* @return the alias for this schema. May be null.
*/
String getAlias();
/**
* @return all enum types for this schema
*/
List<EdmEnumType> getEnumTypes();
/**
* @return all entity types for this schema
*/
List<EdmEntityType> getEntityTypes();
/**
* @return all complex types for this schema
*/
List<EdmComplexType> getComplexTypes();
/**
* @return all actions for this schema
*/
List<EdmAction> getActions();
/**
* @return all functions for this schema
*/
List<EdmFunction> getFunctions();
/**
* @return the entity container for this schema. May be null.
*/
EdmEntityContainer getEntityContainer();
/**
* Returns the list of entity containers for this schema.
* <br/>
* According to CSDL specifications, this method will always return a singleton list for OData 4.0, containing the
* same container as returned by {@link #getEntityContainer()}.
*
* @return the list of entity containers for this schema; singleton list for OData 4.0
*/
List<EdmEntityContainer> getEntityContainers();
/**
* Returns the entity container for the given name, or null if not found.
*
* @param name entity container full qualified name
* @return the entity container for the given name, or null if not found
*/
EdmEntityContainer getEntityContainer(FullQualifiedName name);
List<EdmTypeDefinition> getTypeDefinitions();
}

View File

@ -34,23 +34,37 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
public abstract class AbstractEdmEntityContainer extends EdmNamedImpl implements EdmEntityContainer {
protected final FullQualifiedName entityContainerName;
protected final Map<String, EdmSingleton> singletons = new HashMap<String, EdmSingleton>();
private boolean allSingletonsLoaded = false;
protected final Map<String, EdmEntitySet> entitySets = new HashMap<String, EdmEntitySet>();
private boolean allEntitySetsLoaded = false;
protected final Map<String, EdmActionImport> actionImports = new HashMap<String, EdmActionImport>();
private final FullQualifiedName parentContainerName;
private boolean allActionImportsLoaded = false;
protected final Map<String, EdmFunctionImport> functionImports = new HashMap<String, EdmFunctionImport>();
private boolean allFunctionImportsLoaded = false;
public AbstractEdmEntityContainer(final Edm edm, final FullQualifiedName entityContainerName,
final FullQualifiedName parentContainerName) {
final FullQualifiedName parentContainerName) {
super(edm, entityContainerName.getName());
this.entityContainerName = entityContainerName;
this.parentContainerName = parentContainerName;
}
@Override
public boolean isDefault() {
return true;
}
@Override
public String getNamespace() {
return entityContainerName.getNamespace();

View File

@ -34,9 +34,13 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
public abstract class AbstractEdmEntityType extends AbstractEdmStructuredType implements EdmEntityType {
private final boolean hasStream;
protected EdmEntityType entityBaseType;
private final List<String> keyPredicateNames = new ArrayList<String>();
private final Map<String, EdmKeyPropertyRef> keyPropertyRefs = new LinkedHashMap<String, EdmKeyPropertyRef>();
private List<EdmKeyPropertyRef> keyPropertyRefsList;
protected AbstractEdmEntityType(final Edm edm, final FullQualifiedName typeName, final FullQualifiedName baseTypeName,
@ -111,7 +115,8 @@ public abstract class AbstractEdmEntityType extends AbstractEdmStructuredType im
public boolean hasStream() {
return hasStream;
}
@Override
protected void checkBaseType() {
//Current Client implementation doesn`t need this so I implemented an empty body here.
}

View File

@ -18,6 +18,7 @@
*/
package org.apache.olingo.commons.core.edm;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmAction;
@ -28,17 +29,26 @@ import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmSchema;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
public abstract class AbstractEdmSchemaImpl implements EdmSchema {
protected final String namespace;
private final String alias;
private List<EdmTypeDefinition> typeDefinitions;
private List<EdmEnumType> enumTypes;
private List<EdmEntityType> entityTypes;
private List<EdmComplexType> complexTypes;
private List<EdmAction> actions;
private List<EdmFunction> functions;
private EdmEntityContainer entityContainer;
public AbstractEdmSchemaImpl(String namespace, String alias) {
@ -116,6 +126,22 @@ public abstract class AbstractEdmSchemaImpl implements EdmSchema {
return entityContainer;
}
@Override
public List<EdmEntityContainer> getEntityContainers() {
return Collections.singletonList(getEntityContainer());
}
@Override
public EdmEntityContainer getEntityContainer(final FullQualifiedName name) {
return getEntityContainer() == null
? null
: name == null
? getEntityContainer()
: name.equals(new FullQualifiedName(getEntityContainer().getNamespace(), getEntityContainer().getName()))
? getEntityContainer()
: null;
}
@Override
public String getNamespace() {
return namespace;

View File

@ -36,11 +36,13 @@ import org.apache.olingo.server.api.edm.provider.PropertyRef;
public class EdmEntityTypeImpl extends AbstractEdmEntityType {
private final EdmStructuredTypeHelper helper;
private EntityType entityType;
private boolean baseTypeChecked = false;
public static EdmEntityTypeImpl getInstance(final Edm edm, final FullQualifiedName name,
final EntityType entityType) {
final EntityType entityType) {
final EdmEntityTypeImpl instance = new EdmEntityTypeImpl(edm, name, entityType);
return instance;
@ -85,5 +87,10 @@ public class EdmEntityTypeImpl extends AbstractEdmEntityType {
baseTypeChecked = true;
}
}
@Override
public boolean isOpenType() {
return entityType.isOpenType();
}
}