You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ed...@apache.org on 2014/02/14 23:22:21 UTC
[45/51] [partial] [OLINGO-146] Java Client Lib contributed under SGA from Microsoft Open Technologies, Inc. The majority of this was written by Francesco Chicchiriccò
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataBinder.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataBinder.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataBinder.java
new file mode 100644
index 0000000..6589d04
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataBinder.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.io.Serializable;
+import java.net.URI;
+import org.w3c.dom.Element;
+
+public interface ODataBinder extends Serializable {
+
+ /**
+ * Gets <tt>ODataServiceDocument</tt> from the given service document resource.
+ *
+ * @param resource service document resource.
+ * @return <tt>ODataServiceDocument</tt> object.
+ */
+ ODataServiceDocument getODataServiceDocument(ServiceDocument resource);
+
+ /**
+ * Gets a <tt>FeedResource</tt> from the given OData entity set.
+ *
+ * @param <T> feed resource type.
+ * @param feed OData entity set.
+ * @param reference reference class.
+ * @return <tt>FeedResource</tt> object.
+ */
+ <T extends Feed> T getFeed(ODataEntitySet feed, Class<T> reference);
+
+ /**
+ * Gets an <tt>EntryResource</tt> from the given OData entity.
+ *
+ * @param <T> entry resource type.
+ * @param entity OData entity.
+ * @param reference reference class.
+ * @return <tt>EntryResource</tt> object.
+ */
+ <T extends Entry> T getEntry(ODataEntity entity, Class<T> reference);
+
+ /**
+ * Gets an <tt>EntryResource</tt> from the given OData entity.
+ *
+ * @param <T> entry resource type.
+ * @param entity OData entity.
+ * @param reference reference class.
+ * @param setType whether to explicitly output type information.
+ * @return <tt>EntryResource</tt> object.
+ */
+ <T extends Entry> T getEntry(ODataEntity entity, Class<T> reference, boolean setType);
+
+ /**
+ * Gets the given OData property as DOM element.
+ *
+ * @param prop OData property.
+ * @return <tt>Element</tt> object.
+ */
+ Element toDOMElement(ODataProperty prop);
+
+ ODataLinkCollection getLinkCollection(LinkCollection linkCollection);
+
+ /**
+ * Gets <tt>ODataEntitySet</tt> from the given feed resource.
+ *
+ * @param resource feed resource.
+ * @return <tt>ODataEntitySet</tt> object.
+ */
+ ODataEntitySet getODataEntitySet(Feed resource);
+
+ /**
+ * Gets <tt>ODataEntitySet</tt> from the given feed resource.
+ *
+ * @param resource feed resource.
+ * @param defaultBaseURI default base URI.
+ * @return <tt>ODataEntitySet</tt> object.
+ */
+ ODataEntitySet getODataEntitySet(Feed resource, URI defaultBaseURI);
+
+ /**
+ * Gets <tt>ODataEntity</tt> from the given entry resource.
+ *
+ * @param resource entry resource.
+ * @return <tt>ODataEntity</tt> object.
+ */
+ ODataEntity getODataEntity(Entry resource);
+
+ /**
+ * Gets <tt>ODataEntity</tt> from the given entry resource.
+ *
+ * @param resource entry resource.
+ * @param defaultBaseURI default base URI.
+ * @return <tt>ODataEntity</tt> object.
+ */
+ ODataEntity getODataEntity(Entry resource, URI defaultBaseURI);
+
+ /**
+ * Gets a <tt>LinkResource</tt> from the given OData link.
+ *
+ * @param <T> link resource type.
+ * @param link OData link.
+ * @param reference reference class.
+ * @return <tt>LinkResource</tt> object.
+ */
+ @SuppressWarnings("unchecked")
+ <T extends Link> T getLinkResource(ODataLink link, Class<T> reference);
+
+ /**
+ * Gets an <tt>ODataProperty</tt> from the given DOM element.
+ *
+ * @param property content.
+ * @return <tt>ODataProperty</tt> object.
+ */
+ ODataProperty getProperty(Element property);
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataCollectionValue.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataCollectionValue.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataCollectionValue.java
new file mode 100644
index 0000000..f3fd183
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataCollectionValue.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * OData collection property value.
+ */
+public class ODataCollectionValue extends ODataValue implements Iterable<ODataValue> {
+
+ private static final long serialVersionUID = -3665659846001987187L;
+
+ /**
+ * Type name;
+ */
+ private final String typeName;
+
+ /**
+ * Values.
+ */
+ private final List<ODataValue> values = new ArrayList<ODataValue>();
+
+ /**
+ * Constructor.
+ *
+ * @param typeName type name.
+ */
+ public ODataCollectionValue(final String typeName) {
+ this.typeName = typeName;
+ }
+
+ /**
+ * Adds a value to the collection.
+ *
+ * @param value value to be added.
+ */
+ public void add(final ODataValue value) {
+ if (value.isPrimitive() || value.isComplex()) {
+ values.add(value);
+ }
+ }
+
+ /**
+ * Value iterator.
+ *
+ * @return value iterator.
+ */
+ @Override
+ public Iterator<ODataValue> iterator() {
+ return values.iterator();
+ }
+
+ /**
+ * Gets value type name.
+ *
+ * @return value type name.
+ */
+ public String getTypeName() {
+ return typeName;
+ }
+
+ /**
+ * Gets collection size.
+ *
+ * @return collection size.
+ */
+ public int size() {
+ return values.size();
+ }
+
+ /**
+ * Checks if collection is empty.
+ *
+ * @return 'TRUE' if empty; 'FALSE' otherwise.
+ */
+ public boolean isEmpty() {
+ return values.isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataComplexValue.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataComplexValue.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataComplexValue.java
new file mode 100644
index 0000000..98d3c45
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataComplexValue.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * OData complex property value.
+ */
+public class ODataComplexValue extends ODataValue implements Iterable<ODataProperty> {
+
+ private static final long serialVersionUID = -1878555027714020431L;
+
+ /**
+ * Type name.
+ */
+ private final String typeName;
+
+ /**
+ * Complex type fields.
+ */
+ private final Map<String, ODataProperty> fields = new LinkedHashMap<String, ODataProperty>();
+
+ /**
+ * Constructor.
+ *
+ * @param typeName type name.
+ */
+ public ODataComplexValue(final String typeName) {
+ this.typeName = typeName;
+ }
+
+ /**
+ * Adds field to the complex type.
+ *
+ * @param field field to be added.
+ */
+ public void add(final ODataProperty field) {
+ fields.put(field.getName(), field);
+ }
+
+ /**
+ * Gets field.
+ *
+ * @param name name of the field to be retrieved.
+ * @return requested field.
+ */
+ public ODataProperty get(final String name) {
+ return fields.get(name);
+ }
+
+ /**
+ * Complex property fields iterator.
+ *
+ * @return fields iterator.
+ */
+ @Override
+ public Iterator<ODataProperty> iterator() {
+ return fields.values().iterator();
+ }
+
+ /**
+ * Gest value type name.
+ *
+ * @return value type name.
+ */
+ public String getTypeName() {
+ return typeName;
+ }
+
+ /**
+ * Gets number of fields.
+ *
+ * @return number of fields.
+ */
+ public int size() {
+ return fields.size();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDeserializer.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDeserializer.java
new file mode 100644
index 0000000..ef19822
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDeserializer.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEdmx;
+import com.msopentech.odatajclient.engine.format.ODataFormat;
+import java.io.InputStream;
+import java.io.Serializable;
+import org.w3c.dom.Element;
+
+/**
+ * Utility class for serialization.
+ */
+public interface ODataDeserializer extends Serializable {
+
+ AbstractEdmx<?, ?, ?, ?, ?, ?> toMetadata(InputStream input);
+
+ /**
+ * Gets the ServiceDocumentResource object represented by the given InputStream.
+ *
+ * @param input stream to be de-serialized.
+ * @param format OData service document format.
+ * @return ServiceDocumentResource object.
+ */
+ ServiceDocument toServiceDocument(InputStream input, ODataFormat format);
+
+ /**
+ * Gets a feed object from the given InputStream.
+ *
+ * @param <T> reference class type
+ * @param input stream to be de-serialized.
+ * @param reference reference class (AtomFeed.class, JSONFeed.class).
+ * @return FeedResource instance.
+ */
+ <T extends Feed> T toFeed(InputStream input, Class<T> reference);
+
+ /**
+ * Gets an entry object from the given InputStream.
+ *
+ * @param <T> reference class type
+ * @param input stream to be de-serialized.
+ * @param reference reference class (AtomEntry.class, JSONV3Entry.class).
+ * @return EntryResource instance.
+ */
+ <T extends Entry> T toEntry(InputStream input, Class<T> reference);
+
+ /**
+ * Gets a DOM representation of the given InputStream.
+ *
+ * @param input stream to be de-serialized.
+ * @param format OData format.
+ * @return DOM.
+ */
+ Element toPropertyDOM(InputStream input, ODataFormat format);
+
+ /**
+ * Gets a list of links from the given InputStream.
+ *
+ * @param input stream to be de-serialized.
+ * @param format OData format.
+ * @return de-serialized links.
+ */
+ LinkCollection toLinkCollection(InputStream input, ODataFormat format);
+
+ /**
+ * Gets the ODataError object represented by the given InputStream.
+ *
+ * @param input stream to be parsed and de-serialized.
+ * @param isXML 'TRUE' if the error is represented by XML; 'FALSE' otherwise.
+ * @return
+ */
+ ODataError toODataError(InputStream input, boolean isXML);
+
+ /**
+ * Parses the given input into a DOM tree.
+ *
+ * @param input stream to be parsed and de-serialized.
+ * @return DOM tree
+ */
+ Element toDOM(InputStream input);
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDuration.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDuration.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDuration.java
new file mode 100644
index 0000000..44cd7fc
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataDuration.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.io.Serializable;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * Helper class for handling time (as duration) primitive values.
+ *
+ * @see com.msopentech.odatajclient.engine.data.metadata.edm.EdmSimpleType#TIME
+ * @see Duration
+ */
+public final class ODataDuration implements Serializable {
+
+ private static final long serialVersionUID = 778404231943967899L;
+
+ private final Duration duration;
+
+ public ODataDuration(final String input) {
+ try {
+ final DatatypeFactory dtFactory = DatatypeFactory.newInstance();
+ this.duration = dtFactory.newDuration(input);
+ } catch (DatatypeConfigurationException e) {
+ throw new IllegalArgumentException("Could not parse '" + input + "' as Duration", e);
+ }
+ }
+
+ public ODataDuration(final Duration duration) {
+ this.duration = duration;
+ }
+
+ public Duration getDuration() {
+ return duration;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public String toString() {
+ return this.duration.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntity.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntity.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntity.java
new file mode 100644
index 0000000..79e2c74
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntity.java
@@ -0,0 +1,362 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * OData entity.
+ */
+public class ODataEntity extends ODataItem implements ODataInvokeResult {
+
+ private static final long serialVersionUID = 8360640095932811034L;
+
+ /**
+ * ETag.
+ */
+ private String eTag;
+
+ /**
+ * Media entity flag.
+ */
+ private boolean mediaEntity = false;
+
+ /**
+ * In case of media entity, media content type.
+ */
+ private String mediaContentType;
+
+ /**
+ * In case of media entity, media content source.
+ */
+ private String mediaContentSource;
+
+ /**
+ * Edit link.
+ */
+ protected URI editLink;
+
+ /**
+ * Navigation links (might contain in-line entities or feeds).
+ */
+ protected final List<ODataLink> navigationLinks = new ArrayList<ODataLink>();
+
+ /**
+ * Association links.
+ */
+ protected final List<ODataLink> associationLinks = new ArrayList<ODataLink>();
+
+ /**
+ * Media edit links.
+ */
+ protected final List<ODataLink> editMediaLinks = new ArrayList<ODataLink>();
+
+ /**
+ * Operations (legacy, functions, actions).
+ */
+ protected final List<ODataOperation> operations = new ArrayList<ODataOperation>();
+
+ /**
+ * Entity properties.
+ */
+ protected final List<ODataProperty> properties = new ArrayList<ODataProperty>();
+
+ /**
+ * Constructor.
+ *
+ * @param name OData entity name.
+ */
+ ODataEntity(final String name) {
+ super(name);
+ }
+
+ /**
+ * Gets ETag.
+ *
+ * @return ETag.
+ */
+ public String getETag() {
+ return eTag;
+ }
+
+ /**
+ * Sets ETag.
+ *
+ * @param eTag ETag.
+ */
+ public void setETag(final String eTag) {
+ this.eTag = eTag;
+ }
+
+ /**
+ * Adds an operation.
+ *
+ * @param operation to be added.
+ * @return whether operation was actually added or not.
+ */
+ public boolean addOperation(final ODataOperation operation) {
+ return this.operations.add(operation);
+ }
+
+ /**
+ * Sets operations.
+ *
+ * @param operations operations.
+ */
+ public void setOperations(final List<ODataOperation> operations) {
+ this.operations.clear();
+ if (operations != null && !operations.isEmpty()) {
+ this.operations.addAll(operations);
+ }
+ }
+
+ /**
+ * Searches for operation with given title.
+ *
+ * @param title operation to look for
+ * @return operation if found with given title, <tt>null</tt> otherwise
+ */
+ public ODataOperation getOperation(final String title) {
+ ODataOperation result = null;
+ for (ODataOperation operation : operations) {
+ if (title.equals(operation.getTitle())) {
+ result = operation;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Gets operations.
+ *
+ * @return operations.
+ */
+ public List<ODataOperation> getOperations() {
+ return this.operations;
+ }
+
+ /**
+ * Searches for property with given name.
+ *
+ * @param name property to look for
+ * @return property if found with given name, <tt>null</tt> otherwise
+ */
+ public ODataProperty getProperty(final String name) {
+ ODataProperty result = null;
+
+ if (StringUtils.isNotBlank(name)) {
+ for (ODataProperty property : properties) {
+ if (name.equals(property.getName())) {
+ result = property;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns OData entity properties.
+ *
+ * @return OData entity properties.
+ */
+ public List<ODataProperty> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Adds new property.
+ *
+ * @param property property to be added.
+ */
+ public boolean addProperty(final ODataProperty property) {
+ return properties.contains(property) ? false : properties.add(property);
+ }
+
+ /**
+ * Removes given property.
+ *
+ * @param property property to be removed.
+ */
+ public boolean removeProperty(final ODataProperty property) {
+ return properties.remove(property);
+ }
+
+ /**
+ * Puts the given link into one of available lists, based on its type.
+ *
+ * @param link to be added
+ * @return <tt>true</tt> if the given link was added in one of available lists
+ */
+ public boolean addLink(final ODataLink link) {
+ boolean result = false;
+
+ switch (link.getType()) {
+ case ASSOCIATION:
+ result = associationLinks.contains(link) ? false : associationLinks.add(link);
+ break;
+
+ case ENTITY_NAVIGATION:
+ case ENTITY_SET_NAVIGATION:
+ result = navigationLinks.contains(link) ? false : navigationLinks.add(link);
+ break;
+
+ case MEDIA_EDIT:
+ result = editMediaLinks.contains(link) ? false : editMediaLinks.add(link);
+ break;
+
+ default:
+ }
+
+ return result;
+ }
+
+ /**
+ * Removes the given link from any list (association, navigation, edit-media).
+ *
+ * @param link to be removed
+ * @return <tt>true</tt> if the given link was contained in one of available lists
+ */
+ public boolean removeLink(final ODataLink link) {
+ return associationLinks.remove(link) || navigationLinks.remove(link) || editMediaLinks.remove(link);
+ }
+
+ /**
+ * Returns all entity navigation links (including inline entities / feeds).
+ *
+ * @return OData entity links.
+ */
+ public List<ODataLink> getNavigationLinks() {
+ return navigationLinks;
+ }
+
+ /**
+ * Returns all entity association links.
+ *
+ * @return OData entity links.
+ */
+ public List<ODataLink> getAssociationLinks() {
+ return associationLinks;
+ }
+
+ /**
+ * Returns all entity media edit links.
+ *
+ * @return OData entity links.
+ */
+ public List<ODataLink> getEditMediaLinks() {
+ return editMediaLinks;
+ }
+
+ /**
+ * Returns OData entity edit link.
+ *
+ * @return entity edit link.
+ */
+ public URI getEditLink() {
+ return editLink;
+ }
+
+ /**
+ * Sets OData entity edit link.
+ *
+ * @param editLink edit link.
+ */
+ public void setEditLink(final URI editLink) {
+ this.editLink = editLink;
+ }
+
+ /**
+ * {@inheritDoc }
+ * <p>
+ * If null the edit link will be returned.
+ */
+ @Override
+ public URI getLink() {
+ return super.getLink() == null ? getEditLink() : super.getLink();
+ }
+
+ /**
+ * TRUE if read-only entity.
+ *
+ * @return TRUE if read-only; FALSE otherwise.
+ */
+ public boolean isReadOnly() {
+ return super.getLink() != null;
+ }
+
+ /**
+ * Checks if the current entity is a media entity.
+ *
+ * @return 'TRUE' if media entity; 'FALSE' otherwise.
+ */
+ public boolean isMediaEntity() {
+ return mediaEntity;
+ }
+
+ /**
+ * Sets media entity flag.
+ *
+ * @param isMediaEntity media entity flag value.
+ */
+ public void setMediaEntity(final boolean isMediaEntity) {
+ this.mediaEntity = isMediaEntity;
+ }
+
+ /**
+ * Gets media content type.
+ *
+ * @return media content type.
+ */
+ public String getMediaContentType() {
+ return mediaContentType;
+ }
+
+ /**
+ * Sets media content type.
+ *
+ * @param mediaContentType media content type.
+ */
+ public void setMediaContentType(final String mediaContentType) {
+ this.mediaContentType = mediaContentType;
+ }
+
+ /**
+ * Gets media content source.
+ *
+ * @return media content source.
+ */
+ public String getMediaContentSource() {
+ return mediaContentSource;
+ }
+
+ /**
+ * Sets media content source.
+ *
+ * @param mediaContentSource media content source.
+ */
+ public void setMediaContentSource(final String mediaContentSource) {
+ this.mediaContentSource = mediaContentSource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySet.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySet.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySet.java
new file mode 100644
index 0000000..77d615a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySet.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * OData entity collection.
+ * If pagination was used to get this instance, forward page navigation URI will be available.
+ */
+public class ODataEntitySet extends ODataItem implements ODataInvokeResult {
+
+ private static final long serialVersionUID = 9039605899821494024L;
+
+ /**
+ * Link to the next page.
+ */
+ protected URI next;
+
+ /**
+ * Number of ODataEntities contained in this feed.
+ * If <tt>$inlinecount</tt> was requested, this value comes from there.
+ */
+ protected Integer count;
+
+ /**
+ * OData entities contained in this feed.
+ */
+ protected List<ODataEntity> entities = new ArrayList<ODataEntity>();
+
+ /**
+ * Constructor.
+ */
+ ODataEntitySet() {
+ super(null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param next next link.
+ */
+ ODataEntitySet(final URI next) {
+ super(null);
+ this.next = next;
+ }
+
+ /**
+ * Gets next page link.
+ *
+ * @return next page link; null value if single page or last page reached.
+ */
+ public URI getNext() {
+ return next;
+ }
+
+ /**
+ * Sets in-line count.
+ *
+ * @param count in-line count value.
+ */
+ public void setCount(final int count) {
+ this.count = count;
+ }
+
+ /**
+ * Gets in-line count.
+ *
+ * @return in-line count value.
+ */
+ public int getCount() {
+ return count == null ? entities.size() : count;
+ }
+
+ /**
+ * Adds entity to the current feed.
+ *
+ * @param entity entity to be added.
+ * @return 'FALSE' if already exists; 'TRUE' otherwise.
+ */
+ public boolean addEntity(final ODataEntity entity) {
+ return entities.contains(entity) ? false : entities.add(entity);
+ }
+
+ /**
+ * Removes an entity.
+ *
+ * @param entity entity to be removed.
+ * @return 'TRUE' in case of success; 'FALSE' otherwise.
+ */
+ public boolean removeEntity(final ODataEntity entity) {
+ return entities.remove(entity);
+ }
+
+ /**
+ * Gets contained entities.
+ *
+ * @return feed entries.
+ */
+ public List<ODataEntity> getEntities() {
+ return entities;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySetIterator.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySetIterator.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySetIterator.java
new file mode 100644
index 0000000..8ab8b37
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataEntitySetIterator.java
@@ -0,0 +1,320 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.data.impl.v3.AtomEntry;
+import com.msopentech.odatajclient.engine.data.impl.v3.JSONEntry;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import com.msopentech.odatajclient.engine.utils.ODataConstants;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OData entity set iterator class.
+ */
+public class ODataEntitySetIterator implements Iterator<ODataEntity> {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ODataEntitySetIterator.class);
+
+ private static final long serialVersionUID = 9039605899821494025L;
+
+ private final ODataClient odataClient;
+
+ private final InputStream stream;
+
+ private final ODataPubFormat format;
+
+ private Entry cached;
+
+ private ODataEntitySet entitySet;
+
+ private final ByteArrayOutputStream osFeed;
+
+ private final String namespaces;
+
+ private boolean available = true;
+
+ /**
+ * Constructor.
+ *
+ * @param odataClient client instance getting this request
+ * @param stream source stream.
+ * @param format OData format.
+ */
+ public ODataEntitySetIterator(final ODataClient odataClient,
+ final InputStream stream, final ODataPubFormat format) {
+
+ this.odataClient = odataClient;
+ this.stream = stream;
+ this.format = format;
+ this.osFeed = new ByteArrayOutputStream();
+
+ if (format == ODataPubFormat.ATOM) {
+ namespaces = getAllElementAttributes(stream, "feed", osFeed);
+ } else {
+ namespaces = null;
+ try {
+ if (consume(stream, "\"value\":", osFeed, true) >= 0) {
+ int c = 0;
+ while (c != '[' && (c = stream.read()) >= 0) {
+ osFeed.write(c);
+ }
+ }
+ } catch (IOException e) {
+ LOG.error("Error parsing feed", e);
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public boolean hasNext() {
+ if (available && cached == null) {
+ if (format == ODataPubFormat.ATOM) {
+ cached = nextAtomEntryFromFeed(stream, osFeed, namespaces);
+ } else {
+ cached = nextJsonEntryFromFeed(stream, osFeed);
+ }
+
+ if (cached == null) {
+ available = false;
+ entitySet = odataClient.getReader().
+ readEntitySet(new ByteArrayInputStream(osFeed.toByteArray()), format);
+ close();
+ }
+ }
+
+ return available;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public ODataEntity next() {
+ if (hasNext()) {
+ final ODataEntity res = odataClient.getBinder().getODataEntity(cached);
+ cached = null;
+ return res;
+ }
+
+ throw new NoSuchElementException("No entity found");
+ }
+
+ /**
+ * Unsupported operation.
+ */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Operation not supported");
+ }
+
+ /**
+ * Closes the current iterator.
+ */
+ public void close() {
+ IOUtils.closeQuietly(stream);
+ IOUtils.closeQuietly(osFeed);
+ }
+
+ /**
+ * Gets the next link if exists.
+ *
+ * @return next link if exists; null otherwise.
+ */
+ public URI getNext() {
+ if (entitySet == null) {
+ throw new IllegalStateException("Iteration must be completed in order to retrieve the link for next page");
+ }
+ return entitySet.getNext();
+ }
+
+ /**
+ * Finalize object closing all managed resources.
+ *
+ * @throws Throwable
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+
+ private JSONEntry nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) {
+ final ByteArrayOutputStream entry = new ByteArrayOutputStream();
+
+ JSONEntry entity = null;
+ try {
+ int c = 0;
+
+ boolean foundNewOne = false;
+
+ do {
+ c = input.read();
+ if (c == '{') {
+ entry.write(c);
+ c = -1;
+ foundNewOne = true;
+ }
+ if (c == ']') {
+ osFeed.write(c);
+ c = -1;
+ }
+ } while (c >= 0);
+
+ if (foundNewOne) {
+ int count = 1;
+ c = 0;
+
+ while (count > 0 && c >= 0) {
+ c = input.read();
+ if (c == '{') {
+ count++;
+ } else if (c == '}') {
+ count--;
+ }
+ entry.write(c);
+ }
+
+ if (c >= 0) {
+ entity = odataClient.getDeserializer().toEntry(
+ new ByteArrayInputStream(entry.toByteArray()), JSONEntry.class);
+ }
+ } else {
+ while ((c = input.read()) >= 0) {
+ osFeed.write(c);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Error retrieving entities from EntitySet", e);
+ }
+
+ return entity;
+ }
+
+ /**
+ * De-Serializes a stream into an OData entity set.
+ *
+ * @param input stream to de-serialize.
+ * @param format de-serialize as AtomFeed or JSONFeed
+ * @return de-serialized entity set.
+ */
+ private AtomEntry nextAtomEntryFromFeed(final InputStream input, final OutputStream osFeed, final String namespaces) {
+ final ByteArrayOutputStream entry = new ByteArrayOutputStream();
+
+ AtomEntry entity = null;
+
+ try {
+ if (consume(input, "<entry>", osFeed, false) >= 0) {
+ entry.write("<entry ".getBytes(ODataConstants.UTF8));
+ entry.write(namespaces.getBytes(ODataConstants.UTF8));
+ entry.write(">".getBytes(ODataConstants.UTF8));
+
+ if (consume(input, "</entry>", entry, true) >= 0) {
+ entity = odataClient.getDeserializer().
+ toEntry(new ByteArrayInputStream(entry.toByteArray()), AtomEntry.class);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Error retrieving entities from EntitySet", e);
+ }
+
+ return entity;
+ }
+
+ private String getAllElementAttributes(final InputStream input, final String name, final OutputStream os) {
+ final ByteArrayOutputStream attrs = new ByteArrayOutputStream();
+
+ String res;
+
+ try {
+ byte[] attrsDeclaration = null;
+
+ final String key = "<" + name + " ";
+ if (consume(input, key, os, true) >= 0 && consume(input, ">", attrs, false) >= 0) {
+ attrsDeclaration = attrs.toByteArray();
+ os.write(attrsDeclaration);
+ os.write('>');
+ }
+
+ res = attrsDeclaration == null
+ ? StringUtils.EMPTY
+ : new String(attrsDeclaration, ODataConstants.UTF8).trim();
+ } catch (Exception e) {
+ LOG.error("Error retrieving entities from EntitySet", e);
+ res = StringUtils.EMPTY;
+ }
+
+ return res.endsWith("/") ? res.substring(0, res.length() - 1) : res;
+ }
+
+ private int consume(
+ final InputStream input, final String end, final OutputStream os, final boolean includeEndKey)
+ throws IOException {
+
+ final char[] endKey = end.toCharArray();
+ final char[] endLowerKey = end.toLowerCase().toCharArray();
+ final char[] endUpperKey = end.toUpperCase().toCharArray();
+
+ int pos = 0;
+ int c = 0;
+ while (pos < endKey.length && (c = input.read()) >= 0) {
+ if (c == endLowerKey[pos] || c == endUpperKey[pos]) {
+ pos++;
+ if (includeEndKey && os != null) {
+ os.write(c);
+ }
+ } else if (pos > 0) {
+ if (!includeEndKey && os != null) {
+ for (int i = 0; i < pos; i++) {
+ os.write(endKey[i]);
+ }
+ }
+ if (os != null) {
+ os.write(c);
+ }
+ pos = 0;
+ } else {
+ if (os != null) {
+ os.write(c);
+ }
+ }
+ }
+
+ return c;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataError.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataError.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataError.java
new file mode 100644
index 0000000..3e1726b
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataError.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+/**
+ * OData error.
+ */
+public interface ODataError {
+
+ /**
+ * Gets error code.
+ *
+ * @return error code.
+ */
+ String getCode();
+
+ /**
+ * Gets error message language.
+ *
+ * @return error message language.
+ */
+ String getMessageLang();
+
+ /**
+ * Gets error message.
+ *
+ * @return error message.
+ */
+ String getMessageValue();
+
+ /**
+ * Gets inner error message.
+ *
+ * @return inner error message.
+ */
+ String getInnerErrorMessage();
+
+ /**
+ * Gets inner error type.
+ *
+ * @return inner error type.
+ */
+ String getInnerErrorType();
+
+ /**
+ * Gets inner error stack-trace.
+ *
+ * @return inner error stack-trace
+ */
+ String getInnerErrorStacktrace();
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataGeospatialValue.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataGeospatialValue.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataGeospatialValue.java
new file mode 100644
index 0000000..ba58047
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataGeospatialValue.java
@@ -0,0 +1,489 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.metadata.edm.EdmSimpleType;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.Geospatial;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.GeospatialCollection;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.LineString;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.MultiLineString;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.MultiPoint;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.MultiPolygon;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.Point;
+import com.msopentech.odatajclient.engine.metadata.edm.geospatial.Polygon;
+import com.msopentech.odatajclient.engine.utils.ODataConstants;
+import com.msopentech.odatajclient.engine.utils.XMLUtils;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class ODataGeospatialValue extends ODataPrimitiveValue {
+
+ private static final long serialVersionUID = -3984105137562291082L;
+
+ /**
+ * Geospatial value builder.
+ */
+ public static class Builder extends AbstractBuilder {
+
+ private final ODataGeospatialValue ogv;
+
+ /**
+ * Constructor.
+ */
+ public Builder(final ODataClient client) {
+ super(client);
+ this.ogv = new ODataGeospatialValue(client);
+ }
+
+ /**
+ * Sets the given value provided as a DOM tree.
+ *
+ * @param tree value.
+ * @return the current builder.
+ */
+ public Builder setTree(final Element tree) {
+ this.ogv.tree = tree;
+ return this;
+ }
+
+ /**
+ * Sets the actual object value.
+ *
+ * @param value value.
+ * @return the current builder.
+ */
+ public <T extends Geospatial> Builder setValue(final T value) {
+ this.ogv.value = value;
+ return this;
+ }
+
+ /**
+ * Sets actual value type.
+ *
+ * @param type type.
+ * @return the current builder.
+ */
+ public Builder setType(final EdmSimpleType type) {
+ isSupported(type);
+
+ if (!type.isGeospatial()) {
+ throw new IllegalArgumentException(
+ "Use " + ODataPrimitiveValue.class.getSimpleName() + " for non-geospatial types");
+ }
+
+ if (type == EdmSimpleType.Geography || type == EdmSimpleType.Geometry) {
+ throw new IllegalArgumentException(
+ type + "is not an instantiable type. "
+ + "An entity can declare a property to be of type Geometry. "
+ + "An instance of an entity MUST NOT have a value of type Geometry. "
+ + "Each value MUST be of some subtype.");
+ }
+ this.ogv.type = type;
+ return this;
+ }
+
+ /**
+ * Builds the geospatial value.
+ *
+ * @return <tt>ODataGeospatialValue</tt> object.
+ */
+ public ODataGeospatialValue build() {
+ if (this.ogv.tree == null && this.ogv.value == null) {
+ throw new IllegalArgumentException("Must provide either tree or value");
+ }
+ if (this.ogv.tree != null && this.ogv.value != null) {
+ throw new IllegalArgumentException("Cannot provide both tree and value");
+ }
+
+ if (this.ogv.type == null) {
+ throw new IllegalArgumentException("Must provide geospatial type");
+ }
+
+ if (this.ogv.tree != null) {
+ this.ogv.value = this.ogv.parseTree(this.ogv.tree, this.ogv.type);
+ }
+ if (this.ogv.value != null) {
+ this.ogv.tree = this.ogv.parseGeospatial((Geospatial) this.ogv.value);
+ }
+
+ return this.ogv;
+ }
+ }
+
+ /**
+ * DOM tree.
+ */
+ private Element tree;
+
+ /**
+ * Protected constructor, need to use the builder to instantiate this class.
+ *
+ * @see Builder
+ */
+ protected ODataGeospatialValue(final ODataClient client) {
+ super(client);
+ }
+
+ private Geospatial.Dimension getDimension() {
+ Geospatial.Dimension dimension;
+
+ switch (this.type) {
+ case Geography:
+ case GeographyCollection:
+ case GeographyLineString:
+ case GeographyMultiLineString:
+ case GeographyPoint:
+ case GeographyMultiPoint:
+ case GeographyPolygon:
+ case GeographyMultiPolygon:
+ dimension = Geospatial.Dimension.GEOGRAPHY;
+ break;
+
+ default:
+ dimension = Geospatial.Dimension.GEOMETRY;
+ }
+
+ return dimension;
+ }
+
+ private List<Point> parsePoints(final NodeList posList) {
+ final List<Point> result = new ArrayList<Point>();
+ for (int i = 0; i < posList.getLength(); i++) {
+ final String[] pointInfo = posList.item(i).getTextContent().split(" ");
+ final Point point = new Point(getDimension());
+ point.setX(Double.valueOf(pointInfo[0]));
+ point.setY(Double.valueOf(pointInfo[1]));
+
+ result.add(point);
+ }
+ return result;
+ }
+
+ private LineString parseLineString(final Element element) {
+ return new LineString(getDimension(),
+ parsePoints(element.getElementsByTagName(ODataConstants.ELEM_POS)));
+ }
+
+ private Polygon parsePolygon(final Element element) {
+ List<Point> extPoints = null;
+ final Element exterior =
+ (Element) element.getElementsByTagName(ODataConstants.ELEM_POLYGON_EXTERIOR).item(0);
+ if (exterior != null) {
+ extPoints = parsePoints(
+ ((Element) exterior.getElementsByTagName(ODataConstants.ELEM_POLYGON_LINEARRING).item(0)).
+ getElementsByTagName(ODataConstants.ELEM_POS));
+ }
+ List<Point> intPoints = null;
+ final Element interior =
+ (Element) element.getElementsByTagName(ODataConstants.ELEM_POLYGON_INTERIOR).item(0);
+ if (interior != null) {
+ intPoints = parsePoints(
+ ((Element) interior.getElementsByTagName(ODataConstants.ELEM_POLYGON_LINEARRING).item(0)).
+ getElementsByTagName(ODataConstants.ELEM_POS));
+ }
+
+ return new Polygon(getDimension(), intPoints, extPoints);
+ }
+
+ /**
+ * Parses given tree as geospatial value.
+ */
+ private Geospatial parseTree(final Element tree, final EdmSimpleType type) {
+ Geospatial value;
+
+ switch (type) {
+ case GeographyPoint:
+ case GeometryPoint:
+ value = parsePoints(tree.getElementsByTagName(ODataConstants.ELEM_POS)).get(0);
+ break;
+
+ case GeographyMultiPoint:
+ case GeometryMultiPoint:
+ final Element pMembs =
+ (Element) tree.getElementsByTagName(ODataConstants.ELEM_POINTMEMBERS).item(0);
+ final List<Point> points = pMembs == null
+ ? Collections.<Point>emptyList()
+ : parsePoints(pMembs.getElementsByTagName(ODataConstants.ELEM_POS));
+ value = new MultiPoint(getDimension(), points);
+ break;
+
+ case GeographyLineString:
+ case GeometryLineString:
+ value = parseLineString(tree);
+ break;
+
+ case GeographyMultiLineString:
+ case GeometryMultiLineString:
+ final Element mlMembs =
+ (Element) tree.getElementsByTagName(ODataConstants.ELEM_LINESTRINGMEMBERS).item(0);
+ final List<LineString> lineStrings;
+ if (mlMembs == null) {
+ lineStrings = Collections.<LineString>emptyList();
+ } else {
+ lineStrings = new ArrayList<LineString>();
+ final NodeList lineStringNodes = mlMembs.getElementsByTagName(ODataConstants.ELEM_LINESTRING);
+ for (int i = 0; i < lineStringNodes.getLength(); i++) {
+ lineStrings.add(parseLineString((Element) lineStringNodes.item(i)));
+ }
+ }
+ value = new MultiLineString(getDimension(), lineStrings);
+ break;
+
+ case GeographyPolygon:
+ case GeometryPolygon:
+ value = parsePolygon(tree);
+ break;
+
+ case GeographyMultiPolygon:
+ case GeometryMultiPolygon:
+ final Element mpMembs =
+ (Element) tree.getElementsByTagName(ODataConstants.ELEM_SURFACEMEMBERS).item(0);
+ final List<Polygon> polygons;
+ if (mpMembs == null) {
+ polygons = Collections.<Polygon>emptyList();
+ } else {
+ polygons = new ArrayList<Polygon>();
+ final NodeList polygonNodes = mpMembs.getElementsByTagName(ODataConstants.ELEM_POLYGON);
+ for (int i = 0; i < polygonNodes.getLength(); i++) {
+ polygons.add(parsePolygon((Element) polygonNodes.item(i)));
+ }
+ }
+ value = new MultiPolygon(getDimension(), polygons);
+ break;
+
+ case GeographyCollection:
+ case GeometryCollection:
+ final Element cMembs =
+ (Element) tree.getElementsByTagName(ODataConstants.ELEM_GEOMEMBERS).item(0);
+ final List<Geospatial> geospatials;
+ if (cMembs == null) {
+ geospatials = Collections.<Geospatial>emptyList();
+ } else {
+ geospatials = new ArrayList<Geospatial>();
+ for (Node geom : XMLUtils.getChildNodes(cMembs, Node.ELEMENT_NODE)) {
+ geospatials.add(
+ parseTree((Element) geom, XMLUtils.simpleTypeForNode(getDimension(), geom)));
+ }
+ }
+ value = new GeospatialCollection(getDimension(), geospatials);
+ break;
+
+ default:
+ value = null;
+ }
+
+ return value;
+ }
+
+ private void parsePoints(final Element parent, final Iterator<Point> itor, final boolean wrap) {
+ while (itor.hasNext()) {
+ final Point point = itor.next();
+
+ final Element pos = parent.getOwnerDocument().
+ createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POS);
+ pos.appendChild(parent.getOwnerDocument().createTextNode(
+ Double.toString(point.getX()) + " " + point.getY()));
+
+ final Element appendable;
+ if (wrap) {
+ final Element epoint = parent.getOwnerDocument().
+ createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POINT);
+ parent.appendChild(epoint);
+ appendable = epoint;
+ } else {
+ appendable = parent;
+ }
+ appendable.appendChild(pos);
+ }
+ }
+
+ private void parseLineStrings(final Element parent, final Iterator<LineString> itor, final boolean wrap) {
+ while (itor.hasNext()) {
+ final LineString lineString = itor.next();
+
+ final Element appendable;
+ if (wrap) {
+ final Element eLineString = parent.getOwnerDocument().
+ createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_LINESTRING);
+ parent.appendChild(eLineString);
+ appendable = eLineString;
+ } else {
+ appendable = parent;
+ }
+ parsePoints(appendable, lineString.iterator(), false);
+ }
+ }
+
+ private void parsePolygons(final Element parent, final Iterator<Polygon> itor, final boolean wrap) {
+ while (itor.hasNext()) {
+ final Polygon polygon = itor.next();
+
+ final Element appendable;
+ if (wrap) {
+ final Element ePolygon = parent.getOwnerDocument().createElementNS(
+ ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON);
+ parent.appendChild(ePolygon);
+ appendable = ePolygon;
+ } else {
+ appendable = parent;
+ }
+
+ if (!polygon.getExterior().isEmpty()) {
+ final Element exterior = parent.getOwnerDocument().createElementNS(
+ ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_EXTERIOR);
+ appendable.appendChild(exterior);
+ final Element linearRing = parent.getOwnerDocument().createElementNS(
+ ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_LINEARRING);
+ exterior.appendChild(linearRing);
+
+ parsePoints(linearRing, polygon.getExterior().iterator(), false);
+ }
+ if (!polygon.getInterior().isEmpty()) {
+ final Element interior = parent.getOwnerDocument().createElementNS(
+ ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_INTERIOR);
+ appendable.appendChild(interior);
+ final Element linearRing = parent.getOwnerDocument().createElementNS(
+ ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_LINEARRING);
+ interior.appendChild(linearRing);
+
+ parsePoints(linearRing, polygon.getInterior().iterator(), false);
+ }
+ }
+ }
+
+ private Element parseGeospatial(final Geospatial value) {
+ final DocumentBuilder builder;
+ try {
+ builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new IllegalStateException("Failure initializing Geospatial DOM tree", e);
+ }
+ final Document doc = builder.newDocument();
+
+ final Element tree;
+
+ switch (value.getEdmSimpleType()) {
+ case GeographyPoint:
+ case GeometryPoint:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POINT);
+
+ parsePoints(tree, Collections.singleton((Point) value).iterator(), false);
+ break;
+
+ case GeometryMultiPoint:
+ case GeographyMultiPoint:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_MULTIPOINT);
+
+ final Element pMembs = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POINTMEMBERS);
+ tree.appendChild(pMembs);
+
+ parsePoints(pMembs, ((MultiPoint) value).iterator(), true);
+ break;
+
+ case GeometryLineString:
+ case GeographyLineString:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_LINESTRING);
+
+ parseLineStrings(tree, Collections.singleton((LineString) value).iterator(), false);
+ break;
+
+ case GeometryMultiLineString:
+ case GeographyMultiLineString:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_MULTILINESTRING);
+
+ final Element mlMembs =
+ doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_LINESTRINGMEMBERS);
+ tree.appendChild(mlMembs);
+
+ parseLineStrings(mlMembs, ((MultiLineString) value).iterator(), true);
+ break;
+
+ case GeographyPolygon:
+ case GeometryPolygon:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON);
+ parsePolygons(tree, Collections.singleton(((Polygon) value)).iterator(), false);
+ break;
+
+ case GeographyMultiPolygon:
+ case GeometryMultiPolygon:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_MULTIPOLYGON);
+
+ final Element mpMembs =
+ doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_SURFACEMEMBERS);
+ tree.appendChild(mpMembs);
+
+ parsePolygons(mpMembs, ((MultiPolygon) value).iterator(), true);
+ break;
+
+ case GeographyCollection:
+ case GeometryCollection:
+ tree = doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_GEOCOLLECTION);
+
+ final Element gMembs =
+ doc.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_GEOMEMBERS);
+ tree.appendChild(gMembs);
+
+ final Iterator<Geospatial> itor = ((GeospatialCollection) value).iterator();
+ while (itor.hasNext()) {
+ final Geospatial geospatial = itor.next();
+ gMembs.appendChild(doc.importNode(parseGeospatial(geospatial), true));
+ }
+ break;
+
+ default:
+ tree = null;
+ }
+
+ return tree;
+ }
+
+ public Element toTree() {
+ return this.tree;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final ODataGeospatialValue other = (ODataGeospatialValue) obj;
+ return this.tree.isEqualNode(other.tree);
+ }
+
+ @Override
+ public String toString() {
+ final StringWriter writer = new StringWriter();
+ client.getSerializer().dom(this.tree, writer);
+ return writer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntity.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntity.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntity.java
new file mode 100644
index 0000000..e4b2133
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntity.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import java.net.URI;
+
+/**
+ * OData in-line entity.
+ */
+public class ODataInlineEntity extends ODataLink {
+
+ private static final long serialVersionUID = -4763341581843700743L;
+
+ private final ODataEntity entity;
+
+ /**
+ * Constructor.
+ *
+ * @param uri edit link.
+ * @param type type.
+ * @param title title.
+ * @param entity entity.
+ */
+ ODataInlineEntity(final ODataClient client,
+ final URI uri, final ODataLinkType type, final String title, final ODataEntity entity) {
+
+ super(client, uri, type, title);
+ this.entity = entity;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param baseURI base URI.
+ * @param href href.
+ * @param type type.
+ * @param title title.
+ * @param entity entity.
+ */
+ ODataInlineEntity(final ODataClient client, final URI baseURI, final String href, final ODataLinkType type,
+ final String title, final ODataEntity entity) {
+
+ super(client, baseURI, href, type, title);
+ this.entity = entity;
+ }
+
+ /**
+ * Gets wrapped entity.
+ *
+ * @return wrapped entity.
+ */
+ public ODataEntity getEntity() {
+ return entity;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntitySet.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntitySet.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntitySet.java
new file mode 100644
index 0000000..5582580
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInlineEntitySet.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import java.net.URI;
+
+/**
+ * OData in-line entity set.
+ */
+public class ODataInlineEntitySet extends ODataLink {
+
+ private static final long serialVersionUID = -77628001615355449L;
+
+ private ODataEntitySet entitySet;
+
+ /**
+ * Constructor.
+ *
+ * @param client OData client.
+ * @param uri edit link.
+ * @param type type.
+ * @param title title.
+ * @param entitySet entity set.
+ */
+ ODataInlineEntitySet(final ODataClient client, final URI uri, final ODataLinkType type, final String title,
+ final ODataEntitySet entitySet) {
+
+ super(client, uri, type, title);
+ this.entitySet = entitySet;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param client OData client.
+ * @param baseURI base URI.
+ * @param href href.
+ * @param type type.
+ * @param title title.
+ * @param entitySet entity set.
+ */
+ ODataInlineEntitySet(final ODataClient client, final URI baseURI, final String href, final ODataLinkType type,
+ final String title, final ODataEntitySet entitySet) {
+
+ super(client, baseURI, href, type, title);
+ this.entitySet = entitySet;
+ }
+
+ /**
+ * Gets wrapped entity set.
+ *
+ * @return wrapped entity set.
+ */
+ public ODataEntitySet getEntitySet() {
+ return entitySet;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInvokeResult.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInvokeResult.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInvokeResult.java
new file mode 100644
index 0000000..a2501df
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataInvokeResult.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+/**
+ * Marker interface for any OData domain object that can be returned by an operation invocation.
+ *
+ * @see ODataEntitySet
+ * @see ODataEntity
+ * @see ODataProperty
+ * @see ODataNoContent
+ */
+public interface ODataInvokeResult {
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataItem.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataItem.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataItem.java
new file mode 100644
index 0000000..0b2a891
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataItem.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.io.Serializable;
+import java.net.URI;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract representation of OData entities and links.
+ */
+public abstract class ODataItem implements Serializable {
+
+ private static final long serialVersionUID = -2600707722689304686L;
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(ODataItem.class);
+
+ /**
+ * OData item self link.
+ */
+ protected URI link;
+
+ /**
+ * OData entity name/type.
+ */
+ private final String name;
+
+ /**
+ * Constructor.
+ *
+ * @param name OData entity name.
+ */
+ public ODataItem(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns self link.
+ *
+ * @return entity edit link.
+ */
+ public URI getLink() {
+ return link;
+ }
+
+ /**
+ * Sets self link.
+ *
+ * @param link link.
+ */
+ public void setLink(final URI link) {
+ this.link = link;
+ }
+
+ /**
+ * Returns OData entity name.
+ *
+ * @return entity name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLink.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLink.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLink.java
new file mode 100644
index 0000000..770d39d
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLink.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.utils.ODataVersion;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+import java.net.URI;
+
+/**
+ * OData link.
+ */
+public class ODataLink extends ODataItem {
+
+ private static final long serialVersionUID = 7274966414277952124L;
+
+ protected final ODataClient client;
+
+ /**
+ * Link type.
+ */
+ protected final ODataLinkType type;
+
+ /**
+ * Link rel.
+ */
+ protected final String rel;
+
+ /**
+ * Constructor.
+ *
+ * @param client OData client.
+ * @param uri URI.
+ * @param type type.
+ * @param title title.
+ */
+ ODataLink(final ODataClient client, final URI uri, final ODataLinkType type, final String title) {
+ super(title);
+ this.client = client;
+ this.link = uri;
+
+ this.type = type;
+
+ switch (this.type) {
+ case ASSOCIATION:
+ this.rel = client.getWorkingVersion().getNamespaceMap().get(ODataVersion.ASSOCIATION_LINK_REL) + title;
+ break;
+
+ case ENTITY_NAVIGATION:
+ case ENTITY_SET_NAVIGATION:
+ this.rel = client.getWorkingVersion().getNamespaceMap().get(ODataVersion.NAVIGATION_LINK_REL) + title;
+ break;
+
+ case MEDIA_EDIT:
+ default:
+ this.rel = client.getWorkingVersion().getNamespaceMap().get(ODataVersion.MEDIA_EDIT_LINK_REL) + title;
+ break;
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param client OData client.
+ * @param baseURI base URI.
+ * @param href href.
+ * @param type type.
+ * @param title title.
+ */
+ ODataLink(
+ final ODataClient client, final URI baseURI, final String href, final ODataLinkType type, final String title) {
+
+ this(client, URIUtils.getURI(baseURI, href), type, title);
+ }
+
+ /**
+ * Gets link type.
+ *
+ * @return link type;
+ */
+ public ODataLinkType getType() {
+ return type;
+ }
+
+ /**
+ * Gets link rel.
+ *
+ * @return link rel
+ */
+ public String getRel() {
+ return rel;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkCollection.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkCollection.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkCollection.java
new file mode 100644
index 0000000..abd6a68
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkCollection.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.net.URI;
+import java.util.List;
+
+/**
+ * Link collection wrapper.
+ */
+public class ODataLinkCollection {
+
+ /**
+ * Link to the next page.
+ */
+ private URI next;
+
+ /**
+ * Contained links.
+ */
+ private List<URI> links;
+
+ /**
+ * Constructor.
+ */
+ public ODataLinkCollection() {
+ }
+
+ /**
+ * Adds link to the collection.
+ *
+ * @param link link to be added.
+ * @return 'TRUE' in case of success; 'FALSE' otherwise.
+ */
+ public boolean addLink(final URI link) {
+ return links.add(link);
+ }
+
+ /**
+ * Removes a link.
+ *
+ * @param link link to be removed.
+ * @return 'TRUE' in case of success; 'FALSE' otherwise.
+ */
+ public boolean removeLink(final URI link) {
+ return links.remove(link);
+ }
+
+ /**
+ * Set links.
+ *
+ * @param links links.
+ */
+ public void setLinks(final List<URI> links) {
+ this.links = links;
+ }
+
+ /**
+ * Gets contained links.
+ *
+ * @return list of links.
+ */
+ public List<URI> getLinks() {
+ return links;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param next next page link.
+ */
+ public ODataLinkCollection(final URI next) {
+ this.next = next;
+ }
+
+ /**
+ * Gets next page link.
+ *
+ * @return next page link; null value if single page or last page reached.
+ */
+ public URI getNext() {
+ return next;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkType.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkType.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkType.java
new file mode 100644
index 0000000..a424e0f
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataLinkType.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import com.msopentech.odatajclient.engine.utils.ODataVersion;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.entity.ContentType;
+
+/**
+ * OData link types.
+ */
+public enum ODataLinkType {
+
+ /**
+ * Entity navigation link.
+ */
+ ENTITY_NAVIGATION(ODataPubFormat.ATOM + ";type=entry"),
+ /**
+ * Entity set navigation link.
+ */
+ ENTITY_SET_NAVIGATION(ODataPubFormat.ATOM + ";type=feed"),
+ /**
+ * Association link.
+ */
+ ASSOCIATION(ContentType.APPLICATION_XML.getMimeType()),
+ /**
+ * Media-edit link.
+ */
+ MEDIA_EDIT("*/*");
+
+ private String type;
+
+ private ODataLinkType(final String type) {
+ this.type = type;
+ }
+
+ private ODataLinkType setType(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * Gets
+ * <code>ODataLinkType</code> instance from the given rel and type.
+ *
+ * @param client OData client.
+ * @param rel rel.
+ * @param type type.
+ * @return <code>ODataLinkType</code> object.
+ */
+ public static ODataLinkType fromString(final ODataClient client, final String rel, final String type) {
+ if (StringUtils.isNotBlank(rel)
+ && rel.startsWith(client.getWorkingVersion().getNamespaceMap().get(ODataVersion.MEDIA_EDIT_LINK_REL))) {
+
+ return MEDIA_EDIT.setType(StringUtils.isBlank(type) ? "*/*" : type);
+ }
+
+ if (ODataLinkType.ENTITY_NAVIGATION.type.equals(type)) {
+ return ENTITY_NAVIGATION;
+ }
+
+ if (ODataLinkType.ENTITY_SET_NAVIGATION.type.equals(type)) {
+ return ENTITY_SET_NAVIGATION;
+ }
+
+ if (ODataLinkType.ASSOCIATION.type.equals(type)) {
+ return ASSOCIATION;
+ }
+
+ throw new IllegalArgumentException("Invalid link type: " + type);
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public String toString() {
+ return type;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataNoContent.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataNoContent.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataNoContent.java
new file mode 100644
index 0000000..254c8f4
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/data/ODataNoContent.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * Licensed 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.data;
+
+import java.io.Serializable;
+
+/**
+ * Marker class for invoke with no return type.
+ */
+public class ODataNoContent implements Serializable, ODataInvokeResult {
+
+ private static final long serialVersionUID = 2780193571934253136L;
+
+}