You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/03/20 11:27:10 UTC
[16/21] [OLINGO-200] New StAX (replacing DOM) (de)serializers in
place - still IT to check
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
index 9110d2b..e7f9682 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
@@ -24,9 +24,8 @@ import java.io.Writer;
import org.apache.olingo.client.api.data.Entry;
import org.apache.olingo.client.api.data.Feed;
import org.apache.olingo.client.api.data.Link;
+import org.apache.olingo.client.api.data.Property;
import org.apache.olingo.client.api.format.ODataFormat;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
/**
* Utility class for serialization.
@@ -66,22 +65,20 @@ public interface ODataSerializer extends Serializable {
void entry(Entry obj, Writer writer);
/**
- * Writes entry content onto the given stream.
+ * Writes the property object onto the given stream.
*
- * @param element element to be streamed.
- * @param format streaming format.
+ * @param property object to be streamed.
* @param out output stream.
*/
- void property(Element element, ODataFormat format, OutputStream out);
+ void property(Property property, OutputStream out);
/**
- * Writes entry content by the given writer.
+ * Writes the property object by the given writer.
*
- * @param element element to be streamed.
- * @param format streaming format.
+ * @param property object to be streamed.
* @param writer writer.
*/
- void property(Element element, ODataFormat format, Writer writer);
+ void property(Property property, Writer writer);
/**
* Writes link onto the given stream.
@@ -100,20 +97,4 @@ public interface ODataSerializer extends Serializable {
* @param writer writer.
*/
void link(Link link, ODataFormat format, Writer writer);
-
- /**
- * Writes DOM object onto the given stream.
- *
- * @param content DOM to be streamed.
- * @param out output stream.
- */
- void dom(Node content, OutputStream out);
-
- /**
- * Writes DOM object by the given writer.
- *
- * @param content DOM to be streamed.
- * @param writer writer.
- */
- void dom(Node content, Writer writer);
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
new file mode 100644
index 0000000..c4270fe
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.api.utils;
+
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+
+public final class GeoUtils {
+
+ private GeoUtils() {
+ // Empty private constructor for static utility classes
+ }
+
+ public static Geospatial.Dimension getDimension(final ODataJClientEdmPrimitiveType type) {
+ Geospatial.Dimension dimension;
+
+ switch (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;
+ }
+
+ public static ODataJClientEdmPrimitiveType getType(final Geospatial.Dimension dimension, final String elementName) {
+ ODataJClientEdmPrimitiveType type = null;
+
+ if (Constants.ELEM_POINT.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyPoint
+ : ODataJClientEdmPrimitiveType.GeometryPoint;
+ } else if (Constants.ELEM_MULTIPOINT.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyMultiPoint
+ : ODataJClientEdmPrimitiveType.GeometryMultiPoint;
+ } else if (Constants.ELEM_LINESTRING.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyLineString
+ : ODataJClientEdmPrimitiveType.GeometryLineString;
+ } else if (Constants.ELEM_MULTILINESTRING.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyMultiLineString
+ : ODataJClientEdmPrimitiveType.GeometryMultiLineString;
+ } else if (Constants.ELEM_POLYGON.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyPolygon
+ : ODataJClientEdmPrimitiveType.GeometryPolygon;
+ } else if (Constants.ELEM_MULTIPOLYGON.equals(elementName)) {
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyMultiPolygon
+ : ODataJClientEdmPrimitiveType.GeometryMultiPolygon;
+ } else if (Constants.ELEM_GEOCOLLECTION.equals(elementName)
+ || Constants.ELEM_GEOMEMBERS.equals(elementName)) {
+
+ type = dimension == Geospatial.Dimension.GEOGRAPHY
+ ? ODataJClientEdmPrimitiveType.GeographyCollection
+ : ODataJClientEdmPrimitiveType.GeometryCollection;
+ }
+
+ return type;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
deleted file mode 100644
index 8baa7e3..0000000
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.client.api.utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.Constants;
-import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
-import org.apache.olingo.client.api.domain.geospatial.Geospatial;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * XML utilities.
- */
-public final class XMLUtils {
-
- /**
- * DOM factory.
- */
- public static final DocumentBuilderFactory DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
-
- private XMLUtils() {
- // Empty private constructor for static utility classes
- }
-
- /**
- * Gets XML node name.
- *
- * @param node node.
- * @return node name.
- */
- public static String getSimpleName(final Node node) {
- return node.getLocalName() == null
- ? node.getNodeName().substring(node.getNodeName().indexOf(':') + 1)
- : node.getLocalName();
- }
-
- /**
- * Gets the given node's children of the given type.
- *
- * @param node parent.
- * @param nodetype searched child type.
- * @return children.
- */
- public static List<Node> getChildNodes(final Node node, final short nodetype) {
- final List<Node> result = new ArrayList<Node>();
-
- final NodeList children = node.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- final Node child = children.item(i);
- if (child.getNodeType() == nodetype) {
- result.add(child);
- }
- }
-
- return result;
- }
-
- /**
- * Gets the given node's children with the given name.
- *
- * @param node parent.
- * @param name searched child name.
- * @return children.
- */
- public static List<Element> getChildElements(final Element node, final String name) {
- final List<Element> result = new ArrayList<Element>();
-
- if (StringUtils.isNotBlank(name)) {
- final NodeList children = node.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- final Node child = children.item(i);
- if ((child instanceof Element) && name.equals(child.getNodeName())) {
- result.add((Element) child);
- }
- }
- }
-
- return result;
- }
-
- /**
- * Checks if the given node has <tt>element</tt> children.
- *
- * @param node parent.
- * @return 'TRUE' if the given node has at least one <tt>element</tt> child; 'FALSE' otherwise.
- */
- public static boolean hasElementsChildNode(final Node node) {
- boolean found = false;
-
- for (Node child : getChildNodes(node, Node.ELEMENT_NODE)) {
- if (Constants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))) {
- found = true;
- }
- }
-
- return found;
- }
-
- /**
- * Checks if the given node has only text children.
- *
- * @param node parent.
- * @return 'TRUE' if the given node has only text children; 'FALSE' otherwise.
- */
- public static boolean hasOnlyTextChildNodes(final Node node) {
- boolean result = true;
- final NodeList children = node.getChildNodes();
- for (int i = 0; result && i < children.getLength(); i++) {
- final Node child = children.item(i);
- if (child.getNodeType() != Node.TEXT_NODE) {
- result = false;
- }
- }
-
- return result;
- }
-
- public static ODataJClientEdmPrimitiveType simpleTypeForNode(final Geospatial.Dimension dimension, final Node node) {
- ODataJClientEdmPrimitiveType type = null;
-
- if (Constants.ELEM_POINT.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyPoint
- : ODataJClientEdmPrimitiveType.GeometryPoint;
- } else if (Constants.ELEM_MULTIPOINT.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyMultiPoint
- : ODataJClientEdmPrimitiveType.GeometryMultiPoint;
- } else if (Constants.ELEM_LINESTRING.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyLineString
- : ODataJClientEdmPrimitiveType.GeometryLineString;
- } else if (Constants.ELEM_MULTILINESTRING.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyMultiLineString
- : ODataJClientEdmPrimitiveType.GeometryMultiLineString;
- } else if (Constants.ELEM_POLYGON.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyPolygon
- : ODataJClientEdmPrimitiveType.GeometryPolygon;
- } else if (Constants.ELEM_MULTIPOLYGON.equals(node.getNodeName())) {
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyMultiPolygon
- : ODataJClientEdmPrimitiveType.GeometryMultiPolygon;
- } else if (Constants.ELEM_GEOCOLLECTION.equals(node.getNodeName())
- || Constants.ELEM_GEOMEMBERS.equals(node.getNodeName())) {
-
- type = dimension == Geospatial.Dimension.GEOGRAPHY
- ? ODataJClientEdmPrimitiveType.GeographyCollection
- : ODataJClientEdmPrimitiveType.GeometryCollection;
- }
-
- return type;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml
index 2705261..9c52285 100644
--- a/lib/client-core/pom.xml
+++ b/lib/client-core/pom.xml
@@ -75,6 +75,10 @@
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.olingo</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java
new file mode 100644
index 0000000..64fa3d8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.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.client.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.client.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;
+
+ 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);
+ }
+
+ 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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java
new file mode 100644
index 0000000..76004d1
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/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.client.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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
index 4d7e8db..f92c44b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
@@ -23,13 +23,13 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.client.api.data.Entry;
import org.apache.olingo.client.api.data.Link;
+import org.apache.olingo.client.api.data.Property;
import org.apache.olingo.client.api.domain.ODataOperation;
-import org.w3c.dom.Element;
/**
* Abstract base for classes implementing an OData entry in Atom and JSON.
*/
-public abstract class AbstractEntry extends AbstractPayloadObject implements Entry {
+public abstract class AbstractEntry extends AbstractAtomObject implements Entry {
private static final long serialVersionUID = 2127764552600969783L;
@@ -37,8 +37,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
private String type;
- private String id;
-
private Link readLink;
private Link editLink;
@@ -51,9 +49,7 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
private final List<ODataOperation> operations = new ArrayList<ODataOperation>();
- private Element content;
-
- private Element mediaEntryProperties;
+ private final List<Property> properties = new ArrayList<Property>();
private String mediaContentSource;
@@ -64,7 +60,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
return eTag;
}
- @Override
public void setETag(final String eTag) {
this.eTag = eTag;
}
@@ -80,16 +75,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
}
@Override
- public String getId() {
- return id;
- }
-
- @Override
- public void setId(final String id) {
- this.id = id;
- }
-
- @Override
public Link getSelfLink() {
return readLink;
}
@@ -130,26 +115,21 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
}
@Override
- public Element getContent() {
- return content;
+ public List<Property> getProperties() {
+ return properties;
}
@Override
- public void setContent(final Element content) {
- this.content = content;
- }
+ public Property getProperty(final String name) {
+ Property result = null;
- /**
- * {@inheritDoc }
- */
- @Override
- public Element getMediaEntryProperties() {
- return mediaEntryProperties;
- }
+ for (Property property : properties) {
+ if (name.equals(property.getName())) {
+ result = property;
+ }
+ }
- @Override
- public void setMediaEntryProperties(final Element mediaEntryProperties) {
- this.mediaEntryProperties = mediaEntryProperties;
+ return result;
}
@Override
@@ -174,6 +154,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
@Override
public boolean isMediaEntry() {
- return getMediaEntryProperties() != null || StringUtils.isNotBlank(this.mediaContentSource);
+ return StringUtils.isNotBlank(this.mediaContentSource);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
new file mode 100644
index 0000000..d353c07
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.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.client.api.Constants;
+import org.apache.olingo.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.ComplexValue;
+import org.apache.olingo.client.api.data.Value;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+import org.apache.olingo.client.api.domain.ODataPropertyType;
+
+abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
+
+ private final JSONGeoValueDeserializer geoDeserializer = new JSONGeoValueDeserializer();
+
+ protected ODataJClientEdmPrimitiveType getPrimitiveType(final JsonNode node) {
+ ODataJClientEdmPrimitiveType result = ODataJClientEdmPrimitiveType.String;
+
+ if (node.isIntegralNumber()) {
+ result = ODataJClientEdmPrimitiveType.Int32;
+ } else if (node.isBoolean()) {
+ result = ODataJClientEdmPrimitiveType.Boolean;
+ } else if (node.isFloatingPointNumber()) {
+ result = ODataJClientEdmPrimitiveType.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 ODataJClientEdmType typeInfo) {
+ Value value = null;
+
+ if (node.isNull()) {
+ value = new NullValueImpl();
+ } else {
+ if (typeInfo != null && typeInfo.isGeospatialType()) {
+ final ODataJClientEdmPrimitiveType geoType = ODataJClientEdmPrimitiveType.fromValue(typeInfo.getBaseType());
+
+ value = new GeospatialValueImpl(this.geoDeserializer.deserialize(node, geoType));
+ } 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 ODataJClientEdmType typeInfo) {
+ final CollectionValueImpl value = new CollectionValueImpl();
+
+ final ODataJClientEdmType type = typeInfo == null
+ ? null
+ : new ODataJClientEdmType(typeInfo.getBaseType());
+
+ 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 ODataJClientEdmType typeInfo = StringUtils.isBlank(property.getType())
+ ? null
+ : new ODataJClientEdmType(property.getType());
+
+ 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).toString());
+ }
+ property.setValue(fromPrimitive(node, typeInfo));
+ break;
+
+ case EMPTY:
+ default:
+ property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java
new file mode 100644
index 0000000..3398ed9
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/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.client.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.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.Property;
+import org.apache.olingo.client.api.data.Value;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+
+abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
+
+ private static final ODataJClientEdmPrimitiveType[] NUMBER_TYPES = {
+ ODataJClientEdmPrimitiveType.Byte, ODataJClientEdmPrimitiveType.SByte,
+ ODataJClientEdmPrimitiveType.Single, ODataJClientEdmPrimitiveType.Double,
+ ODataJClientEdmPrimitiveType.Int16, ODataJClientEdmPrimitiveType.Int32, ODataJClientEdmPrimitiveType.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 ODataJClientEdmType typeInfo = type == null
+ ? null
+ : new ODataJClientEdmType(type);
+
+ if (value.isNull()) {
+ jgen.writeNull();
+ } else if (value.isSimple()) {
+ final boolean isNumber = typeInfo == null
+ ? NumberUtils.isNumber(value.asSimple().get())
+ : ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveType());
+ final boolean isBoolean = typeInfo == null
+ ? (value.asSimple().get().equalsIgnoreCase(Boolean.TRUE.toString())
+ || value.asSimple().get().equalsIgnoreCase(Boolean.FALSE.toString()))
+ : typeInfo.getPrimitiveType() == ODataJClientEdmPrimitiveType.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.getBaseType(), 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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java
new file mode 100644
index 0000000..3e92ac4
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/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.client.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.client.api.data.Property;
+import org.apache.olingo.client.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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java
new file mode 100644
index 0000000..9f2d19a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/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.client.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.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.ComplexValue;
+import org.apache.olingo.client.api.data.GeospatialValue;
+import org.apache.olingo.client.api.data.NullValue;
+import org.apache.olingo.client.api.data.PrimitiveValue;
+import org.apache.olingo.client.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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
index 0b5e974..d80bcf3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
@@ -18,201 +18,322 @@
*/
package org.apache.olingo.client.core.data;
-import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import java.io.InputStream;
import java.net.URI;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataClient;
+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.http.entity.ContentType;
import org.apache.olingo.client.api.Constants;
import org.apache.olingo.client.api.domain.ODataOperation;
-import org.apache.olingo.client.api.utils.XMLUtils;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-public class AtomDeserializer {
+public class AtomDeserializer extends AbstractAtomDealer {
private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
- private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
+ private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
- private final ODataClient client;
+ private final AtomPropertyDeserializer propDeserializer;
- public AtomDeserializer(final ODataClient client) {
- this.client = client;
+ public AtomDeserializer(final ODataServiceVersion version) {
+ super(version);
+ this.propDeserializer = new AtomPropertyDeserializer(version);
}
- private void common(final Element input, final AtomObject object) {
- if (StringUtils.isNotBlank(input.getAttribute(Constants.ATTR_XMLBASE))) {
- object.setBaseURI(input.getAttribute(Constants.ATTR_XMLBASE));
- }
+ private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+ }
- final List<Element> ids = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ID);
- if (!ids.isEmpty()) {
- object.setId(ids.get(0).getTextContent());
+ 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");
}
- final List<Element> titles = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_TITLE);
- if (!titles.isEmpty()) {
- object.setTitle(titles.get(0).getTextContent());
+ 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;
+ }
}
+ }
- final List<Element> summaries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_SUMMARY);
- if (!summaries.isEmpty()) {
- object.setSummary(summaries.get(0).getTextContent());
+ 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 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();
- final List<Element> updateds = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_UPDATED);
- if (!updateds.isEmpty()) {
- try {
- object.setUpdated(ISO_DATEFORMAT.parse(updateds.get(0).getTextContent()));
- } catch (Exception e) {
- LOG.error("Could not parse date {}", updateds.get(0).getTextContent(), e);
+ if (event.isStartElement()) {
+ entry.getProperties().add(propDeserializer.deserialize(reader, event.asStartElement()));
+ }
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndProperties = true;
}
}
}
- public AtomEntryImpl entry(final Element input) {
- if (!Constants.ATOM_ELEM_ENTRY.equals(input.getNodeName())) {
+ 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();
-
- common(input, entry);
-
- final String etag = input.getAttribute(Constants.ATOM_ATTR_ETAG);
- if (StringUtils.isNotBlank(etag)) {
- entry.setETag(etag);
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ entry.setBaseURI(xmlBase.getValue());
}
-
- final List<Element> categories = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CATEGORY);
- if (!categories.isEmpty()) {
- entry.setType(categories.get(0).getAttribute(Constants.ATOM_ATTR_TERM));
+ final Attribute etag = start.getAttributeByName(etagQName);
+ if (etag != null) {
+ entry.setETag(etag.getValue());
}
- final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
- for (Element linkElem : links) {
- final LinkImpl link = new LinkImpl();
- link.setRel(linkElem.getAttribute(Constants.ATTR_REL));
- link.setTitle(linkElem.getAttribute(Constants.ATTR_TITLE));
- link.setHref(linkElem.getAttribute(Constants.ATTR_HREF));
-
- 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(
- client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
-
- link.setType(linkElem.getAttribute(Constants.ATTR_TYPE));
- entry.getNavigationLinks().add(link);
-
- final List<Element> inlines = XMLUtils.getChildElements(linkElem, Constants.ATOM_ELEM_INLINE);
- if (!inlines.isEmpty()) {
- final List<Element> entries =
- XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_ENTRY);
- if (!entries.isEmpty()) {
- link.setInlineEntry(entry(entries.get(0)));
+ 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());
}
-
- final List<Element> feeds =
- XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_FEED);
- if (!feeds.isEmpty()) {
- link.setInlineFeed(feed(feeds.get(0)));
+ } 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());
}
- }
- } else if (link.getRel().startsWith(
- client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
-
- entry.getAssociationLinks().add(link);
- } else if (link.getRel().startsWith(
- client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
- entry.getMediaEditLinks().add(link);
- }
- }
+ 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()));
+ }
- final List<Element> authors = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_AUTHOR);
- if (!authors.isEmpty()) {
- final AtomEntryImpl.Author author = new AtomEntryImpl.Author();
- for (Node child : XMLUtils.getChildNodes(input, Node.ELEMENT_NODE)) {
- if (Constants.ATOM_ELEM_AUTHOR_NAME.equals(XMLUtils.getSimpleName(child))) {
- author.setName(child.getTextContent());
- } else if (Constants.ATOM_ELEM_AUTHOR_URI.equals(XMLUtils.getSimpleName(child))) {
- author.setUri(child.getTextContent());
- } else if (Constants.ATOM_ELEM_AUTHOR_EMAIL.equals(XMLUtils.getSimpleName(child))) {
- author.setEmail(child.getTextContent());
+ 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.getMimeType().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 (!author.isEmpty()) {
- entry.setAuthor(author);
+
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndEntry = true;
}
}
- final List<Element> actions = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ACTION);
- for (Element action : actions) {
- final ODataOperation operation = new ODataOperation();
- operation.setMetadataAnchor(action.getAttribute(Constants.ATTR_METADATA));
- operation.setTitle(action.getAttribute(Constants.ATTR_TITLE));
- operation.setTarget(URI.create(action.getAttribute(Constants.ATTR_TARGET)));
+ return entry;
+ }
- entry.getOperations().add(operation);
- }
+ private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+ final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+ return entry(reader, skipBeforeFirstStartElement(reader));
+ }
- final List<Element> contents = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CONTENT);
- if (!contents.isEmpty()) {
- final Element content = contents.get(0);
+ private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
+ throws XMLStreamException {
- List<Element> props = XMLUtils.getChildElements(content, Constants.ELEM_PROPERTIES);
- if (props.isEmpty()) {
- entry.setMediaContentSource(content.getAttribute(Constants.ATOM_ATTR_SRC));
- entry.setMediaContentType(content.getAttribute(Constants.ATTR_TYPE));
+ boolean foundEndElement = false;
+ while (reader.hasNext() && !foundEndElement) {
+ final XMLEvent event = reader.nextEvent();
- props = XMLUtils.getChildElements(input, Constants.ELEM_PROPERTIES);
- if (!props.isEmpty()) {
- entry.setMediaEntryProperties(props.get(0));
- }
- } else {
- entry.setContent(props.get(0));
+ if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+ feed.setCount(Integer.valueOf(event.asCharacters().getData()));
}
- }
- return entry;
+ if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+ foundEndElement = true;
+ }
+ }
}
- public AtomFeedImpl feed(final Element input) {
- if (!Constants.ATOM_ELEM_FEED.equals(input.getNodeName())) {
+ 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();
-
- common(input, feed);
-
- final List<Element> entries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ENTRY);
- for (Element entry : entries) {
- feed.getEntries().add(entry(entry));
+ final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+ if (xmlBase != null) {
+ feed.setBaseURI(xmlBase.getValue());
}
- final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
- for (Element link : links) {
- if (Constants.NEXT_LINK_REL.equals(link.getAttribute(Constants.ATTR_REL))) {
- feed.setNext(URI.create(link.getAttribute(Constants.ATTR_HREF)));
+ 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()));
+ }
}
- }
- final List<Element> counts = XMLUtils.getChildElements(input, Constants.ATOM_ATTR_COUNT);
- if (!counts.isEmpty()) {
- try {
- feed.setCount(Integer.parseInt(counts.get(0).getTextContent()));
- } catch (Exception e) {
- LOG.error("Could not parse $inlinecount {}", counts.get(0).getTextContent(), e);
+ 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);
+ }
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
index 704da5e..aa7c0c1 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
@@ -18,102 +18,8 @@
*/
package org.apache.olingo.client.core.data;
-import java.net.URI;
-import java.util.Date;
-import org.apache.commons.lang3.StringUtils;
-
-public class AtomEntryImpl extends AbstractEntry implements AtomObject {
+public class AtomEntryImpl extends AbstractEntry {
private static final long serialVersionUID = 6973729343868293279L;
- public static class Author {
-
- private String name;
-
- private String uri;
-
- private String email;
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public String getUri() {
- return uri;
- }
-
- public void setUri(final String uri) {
- this.uri = uri;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(final String email) {
- this.email = email;
- }
-
- public boolean isEmpty() {
- return StringUtils.isBlank(name) && StringUtils.isBlank(uri) && StringUtils.isBlank(email);
- }
- }
- private URI baseURI;
-
- private String title;
-
- private String summary;
-
- private Date updated;
-
- private Author author;
-
- @Override
- public void setBaseURI(final String baseURI) {
- this.baseURI = URI.create(baseURI);
- }
-
- @Override
- public URI getBaseURI() {
- return baseURI;
- }
-
- public String getTitle() {
- return title;
- }
-
- @Override
- public void setTitle(final String title) {
- this.title = title;
- }
-
- public String getSummary() {
- return summary;
- }
-
- @Override
- public void setSummary(final String summary) {
- this.summary = summary;
- }
-
- public Date getUpdated() {
- return updated == null ? null : new Date(updated.getTime());
- }
-
- @Override
- public void setUpdated(final Date updated) {
- this.updated = new Date(updated.getTime());
- }
-
- public Author getAuthor() {
- return author;
- }
-
- public void setAuthor(final Author author) {
- this.author = author;
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
index 08a85db..94f2540 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
@@ -20,7 +20,6 @@ package org.apache.olingo.client.core.data;
import java.net.URI;
import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
import org.apache.olingo.client.api.data.Entry;
import org.apache.olingo.client.api.data.Feed;
@@ -30,20 +29,10 @@ import org.apache.olingo.client.api.data.Feed;
*
* @see AtomEntry
*/
-public class AtomFeedImpl extends AbstractPayloadObject implements AtomObject, Feed {
+public class AtomFeedImpl extends AbstractAtomObject implements Feed {
private static final long serialVersionUID = 5466590540021319153L;
- private URI baseURI;
-
- private String id;
-
- private String title;
-
- private String summary;
-
- private Date updated;
-
private Integer count;
private final List<Entry> entries = new ArrayList<Entry>();
@@ -51,51 +40,6 @@ public class AtomFeedImpl extends AbstractPayloadObject implements AtomObject, F
private URI next;
@Override
- public URI getBaseURI() {
- return baseURI;
- }
-
- @Override
- public void setBaseURI(final String baseURI) {
- this.baseURI = URI.create(baseURI);
- }
-
- public String getId() {
- return id;
- }
-
- @Override
- public void setId(final String id) {
- this.id = id;
- }
-
- public String getTitle() {
- return title;
- }
-
- @Override
- public void setTitle(final String title) {
- this.title = title;
- }
-
- public String getSummary() {
- return summary;
- }
-
- @Override
- public void setSummary(final String summary) {
- this.summary = summary;
- }
-
- public Date getUpdated() {
- return new Date(updated.getTime());
- }
-
- @Override
- public void setUpdated(final Date updated) {
- this.updated = new Date(updated.getTime());
- }
-
public void setCount(final Integer count) {
this.count = count;
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
new file mode 100644
index 0000000..e733d2a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.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.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class AtomGeoValueDeserializer {
+
+ private List<Point> points(final XMLEventReader reader, final StartElement start,
+ final ODataJClientEdmPrimitiveType 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);
+ point.setX(Double.valueOf(pointInfo[0]));
+ point.setY(Double.valueOf(pointInfo[1]));
+ 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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 ODataJClientEdmPrimitiveType 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/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
new file mode 100644
index 0000000..409ff99
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.client.core.data;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Collections;
+import java.util.Iterator;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class AtomGeoValueSerializer {
+
+ public static final ThreadLocal<DecimalFormat> DOUBLE_FORMAT = new ThreadLocal<DecimalFormat>() {
+ @Override
+ protected DecimalFormat initialValue() {
+ DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
+ otherSymbols.setDecimalSeparator('.');
+ return new DecimalFormat("#.#########################", otherSymbols);
+ }
+ };
+
+ 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);
+ writer.writeCharacters(DOUBLE_FORMAT.get().format(point.getX()) + " " + DOUBLE_FORMAT.get().format(point.getY()));
+ 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.getEdmSimpleType()) {
+ 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:
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
deleted file mode 100644
index b0ecab9..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.client.core.data;
-
-import java.util.Date;
-
-/**
- * Common methods for <tt>AtomEntryImpl</tt> and <tt>AtomFeedImpl</tt>.
- *
- * @see AtomEntryImpl
- * @see AtomFeedImpl
- */
-public interface AtomObject {
-
- void setBaseURI(String baseURI);
-
- void setId(String id);
-
- void setTitle(String title);
-
- void setSummary(String summary);
-
- void setUpdated(Date updated);
-
-}