You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/04/01 11:00:46 UTC
[34/52] [abbrv] [OLINGO-200] Moving Atom and JSON (de)serializer to
commons
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Link.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Link.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Link.java
new file mode 100644
index 0000000..f0a35a5
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Link.java
@@ -0,0 +1,121 @@
+/*
+ * 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.commons.api.data;
+
+public interface Link {
+
+ /**
+ * Gets rel info.
+ *
+ * @return rel info.
+ */
+ String getRel();
+
+ /**
+ * Sets rel info.
+ *
+ * @param rel rel info.
+ */
+ void setRel(String rel);
+
+ /**
+ * Gets type.
+ *
+ * @return type.
+ */
+ String getType();
+
+ /**
+ * Sets type.
+ *
+ * @param type type.
+ */
+ void setType(String type);
+
+ /**
+ * Gets title.
+ *
+ * @return title.
+ */
+ String getTitle();
+
+ /**
+ * Sets title.
+ *
+ * @param title title.
+ */
+ void setTitle(String title);
+
+ /**
+ * Gets href.
+ *
+ * @return href.
+ */
+ String getHref();
+
+ /**
+ * Sets href.
+ *
+ * @param href href.
+ */
+ void setHref(String href);
+
+ /**
+ * Gets Media ETag.
+ *
+ * @return media ETag
+ */
+ String getMediaETag();
+
+ /**
+ * Sets Media ETag.
+ *
+ * @param etag media ETag
+ */
+ void setMediaETag(String etag);
+
+ /**
+ * Gets in-line entry.
+ *
+ * @return in-line entry.
+ */
+ Entry getInlineEntry();
+
+ /**
+ * Sets in-line entry.
+ *
+ * @param entry entry.
+ */
+ void setInlineEntry(Entry entry);
+
+ /**
+ * Gets in-line feed.
+ *
+ * @return in-line feed.
+ */
+ Feed getInlineFeed();
+
+ /**
+ * Sets in-line feed.
+ *
+ * @param feed feed.
+ */
+ void setInlineFeed(Feed feed);
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/NullValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/NullValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/NullValue.java
new file mode 100644
index 0000000..2fed975
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/NullValue.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.commons.api.data;
+
+public interface NullValue extends Value {
+
+ @Override
+ Void get();
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/PrimitiveValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/PrimitiveValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/PrimitiveValue.java
new file mode 100644
index 0000000..dabbc47
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/PrimitiveValue.java
@@ -0,0 +1,25 @@
+/*
+ * 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.commons.api.data;
+
+public interface PrimitiveValue extends Value {
+
+ @Override
+ String get();
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
new file mode 100644
index 0000000..feb8f71
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Property.java
@@ -0,0 +1,34 @@
+/*
+ * 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.commons.api.data;
+
+public interface Property {
+
+ String getName();
+
+ void setName(String name);
+
+ String getType();
+
+ void setType(String type);
+
+ Value getValue();
+
+ void setValue(Value value);
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Value.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Value.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Value.java
new file mode 100644
index 0000000..045751d
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Value.java
@@ -0,0 +1,44 @@
+/*
+ * 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.commons.api.data;
+
+public interface Value {
+
+ boolean isNull();
+
+ boolean isSimple();
+
+ boolean isGeospatial();
+
+ boolean isComplex();
+
+ boolean isCollection();
+
+ Object get();
+
+ NullValue asNull();
+
+ PrimitiveValue asSimple();
+
+ GeospatialValue asGeospatial();
+
+ ComplexValue asComplex();
+
+ CollectionValue asCollection();
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/v3/LinkCollection.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/v3/LinkCollection.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/v3/LinkCollection.java
new file mode 100644
index 0000000..72186fc
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/v3/LinkCollection.java
@@ -0,0 +1,52 @@
+/*
+ * 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.commons.api.data.v3;
+
+import java.net.URI;
+import java.util.List;
+
+/**
+ * REST resource for an <tt>ODataLinkCollection</tt>.
+ *
+ * @see org.apache.olingo.client.api.domain.ODataLinkCollection
+ */
+public interface LinkCollection {
+
+ /**
+ * Smart management of different JSON format produced by OData services when
+ * <tt>$links</tt> is a single or a collection property.
+ *
+ * @return list of URIs for <tt>$links</tt>
+ */
+ List<URI> getLinks();
+
+ /**
+ * Sets next link.
+ *
+ * @param next next link.
+ */
+ void setNext(final URI next);
+
+ /**
+ * Gets next link if exists.
+ *
+ * @return next link if exists; null otherwise.
+ */
+ URI getNext();
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/commons-core/pom.xml b/lib/commons-core/pom.xml
index a767566..f025fd0 100644
--- a/lib/commons-core/pom.xml
+++ b/lib/commons-core/pom.xml
@@ -46,6 +46,27 @@
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-xml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml</groupId>
+ <artifactId>aalto-xml</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
new file mode 100644
index 0000000..940d8a5
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
@@ -0,0 +1,87 @@
+/*
+ * 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.commons.core.data;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+abstract class AbstractAtomDealer {
+
+ protected static final String TYPE_TEXT = "text";
+
+ protected final ODataServiceVersion version;
+
+ protected final QName etagQName;
+
+ protected final QName inlineQName;
+
+ protected final QName actionQName;
+
+ protected final QName propertiesQName;
+
+ protected final QName typeQName;
+
+ protected final QName nullQName;
+
+ protected final QName elementQName;
+
+ protected final QName countQName;
+
+ protected final QName uriQName;
+ protected final QName nextQName;
+
+ public AbstractAtomDealer(final ODataServiceVersion version) {
+ this.version = version;
+
+ this.etagQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ATTR_ETAG);
+ this.inlineQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_INLINE);
+ this.actionQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_ACTION);
+ this.propertiesQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.PROPERTIES);
+ this.typeQName = new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATTR_TYPE);
+ this.nullQName = new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATTR_NULL);
+ this.elementQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_ELEMENT);
+ this.countQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_COUNT);
+ this.uriQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_URI);
+ this.nextQName =
+ new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.NEXT_LINK_REL);
+ }
+
+ protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeNamespace(StringUtils.EMPTY, Constants.NS_ATOM);
+ writer.writeNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
+ writer.writeNamespace(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
+ writer.writeNamespace(
+ Constants.PREFIX_DATASERVICES, version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
+ writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML);
+ writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
new file mode 100644
index 0000000..f09de40
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
@@ -0,0 +1,78 @@
+/*
+ * 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.commons.core.data;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
+
+abstract class AbstractAtomObject extends AbstractPayloadObject {
+
+ private static final long serialVersionUID = -4391162864875546927L;
+
+ private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
+
+ private URI baseURI;
+
+ private String id;
+
+ private String title;
+
+ private String summary;
+
+ private Date updated;
+
+ public URI getBaseURI() {
+ return baseURI;
+ }
+
+ public void setBaseURI(final String baseURI) {
+ this.baseURI = URI.create(baseURI);
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public Date getUpdated() {
+ return updated;
+ }
+
+ public void setCommonProperty(final String key, final String value) throws ParseException {
+ if ("id".equals(key)) {
+ this.id = value;
+ } else if ("title".equals(key)) {
+ this.title = value;
+ } else if ("summary".equals(key)) {
+ this.summary = value;
+ } else if ("updated".equals(key)) {
+ this.updated = ISO_DATEFORMAT.parse(value);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
new file mode 100644
index 0000000..29a4a75
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
@@ -0,0 +1,159 @@
+/*
+ * 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.commons.core.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.commons.api.data.Entry;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.domain.ODataOperation;
+
+/**
+ * Abstract base for classes implementing an OData entry in Atom and JSON.
+ */
+public abstract class AbstractEntry extends AbstractAtomObject implements Entry {
+
+ private static final long serialVersionUID = 2127764552600969783L;
+
+ private String eTag;
+
+ private String type;
+
+ private Link readLink;
+
+ private Link editLink;
+
+ private final List<Link> associationLinks = new ArrayList<Link>();
+
+ private final List<Link> navigationLinks = new ArrayList<Link>();
+
+ private final List<Link> mediaEditLinks = new ArrayList<Link>();
+
+ private final List<ODataOperation> operations = new ArrayList<ODataOperation>();
+
+ private final List<Property> properties = new ArrayList<Property>();
+
+ private String mediaContentSource;
+
+ private String mediaContentType;
+
+ @Override
+ public String getETag() {
+ return eTag;
+ }
+
+ public void setETag(final String eTag) {
+ this.eTag = eTag;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ @Override
+ public Link getSelfLink() {
+ return readLink;
+ }
+
+ @Override
+ public void setSelfLink(final Link readLink) {
+ this.readLink = readLink;
+ }
+
+ @Override
+ public Link getEditLink() {
+ return editLink;
+ }
+
+ @Override
+ public void setEditLink(final Link editLink) {
+ this.editLink = editLink;
+ }
+
+ @Override
+ public List<Link> getAssociationLinks() {
+ return associationLinks;
+ }
+
+ @Override
+ public List<Link> getNavigationLinks() {
+ return navigationLinks;
+ }
+
+ @Override
+ public List<Link> getMediaEditLinks() {
+ return mediaEditLinks;
+ }
+
+ @Override
+ public List<ODataOperation> getOperations() {
+ return operations;
+ }
+
+ @Override
+ public List<Property> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public Property getProperty(final String name) {
+ Property result = null;
+
+ for (Property property : properties) {
+ if (name.equals(property.getName())) {
+ result = property;
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public String getMediaContentType() {
+ return this.mediaContentType;
+ }
+
+ @Override
+ public void setMediaContentType(final String mediaContentType) {
+ this.mediaContentType = mediaContentType;
+ }
+
+ @Override
+ public String getMediaContentSource() {
+ return this.mediaContentSource;
+ }
+
+ @Override
+ public void setMediaContentSource(final String mediaContentSource) {
+ this.mediaContentSource = mediaContentSource;
+ }
+
+ @Override
+ public boolean isMediaEntry() {
+ return StringUtils.isNotBlank(this.mediaContentSource);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
new file mode 100644
index 0000000..2d865ce
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
@@ -0,0 +1,176 @@
+/*
+ * 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.commons.core.data;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.CollectionValue;
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.Value;
+import org.apache.olingo.commons.api.domain.ODataPropertyType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+
+abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
+
+ private JSONGeoValueDeserializer geoDeserializer;
+
+ private JSONGeoValueDeserializer getGeoDeserializer() {
+ if (geoDeserializer == null) {
+ geoDeserializer = new JSONGeoValueDeserializer(version);
+ }
+ return geoDeserializer;
+ }
+
+ protected EdmPrimitiveTypeKind getPrimitiveType(final JsonNode node) {
+ EdmPrimitiveTypeKind result = EdmPrimitiveTypeKind.String;
+
+ if (node.isIntegralNumber()) {
+ result = EdmPrimitiveTypeKind.Int32;
+ } else if (node.isBoolean()) {
+ result = EdmPrimitiveTypeKind.Boolean;
+ } else if (node.isFloatingPointNumber()) {
+ result = EdmPrimitiveTypeKind.Double;
+ }
+
+ return result;
+ }
+
+ private ODataPropertyType guessPropertyType(final JsonNode node) {
+ ODataPropertyType type = null;
+
+ if (node.isValueNode() || node.isNull()) {
+ type = ODataPropertyType.PRIMITIVE;
+ } else if (node.isArray()) {
+ type = ODataPropertyType.COLLECTION;
+ } else if (node.isObject()) {
+ type = ODataPropertyType.COMPLEX;
+ } else {
+ type = ODataPropertyType.EMPTY;
+ }
+
+ return type;
+ }
+
+ private Value fromPrimitive(final JsonNode node, final EdmTypeInfo typeInfo) {
+ Value value = null;
+
+ if (node.isNull()) {
+ value = new NullValueImpl();
+ } else {
+ if (typeInfo != null && typeInfo.getPrimitiveTypeKind().isGeospatial()) {
+ value = new GeospatialValueImpl(getGeoDeserializer().deserialize(node, typeInfo));
+ } else {
+ value = new PrimitiveValueImpl(node.asText());
+ }
+ }
+
+ return value;
+ }
+
+ private ComplexValue fromComplex(final JsonNode node) {
+ final ComplexValue value = new ComplexValueImpl();
+
+ String type = null;
+ for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
+ final Map.Entry<String, JsonNode> field = itor.next();
+
+ if (type == null && field.getKey().endsWith(Constants.JSON_TYPE_SUFFIX)) {
+ type = field.getValue().asText();
+ } else {
+ final JSONPropertyImpl property = new JSONPropertyImpl();
+ property.setName(field.getKey());
+ property.setType(type);
+ type = null;
+
+ value(property, field.getValue());
+ value.get().add(property);
+ }
+ }
+
+ return value;
+ }
+
+ private CollectionValue fromCollection(final Iterator<JsonNode> nodeItor, final EdmTypeInfo typeInfo) {
+ final CollectionValueImpl value = new CollectionValueImpl();
+
+ final EdmTypeInfo type = typeInfo == null
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+
+ while (nodeItor.hasNext()) {
+ final JsonNode child = nodeItor.next();
+
+ if (child.isValueNode()) {
+ value.get().add(fromPrimitive(child, type));
+ } else if (child.isContainerNode()) {
+ if (child.has(Constants.JSON_TYPE)) {
+ ((ObjectNode) child).remove(Constants.JSON_TYPE);
+ }
+ value.get().add(fromComplex(child));
+ }
+ }
+
+ return value;
+ }
+
+ protected void value(final JSONPropertyImpl property, final JsonNode node) {
+ final EdmTypeInfo typeInfo = StringUtils.isBlank(property.getType())
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
+
+ final ODataPropertyType propType = typeInfo == null
+ ? guessPropertyType(node)
+ : typeInfo.isCollection()
+ ? ODataPropertyType.COLLECTION
+ : typeInfo.isPrimitiveType()
+ ? ODataPropertyType.PRIMITIVE
+ : ODataPropertyType.COMPLEX;
+
+ switch (propType) {
+ case COLLECTION:
+ property.setValue(fromCollection(node.elements(), typeInfo));
+ break;
+
+ case COMPLEX:
+ if (node.has(Constants.JSON_TYPE)) {
+ property.setType(node.get(Constants.JSON_TYPE).asText());
+ ((ObjectNode) node).remove(Constants.JSON_TYPE);
+ }
+ property.setValue(fromComplex(node));
+ break;
+
+ case PRIMITIVE:
+ if (property.getType() == null) {
+ property.setType(getPrimitiveType(node).getFullQualifiedName().toString());
+ }
+ property.setValue(fromPrimitive(node, typeInfo));
+ break;
+
+ case EMPTY:
+ default:
+ property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
new file mode 100644
index 0000000..1380dd5
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonSerializer.java
@@ -0,0 +1,94 @@
+/*
+ * 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.commons.core.data;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.olingo.commons.api.data.CollectionValue;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.Value;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+
+abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
+
+ private static final EdmPrimitiveTypeKind[] NUMBER_TYPES = {
+ EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
+ EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
+ EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, EdmPrimitiveTypeKind.Int64
+ };
+
+ private final JSONGeoValueSerializer geoSerializer = new JSONGeoValueSerializer();
+
+ private void collection(final JsonGenerator jgen, final String itemType, final CollectionValue value)
+ throws IOException {
+
+ jgen.writeStartArray();
+ for (Value item : value.get()) {
+ value(jgen, itemType, item);
+ }
+ jgen.writeEndArray();
+ }
+
+ private void value(final JsonGenerator jgen, final String type, final Value value) throws IOException {
+ final EdmTypeInfo typeInfo = type == null
+ ? null
+ : new EdmTypeInfo.Builder().setTypeExpression(type).build();
+
+ if (value.isNull()) {
+ jgen.writeNull();
+ } else if (value.isSimple()) {
+ final boolean isNumber = typeInfo == null
+ ? NumberUtils.isNumber(value.asSimple().get())
+ : ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveTypeKind());
+ final boolean isBoolean = typeInfo == null
+ ? (value.asSimple().get().equalsIgnoreCase(Boolean.TRUE.toString())
+ || value.asSimple().get().equalsIgnoreCase(Boolean.FALSE.toString()))
+ : typeInfo.getPrimitiveTypeKind() == EdmPrimitiveTypeKind.Boolean;
+
+ if (isNumber) {
+ jgen.writeNumber(value.asSimple().get());
+ } else if (isBoolean) {
+ jgen.writeBoolean(BooleanUtils.toBoolean(value.asSimple().get()));
+ } else {
+ jgen.writeString(value.asSimple().get());
+ }
+ } else if (value.isGeospatial()) {
+ jgen.writeStartObject();
+ geoSerializer.serialize(jgen, value.asGeospatial().get());
+ jgen.writeEndObject();
+ } else if (value.isCollection()) {
+ collection(jgen, typeInfo == null ? null : typeInfo.getFullQualifiedName().toString(), value.asCollection());
+ } else if (value.isComplex()) {
+ jgen.writeStartObject();
+ for (Property property : value.asComplex().get()) {
+ property(jgen, property, property.getName());
+ }
+ jgen.writeEndObject();
+ }
+ }
+
+ protected void property(final JsonGenerator jgen, final Property property, final String name) throws IOException {
+ jgen.writeFieldName(name);
+ value(jgen, property.getType(), property.getValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPayloadObject.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPayloadObject.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPayloadObject.java
new file mode 100644
index 0000000..bad009d
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPayloadObject.java
@@ -0,0 +1,48 @@
+/*
+ * 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.commons.core.data;
+
+import java.io.Serializable;
+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;
+
+/**
+ * Abstract representation of a payload (Atom, JSON) object.
+ */
+public abstract class AbstractPayloadObject implements Serializable {
+
+ private static final long serialVersionUID = 1634654241914156675L;
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java
new file mode 100644
index 0000000..e005f98
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.commons.core.data;
+
+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.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.Value;
+
+public abstract class AbstractPropertyImpl implements Property {
+
+ private String name;
+
+ private String type;
+
+ private Value value;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ @Override
+ public Value getValue() {
+ return value;
+ }
+
+ @Override
+ public void setValue(final Value value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValue.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValue.java
new file mode 100644
index 0000000..31629e2
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractValue.java
@@ -0,0 +1,98 @@
+/*
+ * 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.commons.core.data;
+
+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.apache.olingo.commons.api.data.CollectionValue;
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.GeospatialValue;
+import org.apache.olingo.commons.api.data.NullValue;
+import org.apache.olingo.commons.api.data.PrimitiveValue;
+import org.apache.olingo.commons.api.data.Value;
+
+public abstract class AbstractValue implements Value {
+
+ @Override
+ public boolean isNull() {
+ return false;
+ }
+
+ @Override
+ public boolean isSimple() {
+ return false;
+ }
+
+ @Override
+ public boolean isGeospatial() {
+ return false;
+ }
+
+ @Override
+ public boolean isComplex() {
+ return false;
+ }
+
+ @Override
+ public boolean isCollection() {
+ return false;
+ }
+
+ @Override
+ public NullValue asNull() {
+ return isNull() ? (NullValue) this : null;
+ }
+
+ @Override
+ public PrimitiveValue asSimple() {
+ return isSimple() ? (PrimitiveValue) this : null;
+ }
+
+ @Override
+ public GeospatialValue asGeospatial() {
+ return isGeospatial() ? (GeospatialValue) this : null;
+ }
+
+ @Override
+ public ComplexValue asComplex() {
+ return isComplex() ? (ComplexValue) this : null;
+ }
+
+ @Override
+ public CollectionValue asCollection() {
+ return isCollection() ? (CollectionValue) this : null;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return EqualsBuilder.reflectionEquals(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
new file mode 100644
index 0000000..f42fe00
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
@@ -0,0 +1,370 @@
+/*
+ * 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.commons.core.data;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.text.ParseException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.domain.ODataOperation;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.core.data.v3.XMLLinkCollectionImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AtomDeserializer extends AbstractAtomDealer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
+
+ private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
+
+ private final AtomPropertyDeserializer propDeserializer;
+
+ public AtomDeserializer(final ODataServiceVersion version) {
+ super(version);
+ this.propDeserializer = new AtomPropertyDeserializer(version);
+ }
+
+ private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ private StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
+ StartElement startEvent = null;
+ while (reader.hasNext() && startEvent == null) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ startEvent = event.asStartElement();
+ }
+ }
+ if (startEvent == null) {
+ throw new IllegalArgumentException("Cannot find any XML start element");
+ }
+
+ return startEvent;
+ }
+
+ private void common(final XMLEventReader reader, final StartElement start,
+ final AbstractAtomObject object, final String key) throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ try {
+ object.setCommonProperty(key, event.asCharacters().getData());
+ } catch (ParseException e) {
+ throw new XMLStreamException("While parsing Atom entry or feed common elements", e);
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private void inline(final XMLEventReader reader, final StartElement start, final LinkImpl link)
+ throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
+ StartElement inline = null;
+ while (reader.hasNext() && inline == null) {
+ final XMLEvent innerEvent = reader.peek();
+ if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
+ reader.nextEvent();
+ } else if (innerEvent.isStartElement()) {
+ inline = innerEvent.asStartElement();
+ }
+ }
+ if (inline != null) {
+ if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
+ link.setInlineEntry(entry(reader, inline));
+ }
+ if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
+ link.setInlineFeed(feed(reader, inline));
+ }
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private XMLLinkCollectionImpl linkCollection(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+
+ final XMLLinkCollectionImpl linkCollection = new XMLLinkCollectionImpl();
+
+ boolean isURI = false;
+ boolean isNext = false;
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ isURI = uriQName.equals(event.asStartElement().getName());
+ isNext = nextQName.equals(event.asStartElement().getName());
+ }
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ if (isURI) {
+ linkCollection.getLinks().add(URI.create(event.asCharacters().getData()));
+ isURI = false;
+ } else if (isNext) {
+ linkCollection.setNext(URI.create(event.asCharacters().getData()));
+ isNext = false;
+ }
+ }
+ }
+
+ return linkCollection;
+ }
+
+ private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
+ throws XMLStreamException {
+
+ boolean foundEndProperties = false;
+ while (reader.hasNext() && !foundEndProperties) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ entry.getProperties().add(propDeserializer.deserialize(reader, event.asStartElement()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperties = true;
+ }
+ }
+ }
+
+ private AtomEntryImpl entry(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+ if (!Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
+ return null;
+ }
+
+ final AtomEntryImpl entry = new AtomEntryImpl();
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ entry.setBaseURI(xmlBase.getValue());
+ }
+ final Attribute etag = start.getAttributeByName(etagQName);
+ if (etag != null) {
+ entry.setETag(etag.getValue());
+ }
+
+ boolean foundEndEntry = false;
+ while (reader.hasNext() && !foundEndEntry) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "id");
+ } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "title");
+ } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "summary");
+ } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), entry, "updated");
+ } else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
+ final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
+ if (term != null) {
+ entry.setType(term.getValue());
+ }
+ } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+ final LinkImpl link = new LinkImpl();
+ final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+ if (rel != null) {
+ link.setRel(rel.getValue());
+ }
+ final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+ if (title != null) {
+ link.setTitle(title.getValue());
+ }
+ final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+ if (href != null) {
+ link.setHref(href.getValue());
+ }
+ final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+ if (type != null) {
+ link.setType(type.getValue());
+ }
+
+ if (Constants.SELF_LINK_REL.equals(link.getRel())) {
+ entry.setSelfLink(link);
+ } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
+ entry.setEditLink(link);
+ } else if (link.getRel().startsWith(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
+ entry.getNavigationLinks().add(link);
+ inline(reader, event.asStartElement(), link);
+ } else if (link.getRel().startsWith(
+ version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
+
+ entry.getAssociationLinks().add(link);
+ } else if (link.getRel().startsWith(
+ version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+
+ final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
+ if (metag != null) {
+ link.setMediaETag(metag.getValue());
+ }
+ entry.getMediaEditLinks().add(link);
+ }
+ } else if (actionQName.equals(event.asStartElement().getName())) {
+ final ODataOperation operation = new ODataOperation();
+ final Attribute metadata = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
+ if (metadata != null) {
+ operation.setMetadataAnchor(metadata.getValue());
+ }
+ final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+ if (title != null) {
+ operation.setTitle(title.getValue());
+ }
+ final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
+ if (target != null) {
+ operation.setTarget(URI.create(target.getValue()));
+ }
+
+ entry.getOperations().add(operation);
+ } else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
+ final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+ if (type == null || ContentType.APPLICATION_XML.equals(type.getValue())) {
+ properties(reader, skipBeforeFirstStartElement(reader), entry);
+ } else {
+ entry.setMediaContentType(type.getValue());
+ final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
+ if (src != null) {
+ entry.setMediaContentSource(src.getValue());
+ }
+ }
+ } else if (propertiesQName.equals(event.asStartElement().getName())) {
+ properties(reader, event.asStartElement(), entry);
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndEntry = true;
+ }
+ }
+
+ return entry;
+ }
+
+ private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return entry(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
+ throws XMLStreamException {
+
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ feed.setCount(Integer.valueOf(event.asCharacters().getData()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
+ }
+
+ private AtomFeedImpl feed(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+ if (!Constants.QNAME_ATOM_ELEM_FEED.equals(start.getName())) {
+ return null;
+ }
+
+ final AtomFeedImpl feed = new AtomFeedImpl();
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ feed.setBaseURI(xmlBase.getValue());
+ }
+
+ boolean foundEndFeed = false;
+ while (reader.hasNext() && !foundEndFeed) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ if (countQName.equals(event.asStartElement().getName())) {
+ count(reader, event.asStartElement(), feed);
+ } else if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "id");
+ } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "title");
+ } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "summary");
+ } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+ common(reader, event.asStartElement(), feed, "updated");
+ } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+ final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+ if (rel != null && Constants.NEXT_LINK_REL.equals(rel.getValue())) {
+ final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+ if (href != null) {
+ feed.setNext(URI.create(href.getValue()));
+ }
+ }
+ } else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(event.asStartElement().getName())) {
+ feed.getEntries().add(entry(reader, event.asStartElement()));
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndFeed = true;
+ }
+ }
+
+ return feed;
+ }
+
+ private AtomFeedImpl feed(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return feed(reader, skipBeforeFirstStartElement(reader));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T read(final InputStream input, final Class<T> reference) throws XMLStreamException {
+ if (AtomFeedImpl.class.equals(reference)) {
+ return (T) feed(input);
+ } else if (AtomEntryImpl.class.equals(reference)) {
+ return (T) entry(input);
+ } else if (AtomPropertyImpl.class.equals(reference)) {
+ return (T) property(input);
+ } else if (XMLLinkCollectionImpl.class.equals(reference)) {
+ return (T) linkCollection(input);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomEntryImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomEntryImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomEntryImpl.java
new file mode 100644
index 0000000..8eef97a
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomEntryImpl.java
@@ -0,0 +1,25 @@
+/*
+ * 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.commons.core.data;
+
+public class AtomEntryImpl extends AbstractEntry {
+
+ private static final long serialVersionUID = 6973729343868293279L;
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
new file mode 100644
index 0000000..d40f945
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.commons.core.data;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.olingo.commons.api.data.Entry;
+import org.apache.olingo.commons.api.data.Feed;
+
+/**
+ * List of entries, represented via Atom.
+ *
+ * @see AtomEntry
+ */
+public class AtomFeedImpl extends AbstractAtomObject implements Feed {
+
+ private static final long serialVersionUID = 5466590540021319153L;
+
+ private Integer count;
+
+ private final List<Entry> entries = new ArrayList<Entry>();
+
+ private URI next;
+
+ @Override
+ public void setCount(final Integer count) {
+ this.count = count;
+ }
+
+ @Override
+ public Integer getCount() {
+ return count;
+ }
+
+ @Override
+ public List<Entry> getEntries() {
+ return entries;
+ }
+
+ @Override
+ public void setNext(final URI next) {
+ this.next = next;
+ }
+
+ @Override
+ public URI getNext() {
+ return next;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueDeserializer.java
new file mode 100644
index 0000000..458e4cc
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueDeserializer.java
@@ -0,0 +1,261 @@
+/*
+ * 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.commons.core.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.GeoUtils;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
+import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
+import org.apache.olingo.commons.api.edm.geo.LineString;
+import org.apache.olingo.commons.api.edm.geo.MultiLineString;
+import org.apache.olingo.commons.api.edm.geo.MultiPoint;
+import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
+import org.apache.olingo.commons.api.edm.geo.Point;
+import org.apache.olingo.commons.api.edm.geo.Polygon;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
+
+class AtomGeoValueDeserializer {
+
+ private List<Point> points(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ final List<Point> result = new ArrayList<Point>();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ final String[] pointInfo = event.asCharacters().getData().split(" ");
+
+ final Point point = new Point(GeoUtils.getDimension(type), crs);
+ try {
+ point.setX(EdmDouble.getInstance().valueOfString(pointInfo[0], null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+ point.setY(EdmDouble.getInstance().valueOfString(pointInfo[1], null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null, Double.class));
+ } catch (EdmPrimitiveTypeException e) {
+ throw new XMLStreamException("While deserializing point coordinates as double", e);
+ }
+ result.add(point);
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return result;
+ }
+
+ private MultiPoint multipoint(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ List<Point> points = Collections.<Point>emptyList();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_POINTMEMBERS)) {
+ points = points(reader, event.asStartElement(), type, null);
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return new MultiPoint(GeoUtils.getDimension(type), crs, points);
+ }
+
+ private LineString lineString(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ return new LineString(GeoUtils.getDimension(type), crs, points(reader, start, type, null));
+ }
+
+ private Polygon polygon(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ List<Point> extPoints = null;
+ List<Point> intPoints = null;
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement()) {
+ if (event.asStartElement().getName().equals(Constants.QNAME_POLYGON_EXTERIOR)) {
+ extPoints = points(reader, event.asStartElement(), type, null);
+ }
+ if (event.asStartElement().getName().equals(Constants.QNAME_POLYGON_INTERIOR)) {
+ intPoints = points(reader, event.asStartElement(), type, null);
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return new Polygon(GeoUtils.getDimension(type), crs, intPoints, extPoints);
+ }
+
+ private MultiLineString multiLineString(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ final List<LineString> lineStrings = new ArrayList<LineString>();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_LINESTRING)) {
+ lineStrings.add(lineString(reader, event.asStartElement(), type, null));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return new MultiLineString(GeoUtils.getDimension(type), crs, lineStrings);
+ }
+
+ private MultiPolygon multiPolygon(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ final List<Polygon> polygons = new ArrayList<Polygon>();
+
+ boolean foundEndProperty = false;
+ while (reader.hasNext() && !foundEndProperty) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_POLYGON)) {
+ polygons.add(polygon(reader, event.asStartElement(), type, null));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperty = true;
+ }
+ }
+
+ return new MultiPolygon(GeoUtils.getDimension(type), crs, polygons);
+ }
+
+ private GeospatialCollection collection(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type, final String crs) throws XMLStreamException {
+
+ final List<Geospatial> geospatials = new ArrayList<Geospatial>();
+
+ boolean foundEndCollection = false;
+ while (reader.hasNext() && !foundEndCollection) {
+ final XMLEvent event = reader.nextEvent();
+
+ if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_GEOMEMBERS)) {
+ boolean foundEndMembers = false;
+ while (reader.hasNext() && !foundEndMembers) {
+ final XMLEvent subevent = reader.nextEvent();
+
+ if (subevent.isStartElement()) {
+ geospatials.add(deserialize(reader, subevent.asStartElement(),
+ GeoUtils.getType(GeoUtils.getDimension(type), subevent.asStartElement().getName().getLocalPart())));
+ }
+
+ if (subevent.isEndElement() && Constants.QNAME_GEOMEMBERS.equals(subevent.asEndElement().getName())) {
+ foundEndMembers = true;
+ }
+ }
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndCollection = true;
+ }
+ }
+
+ return new GeospatialCollection(GeoUtils.getDimension(type), crs, geospatials);
+ }
+
+ public Geospatial deserialize(final XMLEventReader reader, final StartElement start,
+ final EdmPrimitiveTypeKind type) throws XMLStreamException {
+
+ String crs = null;
+ final Attribute srsName = start.getAttributeByName(Constants.QNAME_ATTR_SRSNAME);
+ if (srsName != null) {
+ crs = StringUtils.substringAfterLast(srsName.getValue(), "/");
+ }
+
+ Geospatial value;
+
+ switch (type) {
+ case GeographyPoint:
+ case GeometryPoint:
+ value = points(reader, start, type, crs).get(0);
+ break;
+
+ case GeographyMultiPoint:
+ case GeometryMultiPoint:
+ value = multipoint(reader, start, type, crs);
+ break;
+
+ case GeographyLineString:
+ case GeometryLineString:
+ value = lineString(reader, start, type, crs);
+ break;
+
+ case GeographyMultiLineString:
+ case GeometryMultiLineString:
+ value = multiLineString(reader, start, type, crs);
+ break;
+
+ case GeographyPolygon:
+ case GeometryPolygon:
+ value = polygon(reader, start, type, crs);
+ break;
+
+ case GeographyMultiPolygon:
+ case GeometryMultiPolygon:
+ value = multiPolygon(reader, start, type, crs);
+ break;
+
+ case GeographyCollection:
+ case GeometryCollection:
+ value = collection(reader, start, type, crs);
+ break;
+
+ default:
+ value = null;
+ }
+
+ return value;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fac84b3e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueSerializer.java
new file mode 100644
index 0000000..624bcfa
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomGeoValueSerializer.java
@@ -0,0 +1,221 @@
+/*
+ * 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.commons.core.data;
+
+import java.util.Collections;
+import java.util.Iterator;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.geo.Geospatial;
+import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
+import org.apache.olingo.commons.api.edm.geo.LineString;
+import org.apache.olingo.commons.api.edm.geo.MultiLineString;
+import org.apache.olingo.commons.api.edm.geo.MultiPoint;
+import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
+import org.apache.olingo.commons.api.edm.geo.Point;
+import org.apache.olingo.commons.api.edm.geo.Polygon;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
+
+class AtomGeoValueSerializer {
+
+ private void points(final XMLStreamWriter writer, final Iterator<Point> itor, final boolean wrap)
+ throws XMLStreamException {
+
+ while (itor.hasNext()) {
+ final Point point = itor.next();
+
+ if (wrap) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
+ }
+
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POS, Constants.NS_GML);
+ try {
+ writer.writeCharacters(EdmDouble.getInstance().valueToString(point.getX(), null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null)
+ + " "
+ + EdmDouble.getInstance().valueToString(point.getY(), null, null,
+ Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null));
+ } catch (EdmPrimitiveTypeException e) {
+ throw new XMLStreamException("While serializing point coordinates as double", e);
+ }
+ writer.writeEndElement();
+
+ if (wrap) {
+ writer.writeEndElement();
+ }
+ }
+ }
+
+ private void lineStrings(final XMLStreamWriter writer, final Iterator<LineString> itor, final boolean wrap)
+ throws XMLStreamException {
+
+ while (itor.hasNext()) {
+ final LineString lineString = itor.next();
+
+ if (wrap) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
+ }
+
+ points(writer, lineString.iterator(), false);
+
+ if (wrap) {
+ writer.writeEndElement();
+ }
+ }
+ }
+
+ private void polygons(final XMLStreamWriter writer, final Iterator<Polygon> itor, final boolean wrap)
+ throws XMLStreamException {
+
+ while (itor.hasNext()) {
+ final Polygon polygon = itor.next();
+
+ if (wrap) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
+ }
+
+ if (!polygon.getExterior().isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_EXTERIOR, Constants.NS_GML);
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
+
+ points(writer, polygon.getExterior().iterator(), false);
+
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+ if (!polygon.getInterior().isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_INTERIOR, Constants.NS_GML);
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
+
+ points(writer, polygon.getInterior().iterator(), false);
+
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+
+ if (wrap) {
+ writer.writeEndElement();
+ }
+ }
+ }
+
+ private void writeSrsName(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
+ if (value.getCrs() != null) {
+ writer.writeAttribute(Constants.PREFIX_GML, Constants.NS_GML, Constants.ATTR_SRSNAME,
+ Constants.SRS_URLPREFIX + value.getCrs());
+ }
+ }
+
+ public void serialize(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
+ switch (value.getEdmPrimitiveTypeKind()) {
+ case GeographyPoint:
+ case GeometryPoint:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ points(writer, Collections.singleton((Point) value).iterator(), false);
+
+ writer.writeEndElement();
+ break;
+
+ case GeometryMultiPoint:
+ case GeographyMultiPoint:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOINT, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ if (!((MultiPoint) value).isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINTMEMBERS, Constants.NS_GML);
+ points(writer, ((MultiPoint) value).iterator(), true);
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();
+ break;
+
+ case GeometryLineString:
+ case GeographyLineString:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ lineStrings(writer, Collections.singleton((LineString) value).iterator(), false);
+
+ writer.writeEndElement();
+ break;
+
+ case GeometryMultiLineString:
+ case GeographyMultiLineString:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTILINESTRING, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ if (!((MultiLineString) value).isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRINGMEMBERS, Constants.NS_GML);
+ lineStrings(writer, ((MultiLineString) value).iterator(), true);
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();
+ break;
+
+ case GeographyPolygon:
+ case GeometryPolygon:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ polygons(writer, Collections.singleton(((Polygon) value)).iterator(), false);
+
+ writer.writeEndElement();
+ break;
+
+ case GeographyMultiPolygon:
+ case GeometryMultiPolygon:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOLYGON, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ if (!((MultiPolygon) value).isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_SURFACEMEMBERS, Constants.NS_GML);
+ polygons(writer, ((MultiPolygon) value).iterator(), true);
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();
+ break;
+
+ case GeographyCollection:
+ case GeometryCollection:
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOCOLLECTION, Constants.NS_GML);
+ writeSrsName(writer, value);
+
+ if (!((GeospatialCollection) value).isEmpty()) {
+ writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOMEMBERS, Constants.NS_GML);
+ for (final Iterator<Geospatial> itor = ((GeospatialCollection) value).iterator(); itor.hasNext();) {
+ serialize(writer, itor.next());
+ }
+ writer.writeEndElement();
+ }
+
+ writer.writeEndElement();
+ break;
+
+ default:
+ }
+ }
+
+}