You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/05/08 12:41:50 UTC
[12/12] git commit: [OLINGO-260] provided proxy integration tests for
entity set reading and iteration
[OLINGO-260] provided proxy integration tests for entity set reading and iteration
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/d313bcc4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/d313bcc4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/d313bcc4
Branch: refs/heads/master
Commit: d313bcc4acf64c3ee9e59ba3a1593ff329ee7334
Parents: 58ecb3f
Author: fmartelli <fa...@gmail.com>
Authored: Thu May 8 12:41:18 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu May 8 12:41:18 2014 +0200
----------------------------------------------------------------------
.../commons/AbstractTypeInvocationHandler.java | 395 ++++++++++++++
.../commons/ComplexTypeInvocationHandler.java | 142 +++++
.../commons/EntitySetInvocationHandler.java | 31 +-
.../commons/EntityTypeInvocationHandler.java | 267 +---------
.../olingo/ext/proxy/utils/EngineUtils.java | 5 +-
.../olingo/ext/pojogen/AbstractUtility.java | 4 +
.../src/main/resources/entitySet.vm | 3 +-
.../src/main/resources/entityType.vm | 10 +-
.../src/main/resources/v30/complexType.vm | 9 +-
.../src/main/resources/v40/complexType.vm | 8 +-
fit/pom.xml | 6 +
fit/src/it/staticServiceV3/pom.xml | 2 +-
fit/src/it/staticServiceV3/verify.groovy | 2 +-
fit/src/it/staticServiceV4/pom.xml | 2 +-
fit/src/it/staticServiceV4/verify.groovy | 2 +-
fit/src/main/resources/V30/Computer/feed.xml | 207 ++++++++
fit/src/main/resources/V30/Message/feed.xml | 277 ++++++++++
.../olingo/fit/proxy/v3/AbstractTest.java | 153 ++++++
.../fit/proxy/v3/EntitySetTestITCase.java | 98 ++++
.../AllGeoCollectionTypesSet.java | 56 ++
.../astoriadefaultservice/AllGeoTypesSet.java | 54 ++
.../services/astoriadefaultservice/Car.java | 54 ++
.../astoriadefaultservice/Computer.java | 54 ++
.../astoriadefaultservice/ComputerDetail.java | 54 ++
.../astoriadefaultservice/Customer.java | 54 ++
.../astoriadefaultservice/CustomerInfo.java | 54 ++
.../astoriadefaultservice/DefaultContainer.java | 161 ++++++
.../services/astoriadefaultservice/Driver.java | 54 ++
.../astoriadefaultservice/LastLogin.java | 54 ++
.../services/astoriadefaultservice/License.java | 54 ++
.../services/astoriadefaultservice/Login.java | 54 ++
.../astoriadefaultservice/MappedEntityType.java | 54 ++
.../services/astoriadefaultservice/Message.java | 54 ++
.../MessageAttachment.java | 54 ++
.../services/astoriadefaultservice/Order.java | 54 ++
.../astoriadefaultservice/OrderLine.java | 58 ++
.../astoriadefaultservice/PageView.java | 56 ++
.../services/astoriadefaultservice/Person.java | 60 +++
.../astoriadefaultservice/PersonMetadata.java | 54 ++
.../services/astoriadefaultservice/Product.java | 56 ++
.../astoriadefaultservice/ProductDetail.java | 54 ++
.../astoriadefaultservice/ProductPhoto.java | 54 ++
.../astoriadefaultservice/ProductReview.java | 54 ++
.../astoriadefaultservice/RSAToken.java | 54 ++
.../astoriadefaultservice/package-info.java | 21 +
.../astoriadefaultservice/types/Aliases.java | 58 ++
.../types/AllSpatialCollectionTypes.java | 91 ++++
.../AllSpatialCollectionTypesCollection.java | 48 ++
.../types/AllSpatialCollectionTypes_Simple.java | 230 ++++++++
...SpatialCollectionTypes_SimpleCollection.java | 48 ++
.../types/AllSpatialTypes.java | 459 ++++++++++++++++
.../types/AllSpatialTypesCollection.java | 48 ++
.../astoriadefaultservice/types/AuditInfo.java | 73 +++
.../types/BackOrderLine.java | 204 +++++++
.../types/BackOrderLine2.java | 204 +++++++
.../types/BackOrderLine2Collection.java | 48 ++
.../types/BackOrderLineCollection.java | 48 ++
.../astoriadefaultservice/types/Car.java | 163 ++++++
.../types/CarCollection.java | 48 ++
.../types/ComplexToCategory.java | 72 +++
.../types/ComplexWithAllPrimitiveTypes.java | 149 ++++++
.../astoriadefaultservice/types/Computer.java | 136 +++++
.../types/ComputerCollection.java | 61 +++
.../types/ComputerDetail.java | 253 +++++++++
.../types/ComputerDetailCollection.java | 62 +++
.../types/ConcurrencyInfo.java | 65 +++
.../types/ContactDetails.java | 97 ++++
.../astoriadefaultservice/types/Contractor.java | 217 ++++++++
.../types/ContractorCollection.java | 48 ++
.../astoriadefaultservice/types/Customer.java | 282 ++++++++++
.../types/CustomerCollection.java | 48 ++
.../types/CustomerInfo.java | 117 ++++
.../types/CustomerInfoCollection.java | 48 ++
.../astoriadefaultservice/types/Dimensions.java | 72 +++
.../types/DiscontinuedProduct.java | 366 +++++++++++++
.../types/DiscontinuedProductCollection.java | 48 ++
.../astoriadefaultservice/types/Driver.java | 124 +++++
.../types/DriverCollection.java | 48 ++
.../astoriadefaultservice/types/Employee.java | 215 ++++++++
.../types/EmployeeCollection.java | 60 +++
.../astoriadefaultservice/types/LastLogin.java | 170 ++++++
.../types/LastLoginCollection.java | 48 ++
.../astoriadefaultservice/types/License.java | 193 +++++++
.../types/LicenseCollection.java | 48 ++
.../astoriadefaultservice/types/Login.java | 164 ++++++
.../types/LoginCollection.java | 48 ++
.../types/MappedEntityType.java | 531 +++++++++++++++++++
.../types/MappedEntityTypeCollection.java | 48 ++
.../astoriadefaultservice/types/Message.java | 259 +++++++++
.../types/MessageAttachment.java | 114 ++++
.../types/MessageAttachmentCollection.java | 48 ++
.../types/MessageCollection.java | 48 ++
.../astoriadefaultservice/types/MessageKey.java | 75 +++
.../astoriadefaultservice/types/Order.java | 158 ++++++
.../types/OrderCollection.java | 48 ++
.../astoriadefaultservice/types/OrderLine.java | 203 +++++++
.../types/OrderLineCollection.java | 48 ++
.../types/OrderLineKey.java | 75 +++
.../astoriadefaultservice/types/PageView.java | 193 +++++++
.../types/PageViewCollection.java | 48 ++
.../astoriadefaultservice/types/Person.java | 124 +++++
.../types/PersonCollection.java | 48 ++
.../types/PersonMetadata.java | 170 ++++++
.../types/PersonMetadataCollection.java | 48 ++
.../astoriadefaultservice/types/Phone.java | 65 +++
.../astoriadefaultservice/types/Product.java | 284 ++++++++++
.../types/ProductCollection.java | 61 +++
.../types/ProductDetail.java | 124 +++++
.../types/ProductDetailCollection.java | 48 ++
.../types/ProductPageView.java | 240 +++++++++
.../types/ProductPageViewCollection.java | 48 ++
.../types/ProductPhoto.java | 137 +++++
.../types/ProductPhotoCollection.java | 48 ++
.../types/ProductPhotoKey.java | 75 +++
.../types/ProductReview.java | 170 ++++++
.../types/ProductReviewCollection.java | 48 ++
.../types/ProductReviewKey.java | 86 +++
.../astoriadefaultservice/types/RSAToken.java | 124 +++++
.../types/RSATokenCollection.java | 48 ++
.../types/SpecialEmployee.java | 283 ++++++++++
.../types/SpecialEmployeeCollection.java | 48 ++
.../types/package-info.java | 21 +
.../olingo/fit/proxy/v4/AbstractTest.java | 81 +++
.../fit/proxy/v4/EntitySetTestITCase.java | 75 +++
.../services/odatawcfservice/Accounts.java | 54 ++
.../odata/services/odatawcfservice/Boss.java | 55 ++
.../odata/services/odatawcfservice/Company.java | 54 ++
.../services/odatawcfservice/Customers.java | 54 ++
.../odatawcfservice/DefaultStoredPI.java | 53 ++
.../services/odatawcfservice/Departments.java | 54 ++
.../services/odatawcfservice/Employees.java | 54 ++
.../odatawcfservice/InMemoryEntities.java | 166 ++++++
.../services/odatawcfservice/LabourUnion.java | 53 ++
.../services/odatawcfservice/OrderDetails.java | 54 ++
.../odata/services/odatawcfservice/Orders.java | 54 ++
.../odata/services/odatawcfservice/People.java | 58 ++
.../odatawcfservice/ProductDetails.java | 54 ++
.../odatawcfservice/ProductReviews.java | 54 ++
.../services/odatawcfservice/Products.java | 54 ++
.../services/odatawcfservice/PublicCompany.java | 54 ++
.../services/odatawcfservice/StoredPIs.java | 54 ++
.../odatawcfservice/SubscriptionTemplates.java | 54 ++
.../services/odatawcfservice/VipCustomer.java | 53 ++
.../services/odatawcfservice/package-info.java | 21 +
.../odatawcfservice/types/AccessLevel.java | 47 ++
.../services/odatawcfservice/types/Account.java | 204 +++++++
.../types/AccountCollection.java | 75 +++
.../odatawcfservice/types/AccountInfo.java | 88 +++
.../services/odatawcfservice/types/Address.java | 105 ++++
.../services/odatawcfservice/types/Asset.java | 137 +++++
.../odatawcfservice/types/AssetCollection.java | 48 ++
.../services/odatawcfservice/types/Club.java | 114 ++++
.../odatawcfservice/types/ClubCollection.java | 48 ++
.../services/odatawcfservice/types/Color.java | 45 ++
.../services/odatawcfservice/types/Company.java | 243 +++++++++
.../odatawcfservice/types/CompanyAddress.java | 133 +++++
.../odatawcfservice/types/CompanyCategory.java | 46 ++
.../types/CompanyCollection.java | 68 +++
.../odatawcfservice/types/CreditCardPI.java | 293 ++++++++++
.../types/CreditCardPICollection.java | 48 ++
.../odatawcfservice/types/CreditRecord.java | 160 ++++++
.../types/CreditRecordCollection.java | 48 ++
.../odatawcfservice/types/Customer.java | 353 ++++++++++++
.../types/CustomerCollection.java | 48 ++
.../odatawcfservice/types/Department.java | 124 +++++
.../types/DepartmentCollection.java | 48 ++
.../odatawcfservice/types/Employee.java | 320 +++++++++++
.../types/EmployeeCollection.java | 48 ++
.../odatawcfservice/types/GiftCard.java | 173 ++++++
.../types/GiftCardCollection.java | 62 +++
.../odatawcfservice/types/HomeAddress.java | 123 +++++
.../odatawcfservice/types/LabourUnion.java | 114 ++++
.../types/LabourUnionCollection.java | 48 ++
.../services/odatawcfservice/types/Order.java | 190 +++++++
.../odatawcfservice/types/OrderCollection.java | 48 ++
.../odatawcfservice/types/OrderDetail.java | 203 +++++++
.../types/OrderDetailCollection.java | 48 ++
.../odatawcfservice/types/OrderDetailKey.java | 75 +++
.../types/PaymentInstrument.java | 167 ++++++
.../types/PaymentInstrumentCollection.java | 48 ++
.../services/odatawcfservice/types/Person.java | 283 ++++++++++
.../odatawcfservice/types/PersonCollection.java | 69 +++
.../services/odatawcfservice/types/Product.java | 305 +++++++++++
.../types/ProductCollection.java | 69 +++
.../odatawcfservice/types/ProductDetail.java | 192 +++++++
.../types/ProductDetailCollection.java | 61 +++
.../odatawcfservice/types/ProductDetailKey.java | 75 +++
.../odatawcfservice/types/ProductReview.java | 206 +++++++
.../types/ProductReviewCollection.java | 48 ++
.../odatawcfservice/types/ProductReviewKey.java | 97 ++++
.../odatawcfservice/types/PublicCompany.java | 278 ++++++++++
.../types/PublicCompanyCollection.java | 48 ++
.../odatawcfservice/types/Statement.java | 160 ++++++
.../types/StatementCollection.java | 48 ++
.../odatawcfservice/types/StoredPI.java | 160 ++++++
.../types/StoredPICollection.java | 48 ++
.../odatawcfservice/types/Subscription.java | 183 +++++++
.../types/SubscriptionCollection.java | 48 ++
.../odatawcfservice/types/package-info.java | 21 +
...che.olingo.ext.proxy.api.AbstractComplexType | 14 +
pom.xml | 2 +
201 files changed, 20026 insertions(+), 286 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
new file mode 100644
index 0000000..9378eb2
--- /dev/null
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractTypeInvocationHandler.java
@@ -0,0 +1,395 @@
+/*
+ * 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.ext.proxy.commons;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.core.uri.URIUtils;
+import org.apache.olingo.commons.api.domain.CommonODataEntity;
+import org.apache.olingo.commons.api.domain.CommonODataProperty;
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
+import org.apache.olingo.commons.api.domain.ODataInlineEntity;
+import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
+import org.apache.olingo.commons.api.domain.ODataLink;
+import org.apache.olingo.commons.api.domain.ODataLinked;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.ext.proxy.EntityContainerFactory;
+import org.apache.olingo.ext.proxy.api.AbstractEntityCollection;
+import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
+import org.apache.olingo.ext.proxy.api.annotations.EntityType;
+import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
+import org.apache.olingo.ext.proxy.api.annotations.Property;
+import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
+import org.apache.olingo.ext.proxy.context.EntityContext;
+import org.apache.olingo.ext.proxy.utils.ClassUtils;
+import org.apache.olingo.ext.proxy.utils.EngineUtils;
+
+public abstract class AbstractTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?>>
+ extends AbstractInvocationHandler<C> {
+
+ private static final long serialVersionUID = 2629912294765040037L;
+
+ protected final Class<?> typeRef;
+
+ protected Map<String, Object> propertyChanges = new HashMap<String, Object>();
+
+ protected Map<NavigationProperty, Object> linkChanges = new HashMap<NavigationProperty, Object>();
+
+ protected int propertiesTag;
+
+ protected int linksTag;
+
+ protected final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
+
+ protected final EntityTypeInvocationHandler<C> targetHandler;
+
+ protected ODataLinked linked;
+
+ @SuppressWarnings("unchecked")
+ protected AbstractTypeInvocationHandler(
+ final C client,
+ final Class<?> typeRef,
+ final ODataLinked linked,
+ final EntityContainerInvocationHandler<C> containerHandler) {
+ super(client, containerHandler);
+ this.linked = linked;
+ this.typeRef = typeRef;
+ this.propertiesTag = 0;
+ this.linksTag = 0;
+ this.targetHandler = EntityTypeInvocationHandler.class.cast(this);
+ }
+
+ protected AbstractTypeInvocationHandler(
+ final C client,
+ final Class<?> typeRef,
+ final ODataLinked linked,
+ final EntityTypeInvocationHandler<C> targetHandler) {
+ super(client, targetHandler.containerHandler);
+ this.linked = linked;
+ this.typeRef = typeRef;
+ this.propertiesTag = 0;
+ this.linksTag = 0;
+ this.targetHandler = targetHandler;
+ }
+
+ public abstract FullQualifiedName getName();
+
+ public Class<?> getTypeRef() {
+ return typeRef;
+ }
+
+ public Map<String, Object> getPropertyChanges() {
+ return propertyChanges;
+ }
+
+ public Map<NavigationProperty, Object> getLinkChanges() {
+ return linkChanges;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ if (isSelfMethod(method, args)) {
+ return invokeSelfMethod(method, args);
+ } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
+ final Class<?> returnType = method.getReturnType();
+
+ return Proxy.newProxyInstance(
+ Thread.currentThread().getContextClassLoader(),
+ new Class<?>[] {returnType},
+ OperationInvocationHandler.getInstance(targetHandler));
+ } else if (method.getName().startsWith("get")) {
+ // Assumption: for each getter will always exist a setter and viceversa.
+ // get method annotation and check if it exists as expected
+ final Object res;
+
+ final Method getter = typeRef.getMethod(method.getName());
+
+ final Property property = ClassUtils.getAnnotation(Property.class, getter);
+ if (property == null) {
+ final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
+ if (navProp == null) {
+ throw new UnsupportedOperationException("Unsupported method " + method.getName());
+ } else {
+ // if the getter refers to a navigation property ... navigate and follow link if necessary
+ res = getNavigationPropertyValue(navProp, getter);
+ }
+ } else {
+ // if the getter refers to a property .... get property from wrapped entity
+ res = getPropertyValue(property, getter.getGenericReturnType());
+ }
+
+ // attach the current handler
+ attach();
+
+ return res;
+ } else if (method.getName().startsWith("set")) {
+ // get the corresponding getter method (see assumption above)
+ final String getterName = method.getName().replaceFirst("set", "get");
+ final Method getter = typeRef.getMethod(getterName);
+
+ final Property property = ClassUtils.getAnnotation(Property.class, getter);
+ if (property == null) {
+ final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
+ if (navProp == null) {
+ throw new UnsupportedOperationException("Unsupported method " + method.getName());
+ } else {
+ // if the getter refers to a navigation property ...
+ if (ArrayUtils.isEmpty(args) || args.length != 1) {
+ throw new IllegalArgumentException("Invalid argument");
+ }
+
+ setNavigationPropertyValue(navProp, args[0]);
+ }
+ } else {
+ setPropertyValue(property, args[0]);
+ }
+
+ return ClassUtils.returnVoid();
+ } else if (method.getName().startsWith("new")) {
+ // get the corresponding getter method (see assumption above)
+ final String getterName = method.getName().replaceFirst("new", "get");
+ final Method getter = typeRef.getMethod(getterName);
+
+ final Property property = ClassUtils.getAnnotation(Property.class, getter);
+ if (property == null) {
+ throw new UnsupportedOperationException("Unsupported method " + method.getName());
+ }
+
+ return newComplex(property.name(), getter.getReturnType());
+ } else {
+ throw new UnsupportedOperationException("Method not found: " + method);
+ }
+ }
+
+ protected void attach() {
+ if (!entityContext.isAttached(targetHandler)) {
+ entityContext.attach(targetHandler, AttachedEntityStatus.ATTACHED);
+ }
+ }
+
+ protected void attach(final AttachedEntityStatus status) {
+ attach(status, true);
+ }
+
+ protected void attach(final AttachedEntityStatus status, final boolean override) {
+ if (entityContext.isAttached(targetHandler)) {
+ if (override) {
+ entityContext.setStatus(targetHandler, status);
+ }
+ } else {
+ entityContext.attach(targetHandler, status);
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private <NE> NE newComplex(final String propertyName, final Class<NE> reference) {
+ final Class<?> complexTypeRef;
+ final boolean isCollection;
+ if (Collection.class.isAssignableFrom(reference)) {
+ complexTypeRef = ClassUtils.extractTypeArg(reference);
+ isCollection = true;
+ } else {
+ complexTypeRef = reference;
+ isCollection = false;
+ }
+
+ final ComplexType annotation = complexTypeRef.getAnnotation(ComplexType.class);
+ if (annotation == null) {
+ throw new IllegalArgumentException("Invalid complex type " + complexTypeRef);
+ }
+
+ final FullQualifiedName typeName =
+ new FullQualifiedName(ClassUtils.getNamespace(complexTypeRef), annotation.name());
+
+ final ODataComplexValue<? extends CommonODataProperty> complex =
+ client.getObjectFactory().newComplexValue(typeName.toString());
+
+ final ComplexTypeInvocationHandler<?> handler =
+ ComplexTypeInvocationHandler.getInstance(complex, complexTypeRef, targetHandler);
+
+ if (isCollection) {
+ Object value = propertyChanges.get(propertyName);
+
+ if (value == null) {
+ value = new ArrayList<ComplexTypeInvocationHandler<?>>();
+ propertyChanges.put(propertyName, value);
+ }
+
+ ((Collection<ComplexTypeInvocationHandler<?>>) value).add(handler);
+ } else {
+ propertyChanges.put(propertyName, handler);
+ }
+
+ attach(AttachedEntityStatus.CHANGED);
+
+ return (NE) Proxy.newProxyInstance(
+ Thread.currentThread().getContextClassLoader(),
+ new Class<?>[] {complexTypeRef},
+ handler);
+ }
+
+ private Object getNavigationPropertyValue(final NavigationProperty property, final Method getter) {
+ final Class<?> type = getter.getReturnType();
+ final Class<?> collItemType;
+ if (AbstractEntityCollection.class.isAssignableFrom(type)) {
+ final Type[] entityCollectionParams =
+ ((ParameterizedType) type.getGenericInterfaces()[0]).getActualTypeArguments();
+ collItemType = (Class<?>) entityCollectionParams[0];
+ } else {
+ collItemType = type;
+ }
+
+ final Object navPropValue;
+
+ if (linkChanges.containsKey(property)) {
+ navPropValue = linkChanges.get(property);
+ } else {
+ final ODataLink link = EngineUtils.getNavigationLink(property.name(), linked);
+ if (link instanceof ODataInlineEntity) {
+ // return entity
+ navPropValue = getEntityProxy(
+ ((ODataInlineEntity) link).getEntity(),
+ property.targetContainer(),
+ property.targetEntitySet(),
+ type,
+ false);
+ } else if (link instanceof ODataInlineEntitySet) {
+ // return entity set
+ navPropValue = getEntityCollection(
+ collItemType,
+ type,
+ property.targetContainer(),
+ ((ODataInlineEntitySet) link).getEntitySet(),
+ link.getLink(),
+ false);
+ } else {
+ // navigate
+ final URI uri = URIUtils.getURI(
+ containerHandler.getFactory().getServiceRoot(), link.getLink().toASCIIString());
+
+ if (AbstractEntityCollection.class.isAssignableFrom(type)) {
+ navPropValue = getEntityCollection(
+ collItemType,
+ type,
+ property.targetContainer(),
+ client.getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody(),
+ uri,
+ true);
+ } else {
+ final ODataRetrieveResponse<CommonODataEntity> res =
+ client.getRetrieveRequestFactory().getEntityRequest(uri).execute();
+
+ navPropValue = getEntityProxy(
+ res.getBody(),
+ property.targetContainer(),
+ property.targetEntitySet(),
+ type,
+ res.getETag(),
+ true);
+ }
+ }
+
+ if (navPropValue != null) {
+ int checkpoint = linkChanges.hashCode();
+ linkChanges.put(property, navPropValue);
+ updateLinksTag(checkpoint);
+ }
+ }
+
+ return navPropValue;
+ }
+
+ protected abstract Object getPropertyValue(final String name, final Type type);
+
+ private Object getPropertyValue(final Property property, final Type type) {
+ return getPropertyValue(property.name(), type);
+ }
+
+ public Object getAdditionalProperty(final String name) {
+ return getPropertyValue(name, null);
+ }
+
+ public abstract Collection<String> getAdditionalPropertyNames();
+
+ private void setNavigationPropertyValue(final NavigationProperty property, final Object value) {
+ // 1) attach source entity
+ if (!entityContext.isAttached(targetHandler)) {
+ entityContext.attach(targetHandler, AttachedEntityStatus.CHANGED);
+ }
+
+ // 2) attach the target entity handlers
+ for (Object link : AbstractEntityCollection.class.isAssignableFrom(value.getClass())
+ ? (AbstractEntityCollection) value : Collections.singleton(value)) {
+
+ final InvocationHandler etih = Proxy.getInvocationHandler(link);
+ if (!(etih instanceof EntityTypeInvocationHandler)) {
+ throw new IllegalArgumentException("Invalid argument type");
+ }
+
+ @SuppressWarnings("unchecked")
+ final EntityTypeInvocationHandler<C> targetHandler = (EntityTypeInvocationHandler<C>) etih;
+ if (!targetHandler.getTypeRef().isAnnotationPresent(EntityType.class)) {
+ throw new IllegalArgumentException("Invalid argument type " + targetHandler.getTypeRef().getSimpleName());
+ }
+
+ if (!entityContext.isAttached(targetHandler)) {
+ entityContext.attach(targetHandler, AttachedEntityStatus.LINKED);
+ }
+ }
+
+ // 3) add links
+ linkChanges.put(property, value);
+ }
+
+ protected abstract void setPropertyValue(final Property property, final Object value);
+
+ public void addAdditionalProperty(final String name, final Object value) {
+ propertyChanges.put(name, value);
+ if (!entityContext.isAttached(targetHandler)) {
+ entityContext.attach(targetHandler, AttachedEntityStatus.CHANGED);
+ }
+ }
+
+ protected void updatePropertiesTag(final int checkpoint) {
+ if (checkpoint == propertiesTag) {
+ propertiesTag = propertyChanges.hashCode();
+ }
+ }
+
+ private void updateLinksTag(final int checkpoint) {
+ if (checkpoint == linksTag) {
+ linksTag = linkChanges.hashCode();
+ }
+ }
+
+ public abstract boolean isChanged();
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
new file mode 100644
index 0000000..f57bf7e
--- /dev/null
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexTypeInvocationHandler.java
@@ -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.ext.proxy.commons;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
+import org.apache.olingo.commons.api.domain.CommonODataProperty;
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
+import org.apache.olingo.commons.api.domain.ODataLinked;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.ext.proxy.api.annotations.Property;
+import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
+import org.apache.olingo.ext.proxy.utils.EngineUtils;
+
+public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?>>
+ extends AbstractTypeInvocationHandler<C> {
+
+ private static final long serialVersionUID = 2629912294765040037L;
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ static ComplexTypeInvocationHandler<?> getInstance(
+ final ODataComplexValue<?> complex,
+ final Class<?> typeRef,
+ final EntityTypeInvocationHandler<?> handler) {
+
+ return new ComplexTypeInvocationHandler(complex, typeRef, handler);
+ }
+
+ private ComplexTypeInvocationHandler(
+ final ODataComplexValue<?> complex,
+ final Class<?> typeRef,
+ final EntityTypeInvocationHandler<C> handler) {
+
+ super(handler.containerHandler.getClient(), typeRef, (ODataLinked) complex, handler);
+ }
+
+ public void setComplex(final ODataComplexValue<?> complex) {
+ this.linked = (ODataLinked) complex;
+ this.propertyChanges.clear();
+ this.linkChanges.clear();
+ this.propertiesTag = 0;
+ this.linksTag = 0;
+ }
+
+ @Override
+ public FullQualifiedName getName() {
+ return new FullQualifiedName(((ODataComplexValue<?>) this.linked).getTypeName());
+ }
+
+ public ODataComplexValue<?> getComplex() {
+ return (ODataComplexValue<?>) this.linked;
+ }
+
+ @Override
+ protected Object getPropertyValue(final String name, final Type type) {
+ try {
+ final Object res;
+
+ if (propertyChanges.containsKey(name)) {
+ res = propertyChanges.get(name);
+ } else {
+
+ res = type == null
+ ? EngineUtils.getValueFromProperty(
+ client.getCachedEdm(), ((ODataComplexValue<?>) this.linked).get(name))
+ : EngineUtils.getValueFromProperty(
+ client.getCachedEdm(), ((ODataComplexValue<?>) this.linked).get(name), type);
+
+ if (res != null) {
+ int checkpoint = propertyChanges.hashCode();
+ propertyChanges.put(name, res);
+ updatePropertiesTag(checkpoint);
+ }
+ }
+
+ return res;
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Error getting value for property '" + name + "'", e);
+ }
+ }
+
+ @Override
+ public Collection<String> getAdditionalPropertyNames() {
+ final Set<String> res = new HashSet<String>(propertyChanges.keySet());
+ final Set<String> propertyNames = new HashSet<String>();
+ for (Method method : typeRef.getMethods()) {
+ final Annotation ann = method.getAnnotation(Property.class);
+ if (ann != null) {
+ final String property = ((Property) ann).name();
+ propertyNames.add(property);
+
+ // maybe someone could add a normal attribute to the additional set
+ res.remove(property);
+ }
+ }
+
+ for (Iterator<?> itor = ((ODataComplexValue<?>) this.linked).iterator(); itor.hasNext();) {
+ CommonODataProperty property = (CommonODataProperty) itor.next();
+ if (!propertyNames.contains(property.getName())) {
+ res.add(property.getName());
+ }
+ }
+
+ return res;
+ }
+
+ @Override
+ protected void setPropertyValue(final Property property, final Object value) {
+ propertyChanges.put(property.name(), value);
+
+ if (!entityContext.isAttached(targetHandler)) {
+ entityContext.attach(targetHandler, AttachedEntityStatus.CHANGED);
+ }
+ }
+
+ @Override
+ public boolean isChanged() {
+ return targetHandler.isChanged();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
index b800b31..244db50 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
@@ -56,9 +56,9 @@ import org.apache.olingo.ext.proxy.utils.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class EntitySetInvocationHandler<C extends CommonEdmEnabledODataClient<?>,
- T extends Serializable, KEY extends Serializable, EC extends AbstractEntityCollection<T>>
- extends AbstractInvocationHandler
+class EntitySetInvocationHandler<C extends CommonEdmEnabledODataClient<?>, T extends Serializable,
+ KEY extends Serializable, EC extends AbstractEntityCollection<T>>
+ extends AbstractInvocationHandler<C>
implements AbstractEntitySet<T, KEY, EC> {
private static final long serialVersionUID = 2629912294765040027L;
@@ -86,7 +86,7 @@ class EntitySetInvocationHandler<C extends CommonEdmEnabledODataClient<?>,
@SuppressWarnings("unchecked")
private EntitySetInvocationHandler(
final Class<?> ref,
- final EntityContainerInvocationHandler<?> containerHandler) {
+ final EntityContainerInvocationHandler<C> containerHandler) {
super(containerHandler.getClient(), containerHandler);
@@ -330,13 +330,20 @@ class EntitySetInvocationHandler<C extends CommonEdmEnabledODataClient<?>,
@SuppressWarnings("unchecked")
@Override
public <S extends T, SEC extends AbstractEntityCollection<S>> SEC getAll(final Class<SEC> collTypeRef) {
- final Class<S> typeRef = (Class<S>) ClassUtils.extractTypeArg(collTypeRef);
+ final Class<S> ref = (Class<S>) ClassUtils.extractTypeArg(collTypeRef);
+ final Class<S> oref = (Class<S>) ClassUtils.extractTypeArg(this.collTypeRef);
- final URI entitySetURI = client.getURIBuilder(this.uri.toASCIIString()).appendNavigationSegment(
- new FullQualifiedName(ClassUtils.getNamespace(typeRef), ClassUtils.getEntityTypeName(typeRef)).toString()).
- build();
+ final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(this.uri.toASCIIString());
- return fetchWholeEntitySet(entitySetURI, typeRef, collTypeRef);
+ final URI entitySetURI;
+ if (oref.equals(ref)) {
+ entitySetURI = uriBuilder.build();
+ } else {
+ entitySetURI = uriBuilder.appendDerivedEntityTypeSegment(new FullQualifiedName(
+ ClassUtils.getNamespace(ref), ClassUtils.getEntityTypeName(ref)).toString()).build();
+ }
+
+ return fetchWholeEntitySet(entitySetURI, ref, collTypeRef);
}
@Override
@@ -391,10 +398,6 @@ class EntitySetInvocationHandler<C extends CommonEdmEnabledODataClient<?>,
@Override
public EntitySetIterator<T, KEY, EC> iterator() {
- return new EntitySetIterator<T, KEY, EC>(
- client.getURIBuilder(this.uri.toASCIIString()).appendNavigationSegment(
- new FullQualifiedName(ClassUtils.getNamespace(typeRef), ClassUtils.getEntityTypeName(typeRef)).toString()).
- build(),
- this);
+ return new EntitySetIterator<T, KEY, EC>(client.getURIBuilder(this.uri.toASCIIString()).build(), this);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
index d738b5b..bcdbc4e 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityTypeInvocationHandler.java
@@ -20,68 +20,43 @@ package org.apache.olingo.ext.proxy.commons;
import java.io.InputStream;
import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
-import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
-import org.apache.olingo.commons.api.domain.ODataInlineEntity;
-import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
-import org.apache.olingo.commons.api.domain.ODataLink;
+import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataMediaFormat;
-import org.apache.olingo.ext.proxy.EntityContainerFactory;
-import org.apache.olingo.ext.proxy.api.AbstractEntityCollection;
import org.apache.olingo.ext.proxy.api.annotations.EntityType;
-import org.apache.olingo.ext.proxy.api.annotations.NavigationProperty;
import org.apache.olingo.ext.proxy.api.annotations.Property;
import org.apache.olingo.ext.proxy.context.AttachedEntityStatus;
-import org.apache.olingo.ext.proxy.context.EntityContext;
import org.apache.olingo.ext.proxy.context.EntityUUID;
-import org.apache.olingo.ext.proxy.utils.ClassUtils;
import org.apache.olingo.ext.proxy.utils.EngineUtils;
public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?>>
- extends AbstractInvocationHandler<C> {
+ extends AbstractTypeInvocationHandler<C> {
private static final long serialVersionUID = 2629912294765040037L;
private CommonODataEntity entity;
- private final Class<?> typeRef;
-
- private Map<String, Object> propertyChanges = new HashMap<String, Object>();
-
private Map<String, InputStream> streamedPropertyChanges = new HashMap<String, InputStream>();
- private Map<NavigationProperty, Object> linkChanges = new HashMap<NavigationProperty, Object>();
-
private InputStream stream;
private EntityUUID uuid;
- private final EntityContext entityContext = EntityContainerFactory.getContext().entityContext();
-
- private int propertiesTag;
-
- private int linksTag;
-
static EntityTypeInvocationHandler<?> getInstance(
final CommonODataEntity entity,
final EntitySetInvocationHandler<?, ?, ?, ?> entitySet,
@@ -111,8 +86,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
final Class<?> typeRef,
final EntityContainerInvocationHandler<C> containerHandler) {
- super(containerHandler.getClient(), containerHandler);
- this.typeRef = typeRef;
+ super(containerHandler.getClient(), typeRef, (ODataLinked) entity, containerHandler);
this.entity = entity;
this.entity.setMediaEntity(typeRef.getAnnotation(EntityType.class).hasStream());
@@ -124,8 +98,6 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
EngineUtils.getKey(client.getCachedEdm(), typeRef, entity));
this.stream = null;
- this.propertiesTag = 0;
- this.linksTag = 0;
}
public void setEntity(final CommonODataEntity entity) {
@@ -150,6 +122,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
return uuid;
}
+ @Override
public FullQualifiedName getName() {
return this.entity.getTypeName();
}
@@ -162,22 +135,10 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
return uuid.getEntitySetName();
}
- public Class<?> getTypeRef() {
- return typeRef;
- }
-
public CommonODataEntity getEntity() {
return entity;
}
- public Map<String, Object> getPropertyChanges() {
- return propertyChanges;
- }
-
- public Map<NavigationProperty, Object> getLinkChanges() {
- return linkChanges;
- }
-
/**
* Gets the current ETag defined into the wrapped entity.
*
@@ -197,142 +158,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
}
@Override
- @SuppressWarnings("unchecked")
- public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- if (isSelfMethod(method, args)) {
- return invokeSelfMethod(method, args);
- } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
- final Class<?> returnType = method.getReturnType();
-
- return Proxy.newProxyInstance(
- Thread.currentThread().getContextClassLoader(),
- new Class<?>[] {returnType},
- OperationInvocationHandler.getInstance(this));
- } else if (method.getName().startsWith("get")) {
- // Assumption: for each getter will always exist a setter and viceversa.
- // get method annotation and check if it exists as expected
- final Object res;
-
- final Method getter = typeRef.getMethod(method.getName());
-
- final Property property = ClassUtils.getAnnotation(Property.class, getter);
- if (property == null) {
- final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
- if (navProp == null) {
- throw new UnsupportedOperationException("Unsupported method " + method.getName());
- } else {
- // if the getter refers to a navigation property ... navigate and follow link if necessary
- res = getNavigationPropertyValue(navProp, getter);
- }
- } else {
- // if the getter refers to a property .... get property from wrapped entity
- res = getPropertyValue(property, getter.getGenericReturnType());
- }
-
- // attach the current handler
- attach();
-
- return res;
- } else if (method.getName().startsWith("set")) {
- // get the corresponding getter method (see assumption above)
- final String getterName = method.getName().replaceFirst("set", "get");
- final Method getter = typeRef.getMethod(getterName);
-
- final Property property = ClassUtils.getAnnotation(Property.class, getter);
- if (property == null) {
- final NavigationProperty navProp = ClassUtils.getAnnotation(NavigationProperty.class, getter);
- if (navProp == null) {
- throw new UnsupportedOperationException("Unsupported method " + method.getName());
- } else {
- // if the getter refers to a navigation property ...
- if (ArrayUtils.isEmpty(args) || args.length != 1) {
- throw new IllegalArgumentException("Invalid argument");
- }
-
- setNavigationPropertyValue(navProp, args[0]);
- }
- } else {
- setPropertyValue(property, args[0]);
- }
-
- return ClassUtils.returnVoid();
- } else {
- throw new UnsupportedOperationException("Method not found: " + method);
- }
- }
-
- private Object getNavigationPropertyValue(final NavigationProperty property, final Method getter) {
- final Class<?> type = getter.getReturnType();
- final Class<?> collItemType;
- if (AbstractEntityCollection.class.isAssignableFrom(type)) {
- final Type[] entityCollectionParams =
- ((ParameterizedType) type.getGenericInterfaces()[0]).getActualTypeArguments();
- collItemType = (Class<?>) entityCollectionParams[0];
- } else {
- collItemType = type;
- }
-
- final Object navPropValue;
-
- if (linkChanges.containsKey(property)) {
- navPropValue = linkChanges.get(property);
- } else {
- final ODataLink link = EngineUtils.getNavigationLink(property.name(), entity);
- if (link instanceof ODataInlineEntity) {
- // return entity
- navPropValue = getEntityProxy(
- ((ODataInlineEntity) link).getEntity(),
- property.targetContainer(),
- property.targetEntitySet(),
- type,
- false);
- } else if (link instanceof ODataInlineEntitySet) {
- // return entity set
- navPropValue = getEntityCollection(
- collItemType,
- type,
- property.targetContainer(),
- ((ODataInlineEntitySet) link).getEntitySet(),
- link.getLink(),
- false);
- } else {
- // navigate
- final URI uri = URIUtils.getURI(
- containerHandler.getFactory().getServiceRoot(), link.getLink().toASCIIString());
-
- if (AbstractEntityCollection.class.isAssignableFrom(type)) {
- navPropValue = getEntityCollection(
- collItemType,
- type,
- property.targetContainer(),
- client.getRetrieveRequestFactory().getEntitySetRequest(uri).execute().getBody(),
- uri,
- true);
- } else {
- final ODataRetrieveResponse<CommonODataEntity> res =
- client.getRetrieveRequestFactory().getEntityRequest(uri).execute();
-
- navPropValue = getEntityProxy(
- res.getBody(),
- property.targetContainer(),
- property.targetEntitySet(),
- type,
- res.getETag(),
- true);
- }
- }
-
- if (navPropValue != null) {
- int checkpoint = linkChanges.hashCode();
- linkChanges.put(property, navPropValue);
- updateLinksTag(checkpoint);
- }
- }
-
- return navPropValue;
- }
-
- private Object getPropertyValue(final String name, final Type type) {
+ protected Object getPropertyValue(final String name, final Type type) {
try {
final Object res;
@@ -359,18 +185,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
}
}
- private Object getPropertyValue(final Property property, final Type type) {
- if (!(type instanceof ParameterizedType) && (Class<?>) type == InputStream.class) {
- return getStreamedProperty(property);
- } else {
- return getPropertyValue(property.name(), type);
- }
- }
-
- public Object getAdditionalProperty(final String name) {
- return getPropertyValue(name, null);
- }
-
+ @Override
public Collection<String> getAdditionalPropertyNames() {
final Set<String> res = new HashSet<String>(propertyChanges.keySet());
final Set<String> propertyNames = new HashSet<String>();
@@ -394,36 +209,8 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
return res;
}
- private void setNavigationPropertyValue(final NavigationProperty property, final Object value) {
- // 1) attach source entity
- attach(AttachedEntityStatus.CHANGED, false);
-
- // 2) attach the target entity handlers
- for (Object link : AbstractEntityCollection.class.isAssignableFrom(value.getClass())
- ? (AbstractEntityCollection) value : Collections.singleton(value)) {
-
- final InvocationHandler etih = Proxy.getInvocationHandler(link);
- if (!(etih instanceof EntityTypeInvocationHandler)) {
- throw new IllegalArgumentException("Invalid argument type");
- }
-
- @SuppressWarnings("unchecked")
- final EntityTypeInvocationHandler<C> handler = (EntityTypeInvocationHandler<C>) etih;
- if (!handler.getTypeRef().isAnnotationPresent(EntityType.class)) {
- throw new IllegalArgumentException(
- "Invalid argument type " + handler.getTypeRef().getSimpleName());
- }
-
- if (!entityContext.isAttached(handler)) {
- entityContext.attach(handler, AttachedEntityStatus.LINKED);
- }
- }
-
- // 3) add links
- linkChanges.put(property, value);
- }
-
- private void setPropertyValue(final Property property, final Object value) {
+ @Override
+ protected void setPropertyValue(final Property property, final Object value) {
if (property.type().equalsIgnoreCase("Edm.Stream")) {
setStreamedProperty(property, (InputStream) value);
} else {
@@ -433,23 +220,7 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
attach(AttachedEntityStatus.CHANGED);
}
- public void addAdditionalProperty(final String name, final Object value) {
- propertyChanges.put(name, value);
- attach(AttachedEntityStatus.CHANGED);
- }
-
- private void updatePropertiesTag(final int checkpoint) {
- if (checkpoint == propertiesTag) {
- propertiesTag = propertyChanges.hashCode();
- }
- }
-
- private void updateLinksTag(final int checkpoint) {
- if (checkpoint == linksTag) {
- linksTag = linkChanges.hashCode();
- }
- }
-
+ @Override
public boolean isChanged() {
return this.linkChanges.hashCode() != this.linksTag
|| this.propertyChanges.hashCode() != this.propertiesTag
@@ -524,26 +295,6 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
streamedPropertyChanges.put(property.name(), input);
}
- private void attach() {
- if (!entityContext.isAttached(this)) {
- entityContext.attach(this, AttachedEntityStatus.ATTACHED);
- }
- }
-
- private void attach(final AttachedEntityStatus status) {
- attach(status, true);
- }
-
- private void attach(final AttachedEntityStatus status, final boolean override) {
- if (entityContext.isAttached(this)) {
- if (override) {
- entityContext.setStatus(this, status);
- }
- } else {
- entityContext.attach(this, status);
- }
- }
-
@Override
public String toString() {
return uuid.toString();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/EngineUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/EngineUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/EngineUtils.java
index f3e2c62..53f73c5 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/EngineUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/EngineUtils.java
@@ -36,6 +36,7 @@ import org.apache.olingo.client.core.edm.xml.AbstractComplexType;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataLink;
+import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmType;
@@ -60,9 +61,9 @@ public final class EngineUtils {
// Empty private constructor for static utility classes
}
- public static ODataLink getNavigationLink(final String name, final CommonODataEntity entity) {
+ public static ODataLink getNavigationLink(final String name, final ODataLinked complex) {
ODataLink res = null;
- final List<ODataLink> links = entity.getNavigationLinks();
+ final List<ODataLink> links = complex.getNavigationLinks();
for (int i = 0; i < links.size() && res == null; i++) {
if (links.get(i).getName().equalsIgnoreCase(name)) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
index fab1893..1f7562f 100644
--- a/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
+++ b/ext/pojogen-maven-plugin/src/main/java/org/apache/olingo/ext/pojogen/AbstractUtility.java
@@ -98,6 +98,10 @@ public abstract class AbstractUtility {
return getEdmTypeInfo(singleton.getEntityType().getFullQualifiedName().toString());
}
+ public boolean isComplex(final FullQualifiedName fqn) {
+ return metadata.getComplexType(fqn) != null;
+ }
+
public Map<String, String> getEntityKeyType(final EdmSingleton singleton) {
return getEntityKeyType(singleton.getEntityType());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm b/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
index 49c8212..d16fcdb 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entitySet.vm
@@ -54,7 +54,8 @@ import javax.xml.datatype.Duration;
#end
#parse( "${odataVersion}/entitySet.vm" )
-public interface $utility.capitalize($entitySet.Name) extends AbstractEntitySet<$utility.getJavaType($entitySet.EntityType), $type, $utility.getJavaType($entitySet.EntityType)Collection> {
+public interface $utility.capitalize($entitySet.Name)
+ extends AbstractEntitySet<$utility.getJavaType($entitySet.EntityType), $type, $utility.getJavaType($entitySet.EntityType)Collection> {
#foreach( $dos in $utility.getDescendantsOrSelf($utility.getEdmType($entitySet)) )
#set( $djt = $utility.getJavaType($dos) )
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
index e831d93..cdb7399 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/entityType.vm
@@ -62,7 +62,8 @@ import javax.xml.datatype.Duration;
hasStream = $entityType.hasStream(),
isAbstract = $entityType.Abstract#if($entityType.getBaseType()),
baseType = "$entityType.getBaseType().getFullQualifiedName().toString()"#end)
-public interface $utility.capitalize($entityType.Name) extends #if( $entityType.getBaseType() )$utility.getJavaType($entityType.getBaseType())#{elseif}( $entityType.isOpenType() )AbstractOpenType#{else}Serializable#end {
+public interface $utility.capitalize($entityType.Name)
+ extends #if( $entityType.getBaseType() )$utility.getJavaType($entityType.getBaseType())#{elseif}( $entityType.isOpenType() )AbstractOpenType#{else}Serializable#end {
#set( $keys = [] )
#foreach($key in $entityType.KeyPropertyRefs)
@@ -92,9 +93,12 @@ public interface $utility.capitalize($entityType.Name) extends #if( $entityType.
fcNSPrefix = "#if($fcprops.containsKey("fcNSPrefix"))$fcprops.get("fcNSPrefix")#end",
fcNSURI = "#if($fcprops.containsKey("fcNSURI"))$fcprops.get("fcNSURI")#end",
fcKeepInContent = #if($fcprops.containsKey("fcKeepInContent"))$fcprops.get("fcKeepInContent")#{else}false#end)
- $utility.getJavaType($property.Type) get$utility.capitalize($property.Name)();
+ $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
- void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type) _$utility.uncapitalize($property.Name));
+ void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
+ #if($utility.isComplex($property.Type.FullQualifiedName))#*
+ *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+ #end
#end
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
index 6764408..7a5c6cc 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v30/complexType.vm
@@ -24,7 +24,12 @@ public interface $utility.capitalize($complexType.Name) extends Serializable {
#set($property = $complexType.getProperty($propertyName))
@Property(name = "$property.Name", type = "$property.Type.FullQualifiedName.toString()", nullable = $property.Nullable)
- $utility.getJavaType($property.Type) get$utility.capitalize($property.Name)();
+ $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
+
+ void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
+
+ #if($utility.isComplex($property.Type.FullQualifiedName))#*
+ *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+ #end
- void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type) _$utility.uncapitalize($property.Name));
#end
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
----------------------------------------------------------------------
diff --git a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
index 92307ec..dd74ade 100644
--- a/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
+++ b/ext/pojogen-maven-plugin/src/main/resources/v40/complexType.vm
@@ -37,9 +37,13 @@ public interface $utility.capitalize($complexType.Name) extends #if($complexType
unicode = #if($property.isUnicode())$property.isUnicode()#{else}false#end,
collation = "#if($property.getCollation())$property.getCollation()#end",
srid = "#if($property.getSRID())$property.getSRID()#end")
- $utility.getJavaType($property.Type) get$utility.capitalize($property.Name)();
+ $utility.getJavaType($property.Type, $property.Collection) get$utility.capitalize($property.Name)();
- void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type) _$utility.uncapitalize($property.Name));
+ void set$utility.capitalize($property.Name)(final $utility.getJavaType($property.Type, $property.Collection) _$utility.uncapitalize($property.Name));
+
+ #if($utility.isComplex($property.Type.FullQualifiedName))#*
+ *#$utility.getJavaType($property.Type) new$utility.capitalize($property.Name)();
+ #end
#end
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/pom.xml
----------------------------------------------------------------------
diff --git a/fit/pom.xml b/fit/pom.xml
index b47bdf1..905f1cf 100644
--- a/fit/pom.xml
+++ b/fit/pom.xml
@@ -45,6 +45,12 @@
<artifactId>olingo-commons-core</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>client-proxy</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- REST services CXF -->
<dependency>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/src/it/staticServiceV3/pom.xml
----------------------------------------------------------------------
diff --git a/fit/src/it/staticServiceV3/pom.xml b/fit/src/it/staticServiceV3/pom.xml
index 0e2d189..8e8c38b 100644
--- a/fit/src/it/staticServiceV3/pom.xml
+++ b/fit/src/it/staticServiceV3/pom.xml
@@ -78,7 +78,7 @@
<configuration>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<serviceRootURL>http://localhost:9080/stub/StaticService/V30/Static.svc</serviceRootURL>
- <basePackage>org.apache.olingo.proxy.staticservice</basePackage>
+ <basePackage>org.apache.olingo.fit.proxy.v3.staticservice</basePackage>
</configuration>
<id>pojosV3</id>
<phase>generate-sources</phase>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/src/it/staticServiceV3/verify.groovy
----------------------------------------------------------------------
diff --git a/fit/src/it/staticServiceV3/verify.groovy b/fit/src/it/staticServiceV3/verify.groovy
index 9bb42a2..9b74ad2 100644
--- a/fit/src/it/staticServiceV3/verify.groovy
+++ b/fit/src/it/staticServiceV3/verify.groovy
@@ -16,5 +16,5 @@
* specific language governing permissions and limitations
* under the License.
*/
-File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/proxy" );
+File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/fit/proxy/v3" );
assert basepkg.isDirectory() && basepkg.listFiles().length>0;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/src/it/staticServiceV4/pom.xml
----------------------------------------------------------------------
diff --git a/fit/src/it/staticServiceV4/pom.xml b/fit/src/it/staticServiceV4/pom.xml
index 113b69b..31a7ae2 100644
--- a/fit/src/it/staticServiceV4/pom.xml
+++ b/fit/src/it/staticServiceV4/pom.xml
@@ -78,7 +78,7 @@
<configuration>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<serviceRootURL>http://localhost:9080/stub/StaticService/V40/Static.svc</serviceRootURL>
- <basePackage>org.apache.olingo.proxy.staticservice</basePackage>
+ <basePackage>org.apache.olingo.fit.proxy.v4.staticservice</basePackage>
</configuration>
<id>pojosV4</id>
<phase>generate-sources</phase>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/src/it/staticServiceV4/verify.groovy
----------------------------------------------------------------------
diff --git a/fit/src/it/staticServiceV4/verify.groovy b/fit/src/it/staticServiceV4/verify.groovy
index 9bb42a2..02f0407 100644
--- a/fit/src/it/staticServiceV4/verify.groovy
+++ b/fit/src/it/staticServiceV4/verify.groovy
@@ -16,5 +16,5 @@
* specific language governing permissions and limitations
* under the License.
*/
-File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/proxy" );
+File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/fit/proxy/v4" );
assert basepkg.isDirectory() && basepkg.listFiles().length>0;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d313bcc4/fit/src/main/resources/V30/Computer/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V30/Computer/feed.xml b/fit/src/main/resources/V30/Computer/feed.xml
new file mode 100644
index 0000000..62605c9
--- /dev/null
+++ b/fit/src/main/resources/V30/Computer/feed.xml
@@ -0,0 +1,207 @@
+<?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:8080/DefaultService.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
+ <id>http://localhost:8080/DefaultService.svc/Computer</id>
+ <title type="text">Computer</title>
+ <updated>2014-05-08T10:00:26Z</updated>
+ <link rel="self" title="Computer" href="Computer" />
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(11)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(11)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(11)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(11)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">11</d:ComputerId>
+ <d:Name>ssgnpylqxlvzhhddkizabqurdokalozrmmvhcvmbdmjtkqirsgnxxclempdlklusmohumxap</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(12)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(12)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(12)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(12)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">12</d:ComputerId>
+ <d:Name m:null="true" />
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(13)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(13)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(13)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(13)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">13</d:ComputerId>
+ <d:Name>jiuxqefpxesahtftfnopfapumzdkkhy</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(14)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(14)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(14)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(14)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">14</d:ComputerId>
+ <d:Name>nmtpkopimarxykztifuuhhpdbouyupijekgepffouavnyvuifvqnuenbyljgyqdyxdujoxuszrzhlaffyipzylpavoioxzukryrq</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(15)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(15)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(15)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(15)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">15</d:ComputerId>
+ <d:Name m:null="true" />
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(16)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(16)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(16)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(16)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">16</d:ComputerId>
+ <d:Name>licaeurgfuooztfzjpuoqvysuntlvkrptixoulcupvltyrdz</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(17)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(17)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(17)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(17)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">17</d:ComputerId>
+ <d:Name>sssbxzussltcchxgskdezzv</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(18)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(18)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(18)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(18)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">18</d:ComputerId>
+ <d:Name>チ欲せあバя珱縷匚ダバzポソぴソぜぴ亜я歹び暦ミママぞミぞひゼそぴソ畚ゾ畚ゼまボボネダぽソяミ黑あべひソそ裹aグЯククa裹ぞ九ボぞゾ九ぺチマチマ黑たゼ珱</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(19)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(19)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(19)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(19)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">19</d:ComputerId>
+ <d:Name>hfbtpupssugßuxsuvhqsscssstlpoquzuhuratxpazfdmsszcssnuuvtdssbakptoknkaßss</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+ <entry>
+ <id>http://localhost:8080/DefaultService.svc/Computer(20)</id>
+ <category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Computer" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+ <link rel="edit" title="Computer" href="Computer(20)" />
+ <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ComputerDetail" type="application/atom+xml;type=entry" title="ComputerDetail" href="Computer(20)/ComputerDetail" />
+ <title />
+ <updated>2014-05-08T10:00:26Z</updated>
+ <author>
+ <name />
+ </author>
+ <m:action metadata="http://localhost:8080/DefaultService.svc/$metadata#DefaultContainer.GetComputer" title="GetComputer" target="http://localhost:8080/DefaultService.svc/Computer(20)/GetComputer" />
+ <content type="application/xml">
+ <m:properties>
+ <d:ComputerId m:type="Edm.Int32">20</d:ComputerId>
+ <d:Name>xifstdltzpytkiufbpzuofuxnzuyyiazceilfmkqubusfqzuyfrmddtnxjutkmuxnyljapzpodzyojnyapaphkqzcknxhq</d:Name>
+ </m:properties>
+ </content>
+ </entry>
+</feed>
\ No newline at end of file