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/07 10:09:02 UTC

[13/57] [abbrv] [OLINGO-169] Introducing V3 and V4 metadata parsing tests - still using dummy Edm interfaces

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/EnumTypeDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/EnumTypeDeserializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/EnumTypeDeserializer.java
new file mode 100644
index 0000000..8e09eac
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/EnumTypeDeserializer.java
@@ -0,0 +1,71 @@
+/*
+ * 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.odata4.client.core.op.impl;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import java.io.IOException;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.olingo.odata4.client.core.edm.AbstractEnumType;
+import org.apache.olingo.odata4.client.core.edm.v4.AnnotationImpl;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+
+public class EnumTypeDeserializer extends AbstractEdmDeserializer<AbstractEnumType> {
+
+  @Override
+  protected AbstractEnumType doDeserialize(final JsonParser jp, final DeserializationContext ctxt)
+          throws IOException, JsonProcessingException {
+
+    final AbstractEnumType enumType = ODataServiceVersion.V30 == client.getServiceVersion()
+            ? new org.apache.olingo.odata4.client.core.edm.v3.EnumTypeImpl()
+            : new org.apache.olingo.odata4.client.core.edm.v4.EnumTypeImpl();
+
+    for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
+      final JsonToken token = jp.getCurrentToken();
+      if (token == JsonToken.FIELD_NAME) {
+        if ("Name".equals(jp.getCurrentName())) {
+          enumType.setName(jp.nextTextValue());
+        } else if ("UnderlyingType".equals(jp.getCurrentName())) {
+          enumType.setUnderlyingType(jp.nextTextValue());
+        } else if ("IsFlags".equals(jp.getCurrentName())) {
+          enumType.setFlags(BooleanUtils.toBoolean(jp.nextTextValue()));
+        } else if ("Member".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          if (enumType instanceof org.apache.olingo.odata4.client.core.edm.v3.EnumTypeImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.EnumTypeImpl) enumType).
+                    getMembers().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.MemberImpl.class));
+          } else {
+            ((org.apache.olingo.odata4.client.core.edm.v4.EnumTypeImpl) enumType).
+                    getMembers().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v4.MemberImpl.class));
+          }
+        } else if ("Annotation".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v4.EnumTypeImpl) enumType).
+                  setAnnotation(jp.readValueAs( AnnotationImpl.class));
+        }
+      }
+    }
+
+    return enumType;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/InjectableSerializerProvider.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/InjectableSerializerProvider.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/InjectableSerializerProvider.java
new file mode 100644
index 0000000..fc37c83
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/InjectableSerializerProvider.java
@@ -0,0 +1,43 @@
+/*
+ * 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.odata4.client.core.op.impl;
+
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
+import com.fasterxml.jackson.databind.ser.SerializerFactory;
+
+class InjectableSerializerProvider extends DefaultSerializerProvider {
+
+  private static final long serialVersionUID = 3432260063063739646L;
+
+  public InjectableSerializerProvider(
+          final SerializerProvider src, final SerializationConfig config, final SerializerFactory factory) {
+
+    super(src, config, factory);
+  }
+
+  @Override
+  public InjectableSerializerProvider createInstance(
+          final SerializationConfig config, final SerializerFactory factory) {
+
+    return this;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/SchemaDeserializer.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/SchemaDeserializer.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/SchemaDeserializer.java
new file mode 100644
index 0000000..6c07a3b
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/op/impl/SchemaDeserializer.java
@@ -0,0 +1,147 @@
+/*
+ * 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.odata4.client.core.op.impl;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import java.io.IOException;
+import org.apache.olingo.odata4.client.core.edm.AbstractSchema;
+import org.apache.olingo.odata4.client.core.edm.v3.AssociationImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.UsingImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.ValueTermImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.ActionImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.AnnotationImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.FunctionImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.TypeDefinitionImpl;
+import org.apache.olingo.odata4.commons.api.edm.constants.ODataServiceVersion;
+
+@SuppressWarnings("rawtypes")
+public class SchemaDeserializer extends AbstractEdmDeserializer<AbstractSchema> {
+
+  @Override
+  protected AbstractSchema doDeserialize(final JsonParser jp, final DeserializationContext ctxt)
+          throws IOException, JsonProcessingException {
+
+    final AbstractSchema schema = ODataServiceVersion.V30 == client.getServiceVersion()
+            ? new org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl()
+            : new org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl();
+
+    for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
+      final JsonToken token = jp.getCurrentToken();
+      if (token == JsonToken.FIELD_NAME) {
+        if ("Namespace".equals(jp.getCurrentName())) {
+          schema.setNamespace(jp.nextTextValue());
+        } else if ("Alias".equals(jp.getCurrentName())) {
+          schema.setAlias(jp.nextTextValue());
+        } else if ("Using".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                  getUsings().add(jp.readValueAs( UsingImpl.class));
+        } else if ("Association".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                  getAssociations().add(jp.readValueAs( AssociationImpl.class));
+        } else if ("ComplexType".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          if (schema instanceof org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                    getComplexTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.ComplexTypeImpl.class));
+          } else {
+            ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).
+                    getComplexTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v4.ComplexTypeImpl.class));
+          }
+        } else if ("EntityType".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          if (schema instanceof org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                    getEntityTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.EntityTypeImpl.class));
+          } else {
+            ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).
+                    getEntityTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v4.EntityTypeImpl.class));
+          }
+        } else if ("EnumType".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          if (schema instanceof org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                    getEnumTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.EnumTypeImpl.class));
+          } else {
+            ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).
+                    getEnumTypes().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v4.EnumTypeImpl.class));
+          }
+        } else if ("ValueTerm".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                  getValueTerms().add(jp.readValueAs( ValueTermImpl.class));
+        } else if ("EntityContainer".equals(jp.getCurrentName())) {
+          jp.nextToken();
+
+          if (schema instanceof org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).
+                    getEntityContainers().add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.EntityContainerImpl.class));
+          } else {
+            org.apache.olingo.odata4.client.core.edm.v4.EntityContainerImpl entityContainer
+                    = jp.readValueAs(
+                            org.apache.olingo.odata4.client.core.edm.v4.EntityContainerImpl.class);
+            entityContainer.setDefaultEntityContainer(true);
+            ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).
+                    setEntityContainer(entityContainer);
+          }
+        } else if ("Annotations".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          if (schema instanceof org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) {
+            ((org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl) schema).getAnnotationsList().
+                    add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v3.AnnotationsImpl.class));
+          } else {
+            ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).getAnnotationsList().
+                    add(jp.readValueAs(
+                                    org.apache.olingo.odata4.client.core.edm.v4.AnnotationsImpl.class));
+          }
+        } else if ("Action".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).getActions().
+                  add(jp.readValueAs( ActionImpl.class));
+        } else if ("Annotation".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).getAnnotations().
+                  add(jp.readValueAs( AnnotationImpl.class));
+        } else if ("Function".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).getFunctions().
+                  add(jp.readValueAs( FunctionImpl.class));
+        } else if ("TypeDefinition".equals(jp.getCurrentName())) {
+          jp.nextToken();
+          ((org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl) schema).
+                  getTypeDefinitions().add(jp.readValueAs( TypeDefinitionImpl.class));
+        }
+      }
+    }
+
+    return schema;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AbstractDOMParser.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AbstractDOMParser.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AbstractDOMParser.java
deleted file mode 100644
index 49f3285..0000000
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AbstractDOMParser.java
+++ /dev/null
@@ -1,46 +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.odata4.client.core.utils;
-
-import java.io.InputStream;
-import java.io.Writer;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * DOM Parser.
- */
-public abstract class AbstractDOMParser {
-
-  /**
-   * Parses the given input into a DOM tree.
-   *
-   * @param input stream to be parsed and de-serialized.
-   * @return DOM tree
-   */
-  public abstract Element deserialize(InputStream input);
-
-  /**
-   * Writes DOM object by the given writer.
-   *
-   * @param content DOM to be streamed.
-   * @param writer writer.
-   */
-  public abstract void serialize(Node content, Writer writer);
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AndroidDOMParserImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AndroidDOMParserImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AndroidDOMParserImpl.java
deleted file mode 100644
index bbf5bd8..0000000
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/AndroidDOMParserImpl.java
+++ /dev/null
@@ -1,49 +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.odata4.client.core.utils;
-
-import java.io.InputStream;
-import java.io.Writer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-public class AndroidDOMParserImpl extends AbstractDOMParser {
-
-  @Override
-  public Element deserialize(final InputStream input) {
-    try {
-      return XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder().parse(input).getDocumentElement();
-    } catch (Exception e) {
-      throw new IllegalArgumentException("Could not parse DOM", e);
-    }
-  }
-
-  @Override
-  public void serialize(final Node content, final Writer writer) {
-    try {
-      TransformerFactory.newInstance().newTransformer().
-              transform(new DOMSource(content), new StreamResult(writer));
-    } catch (Exception e) {
-      throw new IllegalArgumentException("While serializing DOM element", e);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/DefaultDOMParserImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/DefaultDOMParserImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/DefaultDOMParserImpl.java
deleted file mode 100644
index d8215f7..0000000
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/DefaultDOMParserImpl.java
+++ /dev/null
@@ -1,78 +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.odata4.client.core.utils;
-
-import java.io.InputStream;
-import java.io.Writer;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSOutput;
-import org.w3c.dom.ls.LSParser;
-import org.w3c.dom.ls.LSSerializer;
-
-public class DefaultDOMParserImpl extends AbstractDOMParser {
-
-  private static final Object MONITOR = new Object();
-
-  private static DOMImplementationLS DOM_IMPL;
-
-  private void lazyInit() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
-    synchronized (MONITOR) {
-      if (DOM_IMPL == null) {
-        final DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
-        DOM_IMPL = (DOMImplementationLS) reg.getDOMImplementation("LS");
-      }
-    }
-  }
-
-  @Override
-  public Element deserialize(final InputStream input) {
-    try {
-      lazyInit();
-
-      final LSParser parser = DOM_IMPL.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
-
-      final LSInput lsinput = DOM_IMPL.createLSInput();
-      lsinput.setByteStream(input);
-
-      return parser.parse(lsinput).getDocumentElement();
-    } catch (Exception e) {
-      throw new IllegalArgumentException("Could not parse DOM", e);
-    }
-  }
-
-  @Override
-  public void serialize(final Node content, final Writer writer) {
-    try {
-      lazyInit();
-
-      final LSSerializer serializer = DOM_IMPL.createLSSerializer();
-
-      final LSOutput lso = DOM_IMPL.createLSOutput();
-      lso.setCharacterStream(writer);
-
-      serializer.write(content, lso);
-    } catch (Exception e) {
-      throw new IllegalArgumentException("While serializing DOM element", e);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/XMLUtils.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/XMLUtils.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/XMLUtils.java
deleted file mode 100644
index 90f5743..0000000
--- a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/utils/XMLUtils.java
+++ /dev/null
@@ -1,186 +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.odata4.client.core.utils;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ServiceLoader;
-import javax.xml.parsers.DocumentBuilderFactory;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.odata4.client.api.Constants;
-import org.apache.olingo.odata4.client.core.data.EdmSimpleType;
-import org.apache.olingo.odata4.client.core.data.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();
-
-  public static final AbstractDOMParser PARSER;
-
-  static {
-    final Iterator<AbstractDOMParser> itor
-            = ServiceLoader.load(AbstractDOMParser.class, Thread.currentThread().getContextClassLoader()).iterator();
-    PARSER = itor.hasNext() ? itor.next() : new DefaultDOMParserImpl();
-  }
-
-  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 EdmSimpleType simpleTypeForNode(final Geospatial.Dimension dimension, final Node node) {
-    EdmSimpleType type = null;
-
-    if (Constants.ELEM_POINT.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyPoint
-              : EdmSimpleType.GeometryPoint;
-    } else if (Constants.ELEM_MULTIPOINT.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyMultiPoint
-              : EdmSimpleType.GeometryMultiPoint;
-    } else if (Constants.ELEM_LINESTRING.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyLineString
-              : EdmSimpleType.GeometryLineString;
-    } else if (Constants.ELEM_MULTILINESTRING.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyMultiLineString
-              : EdmSimpleType.GeometryMultiLineString;
-    } else if (Constants.ELEM_POLYGON.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyPolygon
-              : EdmSimpleType.GeometryPolygon;
-    } else if (Constants.ELEM_MULTIPOLYGON.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyMultiPolygon
-              : EdmSimpleType.GeometryMultiPolygon;
-    } else if (Constants.ELEM_GEOCOLLECTION.equals(node.getNodeName())
-            || Constants.ELEM_GEOMEMBERS.equals(node.getNodeName())) {
-
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? EdmSimpleType.GeographyCollection
-              : EdmSimpleType.GeometryCollection;
-    }
-
-    return type;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AbstractDOMParser.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AbstractDOMParser.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AbstractDOMParser.java
new file mode 100644
index 0000000..7237895
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AbstractDOMParser.java
@@ -0,0 +1,46 @@
+/*
+ * 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.odata4.client.core.xml;
+
+import java.io.InputStream;
+import java.io.Writer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * DOM Parser.
+ */
+public abstract class AbstractDOMParser {
+
+  /**
+   * Parses the given input into a DOM tree.
+   *
+   * @param input stream to be parsed and de-serialized.
+   * @return DOM tree
+   */
+  public abstract Element deserialize(InputStream input);
+
+  /**
+   * Writes DOM object by the given writer.
+   *
+   * @param content DOM to be streamed.
+   * @param writer writer.
+   */
+  public abstract void serialize(Node content, Writer writer);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AndroidDOMParserImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AndroidDOMParserImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AndroidDOMParserImpl.java
new file mode 100644
index 0000000..0d49c8e
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/AndroidDOMParserImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.odata4.client.core.xml;
+
+import org.apache.olingo.odata4.client.api.utils.XMLUtils;
+import java.io.InputStream;
+import java.io.Writer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class AndroidDOMParserImpl extends AbstractDOMParser {
+
+  @Override
+  public Element deserialize(final InputStream input) {
+    try {
+      return XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder().parse(input).getDocumentElement();
+    } catch (Exception e) {
+      throw new IllegalArgumentException("Could not parse DOM", e);
+    }
+  }
+
+  @Override
+  public void serialize(final Node content, final Writer writer) {
+    try {
+      TransformerFactory.newInstance().newTransformer().
+              transform(new DOMSource(content), new StreamResult(writer));
+    } catch (Exception e) {
+      throw new IllegalArgumentException("While serializing DOM element", e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/DefaultDOMParserImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/DefaultDOMParserImpl.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/DefaultDOMParserImpl.java
new file mode 100644
index 0000000..deaefc1
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/DefaultDOMParserImpl.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.odata4.client.core.xml;
+
+import java.io.InputStream;
+import java.io.Writer;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSParser;
+import org.w3c.dom.ls.LSSerializer;
+
+public class DefaultDOMParserImpl extends AbstractDOMParser {
+
+  private static final Object MONITOR = new Object();
+
+  private static DOMImplementationLS DOM_IMPL;
+
+  private void lazyInit() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+    synchronized (MONITOR) {
+      if (DOM_IMPL == null) {
+        final DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
+        DOM_IMPL = (DOMImplementationLS) reg.getDOMImplementation("LS");
+      }
+    }
+  }
+
+  @Override
+  public Element deserialize(final InputStream input) {
+    try {
+      lazyInit();
+
+      final LSParser parser = DOM_IMPL.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
+
+      final LSInput lsinput = DOM_IMPL.createLSInput();
+      lsinput.setByteStream(input);
+
+      return parser.parse(lsinput).getDocumentElement();
+    } catch (Exception e) {
+      throw new IllegalArgumentException("Could not parse DOM", e);
+    }
+  }
+
+  @Override
+  public void serialize(final Node content, final Writer writer) {
+    try {
+      lazyInit();
+
+      final LSSerializer serializer = DOM_IMPL.createLSSerializer();
+
+      final LSOutput lso = DOM_IMPL.createLSOutput();
+      lso.setCharacterStream(writer);
+
+      serializer.write(content, lso);
+    } catch (Exception e) {
+      throw new IllegalArgumentException("While serializing DOM element", e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/XMLParser.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/XMLParser.java b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/XMLParser.java
new file mode 100644
index 0000000..d0f0b76
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/main/java/org/apache/olingo/odata4/client/core/xml/XMLParser.java
@@ -0,0 +1,37 @@
+/*
+ * 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.odata4.client.core.xml;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+public final class XMLParser {
+
+  public static final AbstractDOMParser PARSER;
+
+  static {
+    final Iterator<AbstractDOMParser> itor
+            = ServiceLoader.load(AbstractDOMParser.class, Thread.currentThread().getContextClassLoader()).iterator();
+    PARSER = itor.hasNext() ? itor.next() : new DefaultDOMParserImpl();
+  }
+
+  private XMLParser() {
+    // Empty private constructor for static utility classes       
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/AbstractTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/AbstractTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/AbstractTest.java
new file mode 100644
index 0000000..1cbb288
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/AbstractTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.odata4.client.core;
+
+import java.util.Locale;
+import org.apache.olingo.odata4.client.api.ODataClient;
+import org.apache.olingo.odata4.client.api.format.ODataFormat;
+import org.apache.olingo.odata4.client.api.format.ODataPubFormat;
+import org.junit.BeforeClass;
+
+public abstract class AbstractTest {
+
+  protected static ODataV3Client v3Client;
+
+  protected static ODataV4Client v4Client;
+
+  protected abstract ODataClient getClient();
+
+  /**
+   * This is needed for correct number handling (Double, for example).
+   */
+  @BeforeClass
+  public static void setEnglishLocale() {
+    Locale.setDefault(Locale.ENGLISH);
+  }
+
+  @BeforeClass
+  public static void setClientInstances() {
+    v3Client = ODataClientFactory.getV3();
+    v4Client = ODataClientFactory.getV4();
+  }
+
+  protected String getSuffix(final ODataPubFormat format) {
+    return format == ODataPubFormat.ATOM ? "xml" : "json";
+  }
+
+  protected String getSuffix(final ODataFormat format) {
+    return format == ODataFormat.XML ? "xml" : "json";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
new file mode 100644
index 0000000..02cecd9
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v3/MetadataTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.odata4.client.core.v3;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.edm.EdmType;
+import org.apache.olingo.odata4.client.api.http.HttpMethod;
+import org.apache.olingo.odata4.client.core.AbstractTest;
+import org.apache.olingo.odata4.client.core.ODataV3Client;
+import org.apache.olingo.odata4.client.core.edm.v3.ComplexTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.EdmMetadataImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.EdmTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.EntityContainerImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.EntityTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.FunctionImportImpl;
+import org.apache.olingo.odata4.client.core.edm.v3.SchemaImpl;
+import org.junit.Test;
+
+public class MetadataTest extends AbstractTest {
+
+  @Override
+  protected ODataV3Client getClient() {
+    return v3Client;
+  }
+
+  @Test
+  public void parse() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    assertNotNull(metadata);
+
+    final EdmTypeImpl orderCollection
+            = new EdmTypeImpl(metadata, "Collection(Microsoft.Test.OData.Services.AstoriaDefaultService.Order)");
+    assertNotNull(orderCollection);
+    assertTrue(orderCollection.isCollection());
+    assertFalse(orderCollection.isSimpleType());
+    assertFalse(orderCollection.isEnumType());
+    assertFalse(orderCollection.isComplexType());
+    assertTrue(orderCollection.isEntityType());
+
+    final EntityTypeImpl order = orderCollection.getEntityType();
+    assertNotNull(order);
+    assertEquals("Order", order.getName());
+
+    final EdmType stream = new EdmTypeImpl(metadata, "Edm.Stream");
+    assertNotNull(stream);
+    assertFalse(stream.isCollection());
+    assertTrue(stream.isSimpleType());
+    assertFalse(stream.isEnumType());
+    assertFalse(stream.isComplexType());
+    assertFalse(stream.isEntityType());
+
+    final List<FunctionImportImpl> functionImports
+            = metadata.getSchemas().get(0).getDefaultEntityContainer().getFunctionImports();
+    int legacyGetters = 0;
+    int legacyPosters = 0;
+    int actions = 0;
+    int functions = 0;
+    for (FunctionImportImpl functionImport : functionImports) {
+      if (HttpMethod.GET.name().equals(functionImport.getHttpMethod())) {
+        legacyGetters++;
+      } else if (HttpMethod.POST.name().equals(functionImport.getHttpMethod())) {
+        legacyPosters++;
+      } else if (functionImport.getHttpMethod() == null) {
+        if (functionImport.isSideEffecting()) {
+          actions++;
+        } else {
+          functions++;
+        }
+      }
+    }
+    assertEquals(6, legacyGetters);
+    assertEquals(1, legacyPosters);
+    assertEquals(5, actions);
+    assertEquals(0, functions);
+  }
+
+  @Test
+  public void multipleSchemas() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("northwind-metadata.xml"));
+    assertNotNull(metadata);
+
+    final SchemaImpl first = metadata.getSchema("NorthwindModel");
+    assertNotNull(first);
+
+    final SchemaImpl second = metadata.getSchema("ODataWebV3.Northwind.Model");
+    assertNotNull(second);
+
+    final EntityContainerImpl entityContainer = second.getDefaultEntityContainer();
+    assertNotNull(entityContainer);
+    assertEquals("NorthwindEntities", entityContainer.getName());
+  }
+
+  @Test
+  public void entityType() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    assertNotNull(metadata);
+
+    final EntityContainerImpl container = metadata.getSchema(0).getEntityContainers().get(0);
+    assertNotNull(container);
+    final EntityTypeImpl type = metadata.getSchema(0).getEntityType("ProductReview");
+    assertNotNull(type);
+
+    assertFalse(type.getProperties().isEmpty());
+    assertNotNull(type.getProperties().get(0));
+
+    assertFalse(type.getKey().getPropertyRefs().isEmpty());
+    assertNotNull(type.getKey().getPropertyRefs().get(0));
+  }
+
+  @Test
+  public void complexType() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    assertNotNull(metadata);
+
+    final EntityContainerImpl container = metadata.getSchema(0).getEntityContainers().get(0);
+    assertNotNull(container);
+    final ComplexTypeImpl type = metadata.getSchema(0).getComplexType("ContactDetails");
+    assertNotNull(type);
+
+    assertFalse(type.getProperties().isEmpty());
+    assertNotNull(type.getProperties().get(0));
+  }
+
+  @Test
+  public void functionImport() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    assertNotNull(metadata);
+
+    final EntityContainerImpl container = metadata.getSchema(0).getEntityContainers().get(0);
+    assertNotNull(container);
+    final FunctionImportImpl funcImp = container.getFunctionImport("GetArgumentPlusOne");
+    assertNotNull(funcImp);
+
+    assertNotNull(funcImp.getParameters().get(0));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/e7135610/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/MetadataTest.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/MetadataTest.java b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/MetadataTest.java
new file mode 100644
index 0000000..e119861
--- /dev/null
+++ b/odata4-lib/odata4-client-core/src/test/java/org/apache/olingo/odata4/client/core/v4/MetadataTest.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.odata4.client.core.v4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.olingo.odata4.client.api.data.EdmSimpleType;
+import org.apache.olingo.odata4.client.core.AbstractTest;
+import org.apache.olingo.odata4.client.core.ODataV4Client;
+import org.apache.olingo.odata4.client.core.edm.v4.FunctionImportImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.ActionImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.AnnotationImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.AnnotationsImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.ComplexTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EdmMetadataImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EdmTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EntityContainerImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EntitySetImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EntityTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.EnumTypeImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.FunctionImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.SchemaImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.SingletonImpl;
+import org.apache.olingo.odata4.client.core.edm.v4.annotation.Apply;
+import org.apache.olingo.odata4.client.core.edm.v4.annotation.Collection;
+import org.apache.olingo.odata4.client.core.edm.v4.annotation.ConstExprConstruct;
+import org.apache.olingo.odata4.client.core.edm.v4.annotation.Path;
+import org.apache.olingo.odata4.commons.api.edm.constants.StoreGeneratedPattern;
+import org.junit.Test;
+
+public class MetadataTest extends AbstractTest {
+
+  @Override
+  protected ODataV4Client getClient() {
+    return v4Client;
+  }
+
+  @Test
+  public void parse() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    assertNotNull(metadata);
+
+    // 1. Enum
+    final EnumTypeImpl responseEnumType = metadata.getSchema(0).getEnumType("ResponseType");
+    assertNotNull(responseEnumType);
+    assertEquals(6, responseEnumType.getMembers().size());
+    assertEquals(3, responseEnumType.getMember("Accepted").getValue().intValue());
+    assertEquals("Accepted", responseEnumType.getMember(3).getName());
+
+    final EdmTypeImpl responseType = new EdmTypeImpl(metadata,
+            "Microsoft.Exchange.Services.OData.Model.ResponseType");
+    assertNotNull(responseType);
+    assertFalse(responseType.isCollection());
+    assertFalse(responseType.isSimpleType());
+    assertTrue(responseType.isEnumType());
+    assertFalse(responseType.isComplexType());
+    assertFalse(responseType.isEntityType());
+
+    // 2. Complex
+    final ComplexTypeImpl responseStatus = metadata.getSchema(0).getComplexType("ResponseStatus");
+    assertNotNull(responseStatus);
+    assertTrue(responseStatus.getNavigationProperties().isEmpty());
+    assertEquals(EdmSimpleType.DateTimeOffset,
+            EdmSimpleType.fromValue(responseStatus.getProperty("Time").getType()));
+
+    // 3. Entity
+    final EntityTypeImpl user = metadata.getSchema(0).getEntityType("User");
+    assertNotNull(user);
+    assertEquals("Microsoft.Exchange.Services.OData.Model.Entity", user.getBaseType());
+    assertFalse(user.getProperties().isEmpty());
+    assertFalse(user.getNavigationProperties().isEmpty());
+    assertEquals("Microsoft.Exchange.Services.OData.Model.Folder", user.getNavigationProperty("Inbox").getType());
+
+    // 4. Action
+    final List<ActionImpl> moves = metadata.getSchema(0).getActions("Move");
+    assertFalse(moves.isEmpty());
+    ActionImpl move = null;
+    for (ActionImpl action : moves) {
+      if ("Microsoft.Exchange.Services.OData.Model.EmailMessage".equals(action.getReturnType().getType())) {
+        move = action;
+      }
+    }
+    assertNotNull(move);
+    assertTrue(move.isBound());
+    assertEquals("bindingParameter", move.getEntitySetPath());
+    assertEquals(2, move.getParameters().size());
+    assertEquals("Microsoft.Exchange.Services.OData.Model.EmailMessage", move.getParameters().get(0).getType());
+
+    // 5. EntityContainer
+    final EntityContainerImpl container = metadata.getSchema(0).getEntityContainer();
+    assertNotNull(container);
+    final EntitySetImpl users = container.getEntitySet("Users");
+    assertNotNull(users);
+    assertEquals(metadata.getSchema(0).getNamespace() + "." + user.getName(), users.getEntityType());
+    assertEquals(user.getNavigationProperties().size(), users.getNavigationPropertyBindings().size());
+  }
+
+  @Test
+  public void demo() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("demo-metadata.xml"));
+    assertNotNull(metadata);
+
+    assertFalse(metadata.getSchema(0).getAnnotationsList().isEmpty());
+    AnnotationsImpl annots = metadata.getSchema(0).getAnnotationsList("ODataDemo.DemoService/Suppliers");
+    assertNotNull(annots);
+    assertFalse(annots.getAnnotations().isEmpty());
+    assertEquals(ConstExprConstruct.Type.String,
+            annots.getAnnotation("Org.OData.Publication.V1.PrivacyPolicyUrl").getConstExpr().getType());
+    assertEquals("http://www.odata.org/",
+            annots.getAnnotation("Org.OData.Publication.V1.PrivacyPolicyUrl").getConstExpr().getValue());
+  }
+
+  @Test
+  public void multipleSchemas() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("northwind-metadata.xml"));
+    assertNotNull(metadata);
+
+    final SchemaImpl first = metadata.getSchema("NorthwindModel");
+    assertNotNull(first);
+
+    final SchemaImpl second = metadata.getSchema("ODataWebExperimental.Northwind.Model");
+    assertNotNull(second);
+
+    assertEquals(StoreGeneratedPattern.Identity,
+            first.getEntityType("Category").getProperty("CategoryID").getStoreGeneratedPattern());
+
+    final EntityContainerImpl entityContainer = second.getDefaultEntityContainer();
+    assertNotNull(entityContainer);
+    assertEquals("NorthwindEntities", entityContainer.getName());
+    assertTrue(entityContainer.isLazyLoadingEnabled());
+  }
+
+  /**
+   * Tests Example 85 from CSDL specification.
+   */
+  @Test
+  public void fromdoc1() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
+    assertNotNull(metadata);
+
+    assertFalse(metadata.getReferences().isEmpty());
+    assertEquals("Org.OData.Measures.V1", metadata.getReferences().get(1).getIncludes().get(0).getNamespace());
+
+    final EntityTypeImpl product = metadata.getSchema(0).getEntityType("Product");
+    assertTrue(product.isHasStream());
+    assertEquals("UoM.ISOCurrency", product.getProperty("Price").getAnnotation().getTerm());
+    //assertEquals("Currency", product.getProperty("Price").getAnnotation().));
+    assertEquals("Products", product.getNavigationProperty("Supplier").getPartner());
+
+    final EntityTypeImpl category = metadata.getSchema(0).getEntityType("Category");
+    final EdmTypeImpl type = new EdmTypeImpl(metadata, category.getNavigationProperty("Products").getType());
+    assertNotNull(type);
+    assertTrue(type.isCollection());
+    assertFalse(type.isSimpleType());
+
+    final ComplexTypeImpl address = metadata.getSchema(0).getComplexType("Address");
+    assertFalse(address.getNavigationProperty("Country").getReferentialConstraints().isEmpty());
+    assertEquals("Name",
+            address.getNavigationProperty("Country").getReferentialConstraints().get(0).getReferencedProperty());
+
+    final FunctionImpl productsByRating = metadata.getSchema(0).getFunctions("ProductsByRating").get(0);
+    assertNotNull(productsByRating.getParameter("Rating"));
+    assertEquals("Edm.Int32", productsByRating.getParameter("Rating").getType());
+    assertEquals("Collection(ODataDemo.Product)", productsByRating.getReturnType().getType());
+
+    final SingletonImpl contoso = metadata.getSchema(0).getEntityContainer().getSingleton("Contoso");
+    assertNotNull(contoso);
+    assertFalse(contoso.getNavigationPropertyBindings().isEmpty());
+    assertEquals("Products", contoso.getNavigationPropertyBindings().get(0).getPath());
+
+    final FunctionImportImpl functionImport = metadata.getSchema(0).getEntityContainer().
+            getFunctionImport("ProductsByRating");
+    assertNotNull(functionImport);
+    assertEquals(metadata.getSchema(0).getNamespace() + "." + productsByRating.getName(),
+            functionImport.getFunction());
+  }
+
+  /**
+   * Tests Example 86 from CSDL specification.
+   */
+  @Test
+  public void fromdoc2() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("fromdoc2-metadata.xml"));
+    assertNotNull(metadata);
+
+    // Check displayName
+    final AnnotationImpl displayName = metadata.getSchema(0).getAnnotationsList("ODataDemo.Supplier").
+            getAnnotation("Vocabulary1.DisplayName");
+    assertNotNull(displayName);
+    assertNull(displayName.getConstExpr());
+    assertNotNull(displayName.getDynExpr());
+
+    assertTrue(displayName.getDynExpr() instanceof Apply);
+    final Apply apply = (Apply) displayName.getDynExpr();
+    assertEquals(Apply.CANONICAL_FUNCTION_CONCAT, apply.getFunction());
+    assertEquals(3, apply.getParameters().size());
+
+    final Path firstArg = new Path();
+    firstArg.setValue("Name");
+    assertEquals(firstArg, apply.getParameters().get(0));
+
+    final ConstExprConstruct secondArg = new ConstExprConstruct();
+    secondArg.setType(ConstExprConstruct.Type.String);
+    secondArg.setValue(" in ");
+    assertEquals(secondArg, apply.getParameters().get(1));
+
+    final Path thirdArg = new Path();
+    thirdArg.setValue("Address/CountryName");
+    assertEquals(thirdArg, apply.getParameters().get(2));
+
+    // Check Tags
+    final AnnotationImpl tags = metadata.getSchema(0).getAnnotationsList("ODataDemo.Product").
+            getAnnotation("Vocabulary1.Tags");
+    assertNotNull(tags);
+    assertNull(tags.getConstExpr());
+    assertNotNull(tags.getDynExpr());
+
+    assertTrue(tags.getDynExpr() instanceof Collection);
+    final Collection collection = (Collection) tags.getDynExpr();
+    assertEquals(1, collection.getItems().size());
+    assertEquals(ConstExprConstruct.Type.String, ((ConstExprConstruct) collection.getItems().get(0)).getType());
+    assertEquals("MasterData", ((ConstExprConstruct) collection.getItems().get(0)).getValue());
+  }
+
+  /**
+   * Various annotation examples taken from CSDL specification.
+   */
+  @Test
+  public void fromdoc3() {
+    final EdmMetadataImpl metadata = getClient().getReader().
+            readMetadata(getClass().getResourceAsStream("fromdoc3-metadata.xml"));
+    assertNotNull(metadata);
+  }
+
+}