You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2016/02/19 09:40:06 UTC

[1/4] olingo-odata4 git commit: OLINGO-878: Adding support to remove unvalid xml characters from Atom payload

Repository: olingo-odata4
Updated Branches:
  refs/heads/OLINGO-832_StreamSerializerPoC 5b6cccfa9 -> 396a39bae


OLINGO-878: Adding support to remove unvalid xml characters from Atom payload


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/d880d6c4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/d880d6c4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/d880d6c4

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: d880d6c48058d9413bb914a5bd3c13f70a9db323
Parents: 3c205f9
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Thu Feb 11 14:12:47 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Fri Feb 12 19:37:58 2016 -0600

----------------------------------------------------------------------
 .../serializer/ComplexSerializerOptions.java    |  14 +-
 .../EntityCollectionSerializerOptions.java      |  14 +-
 .../api/serializer/EntitySerializerOptions.java |  14 +-
 .../serializer/PrimitiveSerializerOptions.java  |  13 ++
 .../PrimitiveValueSerializerOptions.java        |  14 +-
 .../olingo/server/core/MetadataParser.java      | 199 +++++++++++++++----
 .../server/core/SchemaBasedEdmProvider.java     |  86 +++-----
 .../olingo/server/core/ServiceRequest.java      |  50 ++++-
 .../server/core/requests/DataRequest.java       |  13 +-
 .../src/main/resources/org.apache.olingo.v1.xml |  40 ++++
 .../core/MetadataParserAnnotationsTest.java     |   2 +-
 .../olingo/server/core/MetadataParserTest.java  |   1 -
 .../server/core/ServiceDispatcherTest.java      |   3 +
 .../server/example/TripPinServiceTest.java      |  25 ++-
 .../olingo/server/example/TripPinServlet.java   |   3 +-
 .../src/test/resources/airlines.json            |   2 +-
 .../src/test/resources/annotations.xml          |   3 +
 .../src/test/resources/trippin.xml              |   6 +-
 .../core/serializer/xml/ODataXmlSerializer.java | 138 +++++++++----
 .../serializer/xml/ODataXmlSerializerTest.java  |  27 ++-
 20 files changed, 498 insertions(+), 169 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
index d6788e5..179c4d4 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
@@ -28,6 +28,7 @@ public class ComplexSerializerOptions {
   private ContextURL contextURL;
   private ExpandOption expand;
   private SelectOption select;
+  private String xml10InvalidCharReplacement;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -44,6 +45,11 @@ public class ComplexSerializerOptions {
     return select;
   }
 
+  /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+  public String xml10InvalidCharReplacement() {
+    return xml10InvalidCharReplacement;
+  }  
+
   private ComplexSerializerOptions() {}
 
   /** Initializes the options builder. */
@@ -77,7 +83,13 @@ public class ComplexSerializerOptions {
       options.select = select;
       return this;
     }
-
+    
+    /** set the replacement string for xml 1.0 unicode controlled characters that are not allowed */
+    public Builder xml10InvalidCharReplacement(final String replacement) {
+      options.xml10InvalidCharReplacement = replacement;
+      return this;
+    } 
+    
     /** Builds the OData serializer options. */
     public ComplexSerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
index 611485f..9ee7d24 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
@@ -32,6 +32,7 @@ public class EntityCollectionSerializerOptions {
   private SelectOption select;
   private boolean writeOnlyReferences;
   private String id;
+  private String xml10InvalidCharReplacement;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -63,6 +64,11 @@ public class EntityCollectionSerializerOptions {
     return id;
   }
 
+  /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+  public String xml10InvalidCharReplacement() {
+    return xml10InvalidCharReplacement;
+  }  
+
   /** Initializes the options builder. */
   public static Builder with() {
     return new Builder();
@@ -112,7 +118,13 @@ public class EntityCollectionSerializerOptions {
       options.id = id;
       return this;
     }
-
+    
+    /** set the replacement String for xml 1.0 unicode controlled characters that are not allowed */
+    public Builder xml10InvalidCharReplacement(final String replacement) {
+      options.xml10InvalidCharReplacement = replacement;
+      return this;
+    } 
+    
     /** Builds the OData serializer options. */
     public EntityCollectionSerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
index 16481a2..e244660 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
@@ -28,6 +28,7 @@ public class EntitySerializerOptions {
   private ExpandOption expand;
   private SelectOption select;
   private boolean writeOnlyReferences;
+  private String xml10InvalidCharReplacement;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -49,6 +50,11 @@ public class EntitySerializerOptions {
     return writeOnlyReferences;
   }
 
+  /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+  public String xml10InvalidCharReplacement() {
+    return xml10InvalidCharReplacement;
+  }  
+
   private EntitySerializerOptions() {}
 
   /** Initializes the options builder. */
@@ -88,7 +94,13 @@ public class EntitySerializerOptions {
       options.writeOnlyReferences = ref;
       return this;
     }
-
+    
+    /** set the replacement string for xml 1.0 unicode controlled characters that are not allowed */
+    public Builder xml10InvalidCharReplacement(final String replacement) {
+      options.xml10InvalidCharReplacement = replacement;
+      return this;
+    } 
+    
     /** Builds the OData serializer options. */
     public EntitySerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
index 1de20d8..61a3160 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
@@ -30,6 +30,7 @@ public final class PrimitiveSerializerOptions {
   private Integer precision;
   private Integer scale;
   private Boolean isUnicode;
+  private String xml10InvalidCharReplacement;
 
   /** Gets the {@link ContextURL}. */
   public ContextURL getContextURL() {
@@ -60,6 +61,12 @@ public final class PrimitiveSerializerOptions {
   public Boolean isUnicode() {
     return isUnicode;
   }
+  
+  /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+  public String xml10InvalidCharReplacement() {
+    return xml10InvalidCharReplacement;
+  }  
+  
 
   private PrimitiveSerializerOptions() {}
 
@@ -123,6 +130,12 @@ public final class PrimitiveSerializerOptions {
       return this;
     }
 
+    /** set the replacement string for xml 1.0 unicode controlled characters that are not allowed */
+    public Builder xml10InvalidCharReplacement(final String replacement) {
+      options.xml10InvalidCharReplacement = replacement;
+      return this;
+    } 
+    
     /** Builds the OData serializer options. */
     public PrimitiveSerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
index e84aaa4..c72f420 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
@@ -28,6 +28,7 @@ public class PrimitiveValueSerializerOptions {
   private Integer precision;
   private Integer scale;
   private Boolean isUnicode;
+  private String xml10InvalidCharReplacement;
 
   /** Gets the nullable facet. */
   public Boolean isNullable() {
@@ -53,6 +54,11 @@ public class PrimitiveValueSerializerOptions {
   public Boolean isUnicode() {
     return isUnicode;
   }
+  
+  /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+  public String xml10InvalidCharReplacement() {
+    return xml10InvalidCharReplacement;
+  }  
 
   private PrimitiveValueSerializerOptions() {}
 
@@ -109,7 +115,13 @@ public class PrimitiveValueSerializerOptions {
       options.isUnicode = property.isUnicode();
       return this;
     }
-
+    
+    /** set the replacement string for xml 1.0 unicode controlled characters that are not allowed */
+    public Builder xml10InvalidCharReplacement(final String replacement) {
+      options.xml10InvalidCharReplacement = replacement;
+      return this;
+    } 
+    
     /** Builds the OData serializer options. */
     public PrimitiveValueSerializerOptions build() {
       return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index 03a6675..b93ef4c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -97,57 +97,93 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceIncludeAnnotation;
 public class MetadataParser {
   private boolean parseAnnotations = false;
   private static final String XML_LINK_NS = "http://www.w3.org/1999/xlink";
-  private ReferenceResolver defaultReferenceResolver = new DefaultReferenceResolver();
-  private boolean loadCoreVocabularies = false;
+  private ReferenceResolver referenceResolver = new DefaultReferenceResolver();
+  private boolean useLocalCoreVocabularies = true;
+  private boolean implicitlyLoadCoreVocabularies = false;
   
+  /**
+   * Avoid reading the annotations in the $metadata 
+   * @param parse
+   * @return
+   */
   public MetadataParser parseAnnotations(boolean parse) {
     this.parseAnnotations = parse;
     return this;
   }
-  
+
+  /**
+   * Externalize the reference loading, such that they can be loaded from local caches
+   * @param resolver
+   * @return
+   */
   public MetadataParser referenceResolver(ReferenceResolver resolver) {
-    this.defaultReferenceResolver = resolver;
+    this.referenceResolver = resolver;
     return this;
   }
   
-  public MetadataParser loadCoreVocabularies(boolean load) {
-    this.loadCoreVocabularies = load;
+  /**
+   * Load the core libraries from local classpath
+   * @param load true for yes; false otherwise
+   * @return
+   */
+  public MetadataParser useLocalCoreVocabularies(boolean load) {
+    this.useLocalCoreVocabularies = load;
+    return this;
+  }
+  
+  /**
+   * Load the core vocabularies, irrespective of if they are defined in the $metadata
+   * @param load
+   * @return
+   */
+  public MetadataParser implicitlyLoadCoreVocabularies(boolean load) {
+    this.implicitlyLoadCoreVocabularies = load;
     return this;
   }
   
   public ServiceMetadata buildServiceMetadata(Reader csdl) throws XMLStreamException {
-    SchemaBasedEdmProvider provider = buildEdmProvider(csdl,
-        this.defaultReferenceResolver, this.loadCoreVocabularies);
+    SchemaBasedEdmProvider provider = buildEdmProvider(csdl, this.referenceResolver,
+        this.implicitlyLoadCoreVocabularies, this.useLocalCoreVocabularies);
     return new ServiceMetadataImpl(provider, provider.getReferences(), null);
   }
 
   public SchemaBasedEdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
-    return buildEdmProvider(csdl, this.defaultReferenceResolver, this.loadCoreVocabularies);
+    XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+    XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);    
+    return buildEdmProvider(reader, this.referenceResolver,
+        this.implicitlyLoadCoreVocabularies, this.useLocalCoreVocabularies);
   }
-    
+  
   protected SchemaBasedEdmProvider buildEdmProvider(Reader csdl,
-      ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
+      ReferenceResolver resolver, boolean loadCore, boolean useLocal)
+      throws XMLStreamException {
     XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
-    XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
-    return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
+    XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);    
+    return buildEdmProvider(reader, resolver, loadCore, useLocal);
   }
-  
+    
   protected SchemaBasedEdmProvider buildEdmProvider(InputStream csdl,
-      ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
+      ReferenceResolver resolver, boolean loadCore, boolean useLocal)
+      throws XMLStreamException {
     XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
     XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
-    return buildEdmProvider(reader, referenceResolver, loadCoreVocabularies);
+    return buildEdmProvider(reader, resolver, loadCore, useLocal);
   } 
   
   protected SchemaBasedEdmProvider buildEdmProvider(XMLEventReader reader,
-      ReferenceResolver referenceResolver, boolean loadCoreVocabularies) throws XMLStreamException {
-    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider(referenceResolver);
+      ReferenceResolver resolver, boolean loadCore, boolean useLocal)
+      throws XMLStreamException {
+    SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+    
+    final StringBuilder xmlBase = new StringBuilder();
+    
     new ElementReader<SchemaBasedEdmProvider>() {
       @Override
       void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
           String name) throws XMLStreamException {
-        String xmlBase = attrNS(element, XML_LINK_NS, "base");
-        provider.setXMLBase(xmlBase);        
+        if (attrNS(element, XML_LINK_NS, "base") != null) {
+          xmlBase.append(attrNS(element, XML_LINK_NS, "base"));
+        }
         String version = attr(element, "Version");
         if ("4.0".equals(version)) {
           readDataServicesAndReference(reader, element, provider);
@@ -167,23 +203,100 @@ public class MetadataParser {
                   event.asEndElement().getName().getLocalPart()));
     }
     
-    // load the core vocabularies
-    if (loadCoreVocabularies) {
-      loadVocabularySchema(provider, "Org.OData.Core.V1", "Org.OData.Core.V1.xml");
-      loadVocabularySchema(provider, "Org.OData.Capabilities.V1", "Org.OData.Capabilities.V1.xml");
-      loadVocabularySchema(provider, "Org.OData.Measures.V1", "Org.OData.Measures.V1.xml");
-    }    
+    //load core vocabularies even though they are not defined in the references
+    if (loadCore) {
+      loadCoreVocabulary(provider, "Org.OData.Core.V1");
+      loadCoreVocabulary(provider, "Org.OData.Capabilities.V1");
+      loadCoreVocabulary(provider, "Org.OData.Measures.V1");
+    }
+    
+    // load all the reference schemas
+    if (resolver != null) {
+      loadReferencesSchemas(provider, xmlBase.length() == 0 ? null
+          : fixXmlBase(xmlBase.toString()), resolver, loadCore, useLocal);
+    }
     return provider;
   }  
   
-  private void loadVocabularySchema(SchemaBasedEdmProvider provider, String namespace,
+  private void loadReferencesSchemas(SchemaBasedEdmProvider provider,
+      String xmlBase, ReferenceResolver resolver, boolean loadCore,
+      boolean useLocal) {    
+
+    for (EdmxReference reference:provider.getReferences()) {
+      try {
+        SchemaBasedEdmProvider refProvider = null;
+
+        for (EdmxReferenceInclude include : reference.getIncludes()) {
+
+          // check if the schema is already loaded before.
+          if (provider.getSchema(include.getNamespace()) != null) {
+            continue;
+          }
+          
+          if (isCoreVocabulary(include.getNamespace()) && useLocal) {
+            loadCoreVocabulary(provider, include.getNamespace());
+            continue;
+          }
+                    
+          if (refProvider == null) {
+            InputStream is = this.referenceResolver.resolveReference(reference.getUri(), xmlBase);
+            if (is == null) {
+              throw new EdmException("Failed to load Reference "+reference.getUri()+" loading failed");
+            } else {
+              // do not implicitly load core vocabularies any more. But if the
+              // references loading the core vocabularies try to use local if we can 
+              refProvider = buildEdmProvider(is, resolver, false, useLocal);
+            }
+          }
+          
+          CsdlSchema refSchema = refProvider.getSchema(include.getNamespace(), false);
+          provider.addReferenceSchema(include.getNamespace(), refProvider);
+          if (include.getAlias() != null) {
+            refSchema.setAlias(include.getAlias());
+            provider.addReferenceSchema(include.getAlias(), refProvider);
+          }
+        }
+      } catch (XMLStreamException e) {
+        throw new EdmException("Failed to load Reference "+reference.getUri()+" parsing failed");
+      }
+    }
+  }
+  
+  private void loadCoreVocabulary(SchemaBasedEdmProvider provider,
+      String namespace) throws XMLStreamException {
+    if(namespace.equalsIgnoreCase("Org.OData.Core.V1")) {
+      loadLocalVocabularySchema(provider, "Org.OData.Core.V1", "Org.OData.Core.V1.xml");
+    } else if (namespace.equalsIgnoreCase("Org.OData.Capabilities.V1")) {
+      loadLocalVocabularySchema(provider, "Org.OData.Capabilities.V1", "Org.OData.Capabilities.V1.xml");
+    } else if (namespace.equalsIgnoreCase("Org.OData.Measures.V1")) {
+      loadLocalVocabularySchema(provider, "Org.OData.Measures.V1", "Org.OData.Measures.V1.xml");
+    }
+  }
+
+  private boolean isCoreVocabulary(String namespace) {
+    if(namespace.equalsIgnoreCase("Org.OData.Core.V1") || 
+        namespace.equalsIgnoreCase("Org.OData.Capabilities.V1") || 
+        namespace.equalsIgnoreCase("Org.OData.Measures.V1")) {
+      return true;
+    }
+    return false;
+  }
+
+  private String fixXmlBase(String base) {
+    if (base.endsWith("/")) {
+      return base;
+    } 
+    return base+"/";
+  }  
+  
+  private void loadLocalVocabularySchema(SchemaBasedEdmProvider provider, String namespace,
       String resource) throws XMLStreamException {
-    CsdlSchema schema = provider.getSchema(namespace, false);
+    CsdlSchema schema = provider.getVocabularySchema(namespace);
     if (schema == null) {
       InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource);
       if (is != null) {
-        SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false);
-        provider.addSchema(childProvider.getSchema(namespace, false));
+        SchemaBasedEdmProvider childProvider = buildEdmProvider(is, null, false, false);
+        provider.addVocabularySchema(namespace, childProvider);
       } else {
         throw new XMLStreamException("failed to load "+resource+" core vocabulary");
       }
@@ -191,7 +304,8 @@ public class MetadataParser {
   }  
   
   private void readDataServicesAndReference(XMLEventReader reader,
-      StartElement element, SchemaBasedEdmProvider provider) throws XMLStreamException {
+      StartElement element, SchemaBasedEdmProvider provider)
+      throws XMLStreamException {
     final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
     new ElementReader<SchemaBasedEdmProvider>() {
       @Override
@@ -384,7 +498,9 @@ public class MetadataParser {
     CsdlTypeDefinition td = new CsdlTypeDefinition();
     td.setName(attr(element, "Name"));
     td.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
-    td.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+    if (attr(element, "Unicode") != null) {
+      td.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+    }
 
     String maxLength = attr(element, "MaxLength");
     if (maxLength != null) {
@@ -837,7 +953,9 @@ public class MetadataParser {
     property.setCollection(isCollectionType(element));
     property.setNullable(Boolean.parseBoolean(attr(element, "Nullable") == null ? "true" : attr(
         element, "Nullable")));
-    property.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+    if (attr(element, "Unicode") != null) {
+      property.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+    }
 
     String maxLength = attr(element, "MaxLength");
     if (maxLength != null) {
@@ -1077,18 +1195,23 @@ public class MetadataParser {
   private static class DefaultReferenceResolver implements ReferenceResolver {
     @Override
     public InputStream resolveReference(URI referenceUri, String xmlBase) {
-      URL schemaURL = null;
+      InputStream in = null;
       try {
         if (referenceUri.isAbsolute()) {
-          schemaURL = referenceUri.toURL();
+          URL schemaURL = referenceUri.toURL();
+          in = schemaURL.openStream();
         } else {
           if (xmlBase != null) {
-            schemaURL = new URL(xmlBase+referenceUri.toString());
+            URL schemaURL = new URL(xmlBase+referenceUri.toString());
+            in = schemaURL.openStream();
           } else {
-            throw new EdmException("No xml:base set to read the references from the metadata");
+            in = this.getClass().getClassLoader().getResourceAsStream(referenceUri.getPath());
+            if (in == null) {
+              throw new EdmException("No xml:base set to read the references from the metadata");
+            }
           }        
         }
-        return schemaURL.openStream();
+        return in;
       } catch (MalformedURLException e) {
         throw new EdmException(e);
       } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
index a778e2c..8aea555 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
@@ -18,15 +18,11 @@
  */
 package org.apache.olingo.server.core;
 
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import javax.xml.stream.XMLStreamException;
-
-import org.apache.olingo.commons.api.edm.EdmException;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.provider.CsdlAction;
 import org.apache.olingo.commons.api.edm.provider.CsdlActionImport;
@@ -52,15 +48,11 @@ import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
 public class SchemaBasedEdmProvider implements CsdlEdmProvider {
   private final List<CsdlSchema> edmSchemas = new ArrayList<CsdlSchema>();
   private final Map<String, EdmxReference> references = new ConcurrentHashMap<String, EdmxReference>();
-  private final Map<String, SchemaBasedEdmProvider> referenceSchemas 
-    = new ConcurrentHashMap<String, SchemaBasedEdmProvider>();
-  private String xmlBase;
-  private ReferenceResolver referenceResolver;
+  private final Map<String, SchemaBasedEdmProvider> referenceSchemas = 
+      new ConcurrentHashMap<String, SchemaBasedEdmProvider>();
+  private final Map<String, SchemaBasedEdmProvider> coreVocabularySchemas = 
+      new ConcurrentHashMap<String, SchemaBasedEdmProvider>();
   
-  public SchemaBasedEdmProvider(ReferenceResolver referenceResolver) {
-    this.referenceResolver = referenceResolver;
-  }
-
   void addSchema(CsdlSchema schema) {
     this.edmSchemas.add(schema);
   }
@@ -68,7 +60,23 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
   List<EdmxReference> getReferences(){
     return new ArrayList<EdmxReference>(references.values());
   }
-
+  
+  void addReferenceSchema(String ns, SchemaBasedEdmProvider provider) {
+    this.referenceSchemas.put(ns, provider);
+  }  
+  
+  void addVocabularySchema(String ns, SchemaBasedEdmProvider provider) {
+    this.coreVocabularySchemas.put(ns, provider);
+  }
+  
+  CsdlSchema getVocabularySchema(String ns) {
+    SchemaBasedEdmProvider provider = this.coreVocabularySchemas.get(ns);
+    if (provider != null) {
+      return provider.getSchema(ns, false);
+    }
+    return null;
+  }
+  
   CsdlSchema getSchema(String ns) {
     return getSchema(ns, true);
   }  
@@ -79,46 +87,20 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
         return s;
       }
     }
+    CsdlSchema s = null; 
     if (checkReferences) {
-      return getReferenceSchema(ns);
+      s = getReferenceSchema(ns);
+      if (s == null) {
+        s = getVocabularySchema(ns);
+      }
     }
-    return null;
+    return s;
   }
 
-  private CsdlSchema getReferenceSchema(String ns) {
+  CsdlSchema getReferenceSchema(String ns) {
     if (ns == null) {
       return null;
     }
-    if (this.referenceSchemas.get(ns) == null) {
-      EdmxReference reference = this.references.get(ns);
-      if (reference != null) {
-        SchemaBasedEdmProvider provider = null;
-        if (this.referenceResolver == null) {
-          throw new EdmException("Failed to load Reference "+reference.getUri());
-        } else {
-          InputStream is = this.referenceResolver.resolveReference(reference.getUri(), this.xmlBase);
-          if (is != null) {
-            try {
-              MetadataParser parser = new MetadataParser();
-              provider = parser.buildEdmProvider(is, this.referenceResolver, false);
-            } catch (XMLStreamException e) {
-              throw new EdmException("Failed to load Reference "+reference.getUri()+" parsing failed");
-            }
-          } else {
-            throw new EdmException("Failed to load Reference "+reference.getUri()+" loading failed");
-          }
-        }
-        // copy references
-        for (EdmxReferenceInclude include : reference.getIncludes()) {
-          this.referenceSchemas.put(include.getNamespace(), provider);
-          if (include.getAlias() != null) {
-            CsdlSchema schema = provider.getSchema(include.getNamespace());
-            schema.setAlias(include.getAlias());
-            this.referenceSchemas.put(include.getAlias(), provider);
-          }
-        }
-      }
-    }
     
     if (this.referenceSchemas.get(ns) != null) {
       return this.referenceSchemas.get(ns).getSchema(ns);  
@@ -133,7 +115,7 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
     }
     return null;
   }
-
+  
   @Override
   public CsdlEnumType getEnumType(FullQualifiedName fqn) throws ODataException {
     CsdlSchema schema = getSchema(fqn.getNamespace());
@@ -402,15 +384,5 @@ public class SchemaBasedEdmProvider implements CsdlEdmProvider {
         }
       }
     }
-  }
-
-  public void setXMLBase(String base) {
-    if (base != null) {
-      if (base.endsWith("/")) {
-        this.xmlBase = base;
-      } else {
-        this.xmlBase = base+"/";
-      }
-    }
   } 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
index 0796144..f6b3296 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceRequest.java
@@ -27,14 +27,18 @@ import java.util.Map;
 import java.util.StringTokenizer;
 
 import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.edm.EdmAnnotation;
+import org.apache.olingo.commons.api.edm.EdmSchema;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.annotation.EdmConstantExpression;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpMethod;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataLibraryException;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
 import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
@@ -140,26 +144,60 @@ public abstract class ServiceRequest {
     return this.request.getMethod() == HttpMethod.POST;
   }
 
+  private static FullQualifiedName XML10_CHAR_REPLACE_FQN = new FullQualifiedName(
+      "org.apache.olingo.v1.xml10-incompatible-char-replacement");
+  /**
+   * Replacement character for the XML10 characters that are not supported.
+   * @return
+   */
+  protected String xml10IncompatibleCharReplacement() {
+    for (EdmSchema schema : getServiceMetaData().getEdm().getSchemas()) {
+      if (schema.getEntityContainer() != null) {
+        for (EdmAnnotation annotation:schema.getAnnotations()) {
+          if (annotation.getTerm() != null
+              && annotation.getTerm().getFullQualifiedName().equals(XML10_CHAR_REPLACE_FQN)) {
+            EdmConstantExpression expr = annotation.getExpression().asConstant();
+            return expr.getValueAsString();            
+          }
+        }
+      }
+    }
+    return null;
+  }
+  
   @SuppressWarnings("unchecked")
-  public <T> T getSerializerOptions(Class<T> serilizerOptions, ContextURL contextUrl,
-      boolean references) throws ContentNegotiatorException {
+  public <T> T getSerializerOptions(Class<T> serilizerOptions,
+      ContextURL contextUrl, boolean references) throws ContentNegotiatorException {
+    
+    String xmlReplacement = null;
+    if (getResponseContentType().isCompatible(ContentType.APPLICATION_XML)
+        || getResponseContentType().isCompatible(ContentType.APPLICATION_ATOM_XML)) {
+      xmlReplacement = xml10IncompatibleCharReplacement();
+    }
     
     if (serilizerOptions.isAssignableFrom(EntitySerializerOptions.class)) {
       return (T) EntitySerializerOptions.with()
           .contextURL(isODataMetadataNone(getResponseContentType()) ? null : contextUrl)
           .expand(uriInfo.getExpandOption()).select(this.uriInfo.getSelectOption())
-          .writeOnlyReferences(references).build();
+          .writeOnlyReferences(references)
+          .xml10InvalidCharReplacement(xmlReplacement)
+          .build();
     } else if (serilizerOptions.isAssignableFrom(EntityCollectionSerializerOptions.class)) {
       return (T) EntityCollectionSerializerOptions.with()
           .contextURL(isODataMetadataNone(getResponseContentType()) ? null : contextUrl)
           .count(uriInfo.getCountOption()).expand(uriInfo.getExpandOption())
           .select(uriInfo.getSelectOption()).writeOnlyReferences(references)
-          .id(getODataRequest().getRawBaseUri() + getODataRequest().getRawODataPath()).build();
+          .id(getODataRequest().getRawBaseUri() + getODataRequest().getRawODataPath())
+          .xml10InvalidCharReplacement(xmlReplacement)
+          .build();
     } else if (serilizerOptions.isAssignableFrom(ComplexSerializerOptions.class)) {
       return (T) ComplexSerializerOptions.with().contextURL(contextUrl)
-          .expand(this.uriInfo.getExpandOption()).select(this.uriInfo.getSelectOption()).build();
+          .expand(this.uriInfo.getExpandOption()).select(this.uriInfo.getSelectOption())
+          .xml10InvalidCharReplacement(xmlReplacement)
+          .build();
     } else if (serilizerOptions.isAssignableFrom(PrimitiveSerializerOptions.class)) {
       return (T) PrimitiveSerializerOptions.with().contextURL(contextUrl)
+          .xml10InvalidCharReplacement(xmlReplacement)
           .build();
     }
     return null;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
index 42fbdea..45e1ed6 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -248,10 +248,19 @@ public class DataRequest extends ServiceRequest {
   @SuppressWarnings("unchecked")
   @Override
   public <T> T getSerializerOptions(Class<T> serilizerOptions, ContextURL contextUrl, boolean references)
-      throws ContentNegotiatorException {
+      throws ContentNegotiatorException {   
     if (serilizerOptions.isAssignableFrom(PrimitiveSerializerOptions.class)) {
+      
+      String xmlReplacement = null;
+      if (getResponseContentType().isCompatible(ContentType.APPLICATION_XML)
+          || getResponseContentType().isCompatible(ContentType.APPLICATION_ATOM_XML)) {
+        xmlReplacement = xml10IncompatibleCharReplacement();
+      }      
+      
       return (T) PrimitiveSerializerOptions.with().contextURL(contextUrl)
-          .facetsFrom(getUriResourceProperty().getProperty()).build();
+          .facetsFrom(getUriResourceProperty().getProperty())
+          .xml10InvalidCharReplacement(xmlReplacement)
+          .build();
     }
     return super.getSerializerOptions(serilizerOptions, contextUrl, references);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/main/resources/org.apache.olingo.v1.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/resources/org.apache.olingo.v1.xml b/lib/server-core-ext/src/main/resources/org.apache.olingo.v1.xml
new file mode 100644
index 0000000..d197e45
--- /dev/null
+++ b/lib/server-core-ext/src/main/resources/org.apache.olingo.v1.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+  <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
+    <edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
+  </edmx:Reference>
+  <edmx:DataServices>
+    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="org.apache.olingo.v1" Alias="olingo-extensions">
+
+      <Term Name="xml10-incompatible-char-replacement" Type="Edm.String" AppliesTo="PropertyValue ReturnType">
+        <Annotation Term="Core.Description">
+          <String>
+            Replacement character for invalid characters in the XML 1.0 Atom payload
+          </String>
+        </Annotation>
+      </Term>
+      
+    </Schema>
+  </edmx:DataServices>
+</edmx:Edmx>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
index d71c54d..75c12ad 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
@@ -60,7 +60,7 @@ public class MetadataParserAnnotationsTest {
   public void setUp() throws Exception {
     MetadataParser parser = new MetadataParser();
     parser.parseAnnotations(true);
-    parser.loadCoreVocabularies(true);
+    parser.useLocalCoreVocabularies(true);
     provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/annotations.xml"));
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
index 83160b4..8afe5d2 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserTest.java
@@ -54,7 +54,6 @@ public class MetadataParserTest {
   @Before
   public void setUp() throws Exception {
     MetadataParser parser = new MetadataParser();
-    parser.parseAnnotations(true);
     provider = (CsdlEdmProvider) parser.buildEdmProvider(new FileReader("src/test/resources/trippin.xml"));
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
index 90ead94..ab4a62a 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/ServiceDispatcherTest.java
@@ -91,6 +91,9 @@ public class ServiceDispatcherTest {
   
   public void beforeTest(ServiceHandler serviceHandler) throws Exception {
     MetadataParser parser = new MetadataParser();
+    parser.parseAnnotations(true);
+    parser.useLocalCoreVocabularies(true);
+    parser.implicitlyLoadCoreVocabularies(true);
     ServiceMetadata metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
 
     File baseDir = new File(System.getProperty("java.io.tmpdir"));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
index 3beb274..ec0c7c7 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
@@ -114,20 +114,23 @@ public class TripPinServiceTest {
   }
 
   @Test
-  public void testEntitySet() throws Exception {
-    HttpRequest req = new HttpGet(baseURL+"/People");
-    req.setHeader("Content-Type", "application/json;odata.metadata=minimal");
+  public void testXMLInvalidChars() throws Exception {
+    HttpRequest req = new HttpGet(baseURL+"/Airlines('FM')");
+    req.setHeader("Accept", "application/xml");
 
     HttpResponse response = httpSend(req, 200);
-    JsonNode node = getJSONNode(response);
-
-    assertEquals("$metadata#People", node.get("@odata.context").asText());
-    assertEquals(baseURL+"/People?$skiptoken=8", node.get("@odata.nextLink").asText());
-
-    JsonNode person = ((ArrayNode)node.get("value")).get(0);
-    assertEquals("russellwhyte", person.get("UserName").asText());
+    String actual = IOUtils.toString(response.getEntity().getContent());
+    String expected = 
+        "<m:properties>"
+        +     "<d:AirlineCode>FM</d:AirlineCode>"
+        +     "<d:Name>Shanghai xxxAirlinexxx</d:Name>" 
+        +     "<d:Picture m:null=\"true\"/>" 
+        +  "</m:properties>"  
+        + "</a:content>"  
+        +"</a:entry>";
+    assertTrue(actual.endsWith(expected));
   }
-
+  
   @Test
   public void testReadEntitySetWithPaging() throws Exception {
     String url = baseURL+"/People";

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
index 06e498c..7ab019d 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServlet.java
@@ -51,7 +51,8 @@ public class TripPinServlet extends HttpServlet {
 
     try {
       parser.parseAnnotations(true);
-      parser.loadCoreVocabularies(true);
+      parser.useLocalCoreVocabularies(true);
+      parser.implicitlyLoadCoreVocabularies(true);
       metadata = parser.buildServiceMetadata(new FileReader("src/test/resources/trippin.xml"));
     } catch (XMLStreamException e) {
       throw new IOException(e);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/resources/airlines.json
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/airlines.json b/lib/server-core-ext/src/test/resources/airlines.json
index 1d93aa7..9019c97 100644
--- a/lib/server-core-ext/src/test/resources/airlines.json
+++ b/lib/server-core-ext/src/test/resources/airlines.json
@@ -10,7 +10,7 @@
       },
       {
          "AirlineCode":"FM",
-         "Name":"Shanghai Airline"
+         "Name":"Shanghai \u0000Airline\u0001"
       },
       {
          "AirlineCode":"MU",

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/resources/annotations.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/annotations.xml b/lib/server-core-ext/src/test/resources/annotations.xml
index 1c5281a..3c8570f 100644
--- a/lib/server-core-ext/src/test/resources/annotations.xml
+++ b/lib/server-core-ext/src/test/resources/annotations.xml
@@ -11,6 +11,9 @@
   language governing permissions and limitations under the License. -->
 <edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"
 	Version="4.0">
+  <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/os/vocabularies/Org.OData.Core.V1.xml">
+    <edmx:Include Alias="Core" Namespace="Org.OData.Core.V1" />
+  </edmx:Reference>	
 	<edmx:DataServices>
 		<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm"
 			Namespace="Org.OData.AnnoatationTest" Alias="test">

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core-ext/src/test/resources/trippin.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/resources/trippin.xml b/lib/server-core-ext/src/test/resources/trippin.xml
index 3266344..5970ea2 100644
--- a/lib/server-core-ext/src/test/resources/trippin.xml
+++ b/lib/server-core-ext/src/test/resources/trippin.xml
@@ -10,6 +10,9 @@
 	OF ANY KIND, either express or implied. See the License for the specific 
 	language governing permissions and limitations under the License. -->
 <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
+  <edmx:Reference Uri="org.apache.olingo.v1.xml">
+    <edmx:Include Alias="olingo-extensions" Namespace="org.apache.olingo.v1" />
+  </edmx:Reference>
 	<edmx:DataServices>
 		<Schema Namespace="Microsoft.OData.SampleService.Models.TripPin"
 			xmlns="http://docs.oasis-open.org/odata/ns/edm">
@@ -103,7 +106,7 @@
 						<EnumMember>Org.OData.Core.V1.Permission/Read</EnumMember>
 					</Annotation>
 				</Property>
-				<Property Name="Name" Type="Edm.String" Nullable="false" />
+				<Property Name="Name" Type="Edm.String" Nullable="false"/>
 				<Property Name="IataCode" Type="Edm.String" Nullable="false">
 					<Annotation Term="Org.OData.Core.V1.Immutable" Bool="true" />
 				</Property>
@@ -453,6 +456,7 @@
 				</Annotation>
 				<Annotation Term="Core.RequiresType" String="Edm.String" />
 			</Term>
+		 <Annotation Term="org.apache.olingo.v1.xml10-incompatible-char-replacement" String="xxx"/>
 		</Schema>
 	</edmx:DataServices>
 </edmx:Edmx>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 0057db4..a72e096 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -52,6 +52,7 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.ex.ODataErrorDetail;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
@@ -250,10 +251,10 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       }
 
       if (options == null) {
-        writeEntitySet(metadata, entityType, entitySet, null, null, writer);
+        writeEntitySet(metadata, entityType, entitySet, null, null, null, writer);
       } else {
         writeEntitySet(metadata, entityType, entitySet,
-            options.getExpand(), options.getSelect(), writer);
+            options.getExpand(), options.getSelect(), options.xml10InvalidCharReplacement(), writer);
       }
 
       writer.writeEndElement();
@@ -296,7 +297,9 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
       writeEntity(metadata, entityType, entity, contextURL,
           options == null ? null : options.getExpand(),
-          options == null ? null : options.getSelect(), writer, true);
+          options == null ? null : options.getSelect(),
+          options == null ? null : options.xml10InvalidCharReplacement(),
+          writer, true);
       writer.writeEndDocument();
 
       writer.flush();
@@ -336,15 +339,17 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   protected void writeEntitySet(final ServiceMetadata metadata, final EdmEntityType entityType,
       final EntityCollection entitySet, final ExpandOption expand, final SelectOption select,
-      final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
+      final String xml10InvalidCharReplacement,final XMLStreamWriter writer) 
+          throws XMLStreamException, SerializerException {
     for (final Entity entity : entitySet.getEntities()) {
-      writeEntity(metadata, entityType, entity, null, expand, select, writer, false);
+      writeEntity(metadata, entityType, entity, null, expand, select, xml10InvalidCharReplacement, writer, false);
     }
   }
 
   protected void writeEntity(final ServiceMetadata metadata, final EdmEntityType entityType,
       final Entity entity, final ContextURL contextURL, final ExpandOption expand,
-      final SelectOption select, final XMLStreamWriter writer, final boolean top)
+      final SelectOption select, final String xml10InvalidCharReplacement,
+      final XMLStreamWriter writer, final boolean top)
       throws XMLStreamException, SerializerException {
 
     writer.writeStartElement(ATOM, Constants.ATOM_ELEM_ENTRY, NS_ATOM);
@@ -397,7 +402,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     }
 
     EdmEntityType resolvedType = resolveEntityType(metadata, entityType, entity.getType());
-    writeNavigationProperties(metadata, resolvedType, entity, expand, writer);
+    writeNavigationProperties(metadata, resolvedType, entity, expand, xml10InvalidCharReplacement, writer);
 
     writer.writeStartElement(ATOM, Constants.ATOM_ELEM_CATEGORY, NS_ATOM);
     writer.writeAttribute(Constants.ATOM_ATTR_SCHEME, Constants.NS_SCHEME);
@@ -412,7 +417,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     }
 
     writer.writeStartElement(METADATA, Constants.PROPERTIES, NS_METADATA);
-    writeProperties(metadata, resolvedType, entity.getProperties(), select, writer);
+    writeProperties(metadata, resolvedType, entity.getProperties(), select, xml10InvalidCharReplacement, writer);
     writer.writeEndElement(); // properties
 
     if (!entityType.hasStream()) { // content
@@ -490,8 +495,8 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
   }
 
   protected void writeProperties(final ServiceMetadata metadata, final EdmStructuredType type,
-      final List<Property> properties, final SelectOption select, final XMLStreamWriter writer)
-      throws XMLStreamException, SerializerException {
+      final List<Property> properties, final SelectOption select, final String xml10InvalidCharReplacement, 
+      final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
     final boolean all = ExpandSelectHelper.isAll(select);
     final Set<String> selected = all ? new HashSet<String>() :
         ExpandSelectHelper.getSelectedPropertyNames(select.getSelectItems());
@@ -501,14 +506,15 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
         final Property property = findProperty(propertyName, properties);
         final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null :
             ExpandSelectHelper.getSelectedPaths(select.getSelectItems(), propertyName);
-        writeProperty(metadata, edmProperty, property, selectedPaths, writer);
+        writeProperty(metadata, edmProperty, property, selectedPaths, xml10InvalidCharReplacement, writer);
       }
     }
   }
 
   protected void writeNavigationProperties(final ServiceMetadata metadata,
       final EdmStructuredType type, final Linked linked, final ExpandOption expand,
-      final XMLStreamWriter writer) throws SerializerException, XMLStreamException {
+      final String xml10InvalidCharReplacement, final XMLStreamWriter writer) 
+          throws SerializerException, XMLStreamException {
     if (ExpandSelectHelper.hasExpand(expand)) {
       final boolean expandAll = ExpandSelectHelper.isExpandAll(expand);
       final Set<String> expanded = expandAll ? new HashSet<String>() :
@@ -529,7 +535,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
             writeExpandedNavigationProperty(metadata, property, navigationLink,
                 innerOptions == null ? null : innerOptions.getExpandOption(),
                 innerOptions == null ? null : innerOptions.getSelectOption(),
-                writer);
+                    xml10InvalidCharReplacement, writer);
             writer.writeEndElement();
             writer.writeEndElement();
           }
@@ -588,27 +594,28 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   protected void writeExpandedNavigationProperty(final ServiceMetadata metadata,
       final EdmNavigationProperty property, final Link navigationLink,
-      final ExpandOption innerExpand, final SelectOption innerSelect, final XMLStreamWriter writer)
-      throws XMLStreamException, SerializerException {
+      final ExpandOption innerExpand, final SelectOption innerSelect, final String xml10InvalidCharReplacement,
+      final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
     if (property.isCollection()) {
       if (navigationLink != null && navigationLink.getInlineEntitySet() != null) {
         writer.writeStartElement(ATOM, Constants.ATOM_ELEM_FEED, NS_ATOM);
         writeEntitySet(metadata, property.getType(), navigationLink.getInlineEntitySet(), innerExpand,
-            innerSelect, writer);
+            innerSelect, xml10InvalidCharReplacement, writer);
         writer.writeEndElement();
       }
     } else {
       if (navigationLink != null && navigationLink.getInlineEntity() != null) {
         writeEntity(metadata, property.getType(), navigationLink.getInlineEntity(), null,
-            innerExpand, innerSelect, writer, false);
+            innerExpand, innerSelect, xml10InvalidCharReplacement, writer, false);
       }
     }
   }
 
-  protected void writeProperty(final ServiceMetadata metadata, final EdmProperty edmProperty,
-      final Property property,
-      final Set<List<String>> selectedPaths, final XMLStreamWriter writer) throws XMLStreamException,
-      SerializerException {
+  protected void writeProperty(final ServiceMetadata metadata,
+      final EdmProperty edmProperty, final Property property,
+      final Set<List<String>> selectedPaths,
+      final String xml10InvalidCharReplacement, final XMLStreamWriter writer)
+      throws XMLStreamException, SerializerException {
     writer.writeStartElement(DATA, edmProperty.getName(), NS_DATA);
     if (property == null || property.isNull()) {
       if (edmProperty.isNullable()) {
@@ -618,7 +625,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
             SerializerException.MessageKeys.MISSING_PROPERTY, edmProperty.getName());
       }
     } else {
-      writePropertyValue(metadata, edmProperty, property, selectedPaths, writer);
+      writePropertyValue(metadata, edmProperty, property, selectedPaths, xml10InvalidCharReplacement, writer);
     }
     writer.writeEndElement();
   }
@@ -642,9 +649,11 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     return definedType;
   }
 
-  private void writePropertyValue(final ServiceMetadata metadata, final EdmProperty edmProperty,
-      final Property property, final Set<List<String>> selectedPaths,
-      final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
+  private void writePropertyValue(final ServiceMetadata metadata,
+      final EdmProperty edmProperty, final Property property,
+      final Set<List<String>> selectedPaths,
+      final String xml10InvalidCharReplacement, final XMLStreamWriter writer)
+      throws XMLStreamException, SerializerException {
     try {
       if (edmProperty.isPrimitive()
           || edmProperty.getType().getKind() == EdmTypeKind.ENUM
@@ -657,22 +666,23 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
           writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
               edmProperty.isNullable(), edmProperty.getMaxLength(),
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
-              writer);
+              xml10InvalidCharReplacement,writer);
         } else {
           writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
               edmProperty.isNullable(), edmProperty.getMaxLength(),
               edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
-              writer);
+              xml10InvalidCharReplacement, writer);
         }
       } else if (property.isComplex()) {
         if (edmProperty.isCollection()) {
           writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE, collectionType(edmProperty.getType()));
-          writeComplexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, selectedPaths, writer);
+          writeComplexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, selectedPaths, 
+              xml10InvalidCharReplacement, writer);
         } else {
           writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
               "#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
           writeComplexValue(metadata, property, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
-              selectedPaths, writer);
+              selectedPaths, xml10InvalidCharReplacement, writer);
         }
       } else {
         throw new SerializerException("Property type not yet supported!",
@@ -687,14 +697,15 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   private void writePrimitiveCollection(final EdmPrimitiveType type, final Property property,
       final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
-      final Boolean isUnicode,
+      final Boolean isUnicode, final String xml10InvalidCharReplacement,
       final XMLStreamWriter writer) throws XMLStreamException, EdmPrimitiveTypeException, SerializerException {
     for (Object value : property.asCollection()) {
       writer.writeStartElement(METADATA, Constants.ELEM_ELEMENT, NS_METADATA);
       switch (property.getValueType()) {
       case COLLECTION_PRIMITIVE:
       case COLLECTION_ENUM:
-        writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, writer);
+        writePrimitiveValue(type, value, isNullable, maxLength, precision,
+            scale, isUnicode, xml10InvalidCharReplacement, writer);
         break;
       case COLLECTION_GEOSPATIAL:
         throw new SerializerException("Property type not yet supported!",
@@ -707,8 +718,9 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     }
   }
 
-  private void writeComplexCollection(final ServiceMetadata metadata, final EdmComplexType type,
-      final Property property, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
+  private void writeComplexCollection(final ServiceMetadata metadata,
+      final EdmComplexType type, final Property property, final Set<List<String>> selectedPaths,
+      final String xml10InvalidCharReplacement, final XMLStreamWriter writer)
       throws XMLStreamException, SerializerException {
     for (Object value : property.asCollection()) {
       writer.writeStartElement(METADATA, Constants.ELEM_ELEMENT, NS_METADATA);
@@ -717,7 +729,9 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       }
       switch (property.getValueType()) {
       case COLLECTION_COMPLEX:
-        writeComplexValue(metadata, property, type, ((ComplexValue) value).getValue(), selectedPaths, writer);
+        writeComplexValue(metadata, property, type,
+            ((ComplexValue) value).getValue(), selectedPaths,
+            xml10InvalidCharReplacement, writer);
         break;
       default:
         throw new SerializerException("Property type not yet supported!",
@@ -729,7 +743,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   private void writePrimitive(final EdmPrimitiveType type, final Property property,
       final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
-      final Boolean isUnicode, final XMLStreamWriter writer)
+      final Boolean isUnicode, final String xml10InvalidCharReplacement, final XMLStreamWriter writer)
       throws EdmPrimitiveTypeException, XMLStreamException, SerializerException {
     if (property.isPrimitive()) {
       if (type != EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.String)) {
@@ -739,7 +753,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
                 type.getName());
       }
       writePrimitiveValue(type, property.asPrimitive(),
-          isNullable, maxLength, precision, scale, isUnicode, writer);
+          isNullable, maxLength, precision, scale, isUnicode, xml10InvalidCharReplacement, writer);
     } else if (property.isGeospatial()) {
       throw new SerializerException("Property type not yet supported!",
           SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
@@ -747,7 +761,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
           "#" + type.getFullQualifiedName().getFullQualifiedNameAsString());
       writePrimitiveValue(type, property.asEnum(),
-          isNullable, maxLength, precision, scale, isUnicode, writer);
+          isNullable, maxLength, precision, scale, isUnicode, xml10InvalidCharReplacement, writer);
     } else {
       throw new SerializerException("Inconsistent property type!",
           SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, property.getName());
@@ -756,19 +770,23 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   protected void writePrimitiveValue(final EdmPrimitiveType type, final Object primitiveValue,
       final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
-      final Boolean isUnicode,
+      final Boolean isUnicode, final String xml10InvalidCharReplacement,
       final XMLStreamWriter writer) throws EdmPrimitiveTypeException, XMLStreamException {
     final String value = type.valueToString(primitiveValue,
         isNullable, maxLength, precision, scale, isUnicode);
     if (value == null) {
       writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
     } else {
-      writer.writeCharacters(value);
+      // XML 1.0 does not handle certain unicode characters, they need to be replaced
+      writer.writeCharacters(replaceInvalidCharacters(type, value,
+          isUnicode, xml10InvalidCharReplacement));
     }
   }
 
-  protected void writeComplexValue(final ServiceMetadata metadata, Property complexProperty, final EdmComplexType type,
-      final List<Property> properties, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
+  protected void writeComplexValue(final ServiceMetadata metadata,
+      Property complexProperty, final EdmComplexType type,
+      final List<Property> properties, final Set<List<String>> selectedPaths,
+      final String xml10InvalidCharReplacement, final XMLStreamWriter writer)
       throws XMLStreamException, SerializerException {
 
     final EdmComplexType resolvedType = resolveComplexType(metadata,
@@ -779,7 +797,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
         writeProperty(metadata, (EdmProperty) resolvedType.getProperty(propertyName), property,
             selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
-            writer);
+            xml10InvalidCharReplacement, writer);
       }
     }
   }
@@ -822,6 +840,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
             options == null ? null : options.getPrecision(),
             options == null ? null : options.getScale(),
             options == null ? null : options.isUnicode(),
+            options == null ? null : options.xml10InvalidCharReplacement(),
             writer);
       }
       writer.writeEndElement();
@@ -874,7 +893,10 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
         writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_NULL, "true");
       } else {
         final List<Property> values = property.asComplex().getValue();
-        writeProperties(metadata, resolvedType, values, options == null ? null : options.getSelect(), writer);
+        writeProperties(metadata, resolvedType, values, 
+            options == null ? null : options.getSelect(),
+            options == null ? null : options.xml10InvalidCharReplacement(),
+            writer);
       }
       writer.writeEndDocument();
       writer.flush();
@@ -922,6 +944,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
           options == null ? null : options.getPrecision(),
           options == null ? null : options.getScale(),
           options == null ? null : options.isUnicode(),
+          options == null ? null : options.xml10InvalidCharReplacement(),
           writer);
       writer.writeEndElement();
       writer.writeEndDocument();
@@ -967,7 +990,8 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
           ContextURLBuilder.create(contextURL).toASCIIString());
       writeMetadataETag(metadata, writer);
-      writeComplexCollection(metadata, type, property, null, writer);
+      writeComplexCollection(metadata, type, property, null, 
+          options == null ? null:options.xml10InvalidCharReplacement(), writer);
       writer.writeEndElement();
       writer.writeEndDocument();
       writer.flush();
@@ -1104,4 +1128,30 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     writer.writeAttribute(Constants.ATTR_HREF, entitySet.getNext().toASCIIString());
     writer.writeEndElement();
   }
+  
+  static String replaceInvalidCharacters(EdmPrimitiveType expectedType,
+      String value, Boolean isUniCode, String invalidCharacterReplacement) {
+    if (!(expectedType instanceof EdmString)
+        || invalidCharacterReplacement == null || isUniCode == null || !isUniCode) {
+      return value;
+    }
+    String s = (String) value;
+    StringBuilder result = null;
+    for (int i = 0; i < s.length(); i++) {
+      char c = s.charAt(i);
+      if (c <= 0x0020 && c != ' ' && c != '\n' && c != '\t' && c != '\r') {
+        if (result == null) {
+          result = new StringBuilder();
+          result.append(s.substring(0, i));
+        }
+        result.append(invalidCharacterReplacement);
+      } else if (result != null) {
+        result.append(c);
+      }
+    }
+    if (result == null) {
+      return value;
+    }
+    return result.toString();
+  }  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d880d6c4/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
index c904ea7..07b5e56 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
@@ -1796,6 +1796,30 @@ public class ODataXmlSerializerTest {
   }
 
   @Test
+  public void testXML10ReplacementChar() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
+    final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
+    property.setValue(ValueType.PRIMITIVE, "ab\u0000cd\u0001");
+    final String resultString = IOUtils.toString(serializer
+        .primitive(metadata, (EdmPrimitiveType) edmProperty.getType(), property,
+            PrimitiveSerializerOptions.with()
+                .contextURL(ContextURL.with()
+                    .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
+                    .build())
+                .xml10InvalidCharReplacement("XX")
+                .unicode(Boolean.TRUE)
+                .build()).getContent());
+
+    String expected = "<?xml version='1.0' encoding='UTF-8'?>"
+        + "<m:value xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" "
+        + "m:context=\"$metadata#ESAllPrim(32767)/PropertyString\" "
+        + "m:metadata-etag=\"metadataETag\">"
+        + "abXXcdXX</m:value>";
+    Assert.assertEquals(expected, resultString);
+  }
+  
+  @Test
   public void primitivePropertyNull() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
@@ -1966,8 +1990,7 @@ public class ODataXmlSerializerTest {
     XMLAssert.assertXMLEqual(diff, true);
   }
   
-  private static class CustomDifferenceListener implements DifferenceListener {
-
+  public static class CustomDifferenceListener implements DifferenceListener {
     @Override
     public int differenceFound(Difference difference) {
       final String xpath = "/updated[1]/text()[1]";


[4/4] olingo-odata4 git commit: [OLINGO-832] Merge branch 'master' into OLINGO-832_StreamSerializerPoC

Posted by mi...@apache.org.
[OLINGO-832] Merge branch 'master' into OLINGO-832_StreamSerializerPoC


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/396a39ba
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/396a39ba
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/396a39ba

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 396a39baec9539249dcfa4b111e87c037cb6fb64
Parents: 5b6cccf d040afe
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Feb 19 09:39:49 2016 +0100
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Feb 19 09:39:49 2016 +0100

----------------------------------------------------------------------
 .../core/edm/annotation/EdmRecordImpl.java      |  16 +-
 .../core/edm/annotations/EdmRecordImplTest.java |   6 -
 .../core/edm/primitivetype/EdmDateTest.java     |  16 +-
 .../serializer/ComplexSerializerOptions.java    |  14 +-
 .../EntityCollectionSerializerOptions.java      |  11 +
 .../api/serializer/EntitySerializerOptions.java |  14 +-
 .../serializer/PrimitiveSerializerOptions.java  |  13 +
 .../PrimitiveValueSerializerOptions.java        |  14 +-
 .../olingo/server/core/MetadataParser.java      | 262 ++++++++++++++-----
 .../server/core/SchemaBasedEdmProvider.java     | 117 ++++-----
 .../olingo/server/core/ServiceRequest.java      |  50 +++-
 .../server/core/requests/DataRequest.java       |  13 +-
 .../src/main/resources/org.apache.olingo.v1.xml |  40 +++
 .../core/MetadataParserAnnotationsTest.java     |  10 +-
 .../olingo/server/core/MetadataParserTest.java  |   1 -
 .../server/core/ServiceDispatcherTest.java      |   3 +
 .../olingo/server/example/TripPinHandler.java   |   1 +
 .../server/example/TripPinServiceTest.java      |  30 ++-
 .../olingo/server/example/TripPinServlet.java   |   3 +-
 .../src/test/resources/airlines.json            |   2 +-
 .../src/test/resources/annotations.xml          |  17 ++
 .../src/test/resources/trippin.xml              |   6 +-
 .../xml/MetadataDocumentXmlSerializer.java      |   5 +-
 .../core/serializer/xml/ODataXmlSerializer.java | 138 ++++++----
 .../serializer/xml/ODataXmlSerializerTest.java  |  27 +-
 25 files changed, 606 insertions(+), 223 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/396a39ba/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
----------------------------------------------------------------------
diff --cc lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
index 6f4ed2d,9ee7d24..9335829
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
@@@ -33,7 -32,7 +33,8 @@@ public class EntityCollectionSerializer
    private SelectOption select;
    private boolean writeOnlyReferences;
    private String id;
 +  private WriteContentErrorCallback writeContentErrorCallback;
+   private String xml10InvalidCharReplacement;
  
    /** Gets the {@link ContextURL}. */
    public ContextURL getContextURL() {
@@@ -65,17 -64,10 +66,21 @@@
      return id;
    }
  
 +  /**
 +   * Gets the callback which is used in case of an exception during
 +   * write of the content (in case the content will be written/streamed
 +   * in the future)
 +   * @return callback which is used in case of an exception during
 +   * write of the content
 +   *
 +   */
 +  public WriteContentErrorCallback getWriteContentErrorCallback() {
 +    return writeContentErrorCallback;
 +  }
+   /** Gets the replacement string for unicode characters, that is not allowed in XML 1.0 */
+   public String xml10InvalidCharReplacement() {
+     return xml10InvalidCharReplacement;
+   }  
  
    /** Initializes the options builder. */
    public static Builder with() {
@@@ -126,19 -118,13 +131,25 @@@
        options.id = id;
        return this;
      }
 -    
 +
 +    /**
 +     * Set the callback which is used in case of an exception during
 +     * write of the content.
 +     *
 +     * @param writeContentErrorCallback the callback
 +     * @return the builder
 +     */
 +    public Builder writeContentErrorCallback(WriteContentErrorCallback writeContentErrorCallback) {
 +      options.writeContentErrorCallback = writeContentErrorCallback;
 +      return this;
 +    }
 +
+     /** set the replacement String for xml 1.0 unicode controlled characters that are not allowed */
+     public Builder xml10InvalidCharReplacement(final String replacement) {
+       options.xml10InvalidCharReplacement = replacement;
+       return this;
+     } 
+     
      /** Builds the OData serializer options. */
      public EntityCollectionSerializerOptions build() {
        return options;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/396a39ba/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 1a07faa,a72e096..a42e3df
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@@ -53,8 -51,8 +53,9 @@@ import org.apache.olingo.commons.api.ed
  import org.apache.olingo.commons.api.edm.FullQualifiedName;
  import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
  import org.apache.olingo.commons.api.ex.ODataErrorDetail;
 +import org.apache.olingo.commons.api.ex.ODataRuntimeException;
  import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+ import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
  import org.apache.olingo.server.api.ODataServerError;
  import org.apache.olingo.server.api.ServiceMetadata;
  import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
@@@ -345,10 -338,11 +348,11 @@@ public class ODataXmlSerializer extend
    }
  
    protected void writeEntitySet(final ServiceMetadata metadata, final EdmEntityType entityType,
 -      final EntityCollection entitySet, final ExpandOption expand, final SelectOption select,
 +      final AbstractEntityCollection entitySet, final ExpandOption expand, final SelectOption select,
-       final XMLStreamWriter writer) throws XMLStreamException, SerializerException {
+       final String xml10InvalidCharReplacement,final XMLStreamWriter writer) 
+           throws XMLStreamException, SerializerException {
 -    for (final Entity entity : entitySet.getEntities()) {
 +    for (final Entity entity : entitySet) {
-       writeEntity(metadata, entityType, entity, null, expand, select, writer, false);
+       writeEntity(metadata, entityType, entity, null, expand, select, xml10InvalidCharReplacement, writer, false);
      }
    }
  


[3/4] olingo-odata4 git commit: [OLINGO-887] Set timezone fix for testing

Posted by mi...@apache.org.
[OLINGO-887] Set timezone fix for testing


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/d040afe7
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/d040afe7
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/d040afe7

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: d040afe78456b14632b9cefa46441830310f7d6c
Parents: a8d1d4c
Author: Christian Amend <ch...@sap.com>
Authored: Wed Feb 17 14:48:02 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Wed Feb 17 14:48:02 2016 +0100

----------------------------------------------------------------------
 .../commons/core/edm/primitivetype/EdmDateTest.java | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d040afe7/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
index e3f4c99..fad0aba 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java
@@ -6,9 +6,9 @@
  * 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
@@ -26,12 +26,24 @@ import java.util.TimeZone;
 
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 public class EdmDateTest extends PrimitiveTypeBaseTest {
 
   private final EdmPrimitiveType instance = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date);
 
+  @Before
+  public void setup() {
+    TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+  }
+
+  @After
+  public void teardown() {
+    TimeZone.setDefault(null);
+  }
+
   @Test
   public void toUriLiteral() throws Exception {
     assertEquals("2009-12-26", instance.toUriLiteral("2009-12-26"));


[2/4] olingo-odata4 git commit: OLINGO-878: Adding support to remove invalid xml characters from Atom payload

Posted by mi...@apache.org.
OLINGO-878: Adding support to remove invalid xml characters from Atom payload


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/a8d1d4c6
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/a8d1d4c6
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/a8d1d4c6

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: a8d1d4c647225671dc45f0297789e7a5b45479f0
Parents: 3c205f9 d880d6c
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Fri Feb 12 19:44:36 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Feb 15 12:31:34 2016 -0600

----------------------------------------------------------------------
 .../core/edm/annotation/EdmRecordImpl.java      |  16 +-
 .../core/edm/annotations/EdmRecordImplTest.java |   6 -
 .../serializer/ComplexSerializerOptions.java    |  14 +-
 .../EntityCollectionSerializerOptions.java      |  14 +-
 .../api/serializer/EntitySerializerOptions.java |  14 +-
 .../serializer/PrimitiveSerializerOptions.java  |  13 +
 .../PrimitiveValueSerializerOptions.java        |  14 +-
 .../olingo/server/core/MetadataParser.java      | 262 ++++++++++++++-----
 .../server/core/SchemaBasedEdmProvider.java     | 117 ++++-----
 .../olingo/server/core/ServiceRequest.java      |  50 +++-
 .../server/core/requests/DataRequest.java       |  13 +-
 .../src/main/resources/org.apache.olingo.v1.xml |  40 +++
 .../core/MetadataParserAnnotationsTest.java     |  10 +-
 .../olingo/server/core/MetadataParserTest.java  |   1 -
 .../server/core/ServiceDispatcherTest.java      |   3 +
 .../olingo/server/example/TripPinHandler.java   |   1 +
 .../server/example/TripPinServiceTest.java      |  30 ++-
 .../olingo/server/example/TripPinServlet.java   |   3 +-
 .../src/test/resources/airlines.json            |   2 +-
 .../src/test/resources/annotations.xml          |  17 ++
 .../src/test/resources/trippin.xml              |   6 +-
 .../xml/MetadataDocumentXmlSerializer.java      |   5 +-
 .../core/serializer/xml/ODataXmlSerializer.java | 138 ++++++----
 .../serializer/xml/ODataXmlSerializerTest.java  |  27 +-
 24 files changed, 594 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/EdmRecordImpl.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/EdmRecordImpl.java
index 919f189,919f189..811f82b
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/EdmRecordImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/annotation/EdmRecordImpl.java
@@@ -59,14 -59,14 +59,14 @@@ public class EdmRecordImpl extends Abst
    @Override
    public EdmStructuredType getType() {
      if (type == null) {
--      if (record.getType() == null) {
--        throw new EdmException("Must specify a type for a Record expression.");
--      }
--      final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(record.getType()).build();
--      if (typeInfo.isEntityType() || typeInfo.isComplexType()) {
--        type = typeInfo.isEntityType() ? typeInfo.getEntityType() : typeInfo.getComplexType();
--      } else {
--        throw new EdmException("Record expressions must specify a complex or entity type.");
++      // record MAY have a type information.
++      if (record.getType() != null) {
++        final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(record.getType()).build();
++        if (typeInfo.isEntityType() || typeInfo.isComplexType()) {
++          type = typeInfo.isEntityType() ? typeInfo.getEntityType() : typeInfo.getComplexType();
++        } else {
++          throw new EdmException("Record expressions must specify a complex or entity type.");
++        }
        }
      }
      return type;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/annotations/EdmRecordImplTest.java
----------------------------------------------------------------------
diff --cc lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/annotations/EdmRecordImplTest.java
index ddae8bc,ddae8bc..8076ffb
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/annotations/EdmRecordImplTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/annotations/EdmRecordImplTest.java
@@@ -63,12 -63,12 +63,6 @@@ public class EdmRecordImplTest extends 
      assertSingleKindDynamicExpression(dynExp);
  
      EdmRecord asRecord = dynExp.asRecord();
--    try {
--      asRecord.getType();
--      fail("EdmException expected");
--    } catch (EdmException e) {
--      assertEquals("Must specify a type for a Record expression.", e.getMessage());
--    }
  
      assertNotNull(asRecord.getAnnotations());
      assertTrue(asRecord.getAnnotations().isEmpty());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
index 03a6675,b93ef4c..c47aa52
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@@ -191,8 -304,9 +304,8 @@@ public class MetadataParser 
    }  
    
    private void readDataServicesAndReference(XMLEventReader reader,
-       StartElement element, SchemaBasedEdmProvider provider) throws XMLStreamException {
-     final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
+       StartElement element, SchemaBasedEdmProvider provider)
+       throws XMLStreamException {
 -    final ArrayList<EdmxReference> references = new ArrayList<EdmxReference>();
      new ElementReader<SchemaBasedEdmProvider>() {
        @Override
        void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
@@@ -200,15 -314,15 +313,14 @@@
          if (name.equals("DataServices")) {
            readSchema(reader, element, provider);
          } else if (name.equals("Reference")) {
--          readReference(reader, element, references, "Reference");
++          readReference(reader, element, provider, "Reference");
          }
        }
      }.read(reader, element, provider, "DataServices", "Reference");
--    provider.addReferences(references);
    }
  
    private void readReference(XMLEventReader reader, StartElement element,
--      final ArrayList<EdmxReference> references, String name) throws XMLStreamException {
++      final SchemaBasedEdmProvider provider, String name) throws XMLStreamException {
      EdmxReference reference;
      try {
        String uri = attr(element, "Uri");
@@@ -235,7 -349,7 +347,7 @@@
          }
        }
      }.read(reader, element, reference, "Include", "IncludeAnnotations", "Annotation");
--    references.add(reference);
++    provider.addReference(reference);
    }
    
    private void readSchema(XMLEventReader reader, StartElement element,
@@@ -447,7 -563,7 +561,7 @@@
      final CsdlAnnotations annotations = new CsdlAnnotations();
      annotations.setTarget(attr(element, "Target"));
      annotations.setQualifier(attr(element, "Qualifier"));
--    readAnnotations(reader, element, annotations);
++    peekAnnotations(reader, element.getName().getLocalPart(), annotations);
      schema.getAnnotationGroups().add(annotations);
    }
  
@@@ -540,24 -656,24 +654,8 @@@
        void build(XMLEventReader reader, StartElement element, T target, String name)
            throws XMLStreamException {
          
--        // attribute based expressions        
--        if (attr(element,  "AnnotationPath") != null) {
--         write(target, new CsdlAnnotationPath().setValue(attr(element,  "AnnotationPath"))); 
--        }
--        if (attr(element,  "NavigationPropertyPath") != null) {
--          write(target, new CsdlNavigationPropertyPath()
--              .setValue(attr(element, "NavigationPropertyPath"))); 
--        }
--        if (attr(element,  "Path") != null) {
--          write(target, new CsdlPath().setValue(attr(element, "Path"))); 
--        }
--        if (attr(element,  "PropertyPath") != null) {
--          write(target, new CsdlPropertyPath().setValue(attr(element, "PropertyPath"))); 
--        }
--        if (attr(element,  "UrlRef") != null) {
--          write(target, new CsdlUrlRef().setValue(new CsdlConstantExpression(
--              ConstantExpressionType.String, attr(element, "UrlRef"))));
--        }        
++        // attribute based expressions.
++        readAttributeExpressions(element, target);        
  
          // element based expressions
          for (ConstantExpressionType type:ConstantExpressionType.values()) {
@@@ -567,7 -683,7 +665,8 @@@
                write(target, expr);
              }
            }        
--        }        
++        }
++        
          if (name.equals("Collection")) {
            CsdlCollection expr = new CsdlCollection();
            readExpressions(reader, element, expr);
@@@ -630,6 -746,6 +729,35 @@@
          "Int", "String", "TimeOfDay");
    }
    
++  private <T> void readAttributeExpressions(StartElement element, T target)
++      throws XMLStreamException {
++    // attribute based expressions
++    for (ConstantExpressionType type:ConstantExpressionType.values()) {
++      if (attr(element, type.name()) != null) {
++        write(target, new CsdlConstantExpression(
++            type, attr(element, type.name())));
++      }        
++    }
++    
++    if (attr(element,  "AnnotationPath") != null) {
++     write(target, new CsdlAnnotationPath().setValue(attr(element,  "AnnotationPath"))); 
++    }
++    if (attr(element,  "NavigationPropertyPath") != null) {
++      write(target, new CsdlNavigationPropertyPath()
++          .setValue(attr(element, "NavigationPropertyPath"))); 
++    }
++    if (attr(element,  "Path") != null) {
++      write(target, new CsdlPath().setValue(attr(element, "Path"))); 
++    }
++    if (attr(element,  "PropertyPath") != null) {
++      write(target, new CsdlPropertyPath().setValue(attr(element, "PropertyPath"))); 
++    }
++    if (attr(element,  "UrlRef") != null) {
++      write(target, new CsdlUrlRef().setValue(new CsdlConstantExpression(
++          ConstantExpressionType.String, attr(element, "UrlRef"))));
++    }
++  }  
++  
    private String elementValue(XMLEventReader reader, StartElement element) throws XMLStreamException {
      while (reader.hasNext()) {
        XMLEvent event = reader.peek();
@@@ -655,6 -771,6 +783,7 @@@
            throws XMLStreamException {
          CsdlPropertyValue value = new CsdlPropertyValue();
          value.setProperty(attr(element, "Property"));
++        readAttributeExpressions(element, value);
          readExpressions(reader, element, value);
          record.getPropertyValues().add(value);
        }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
index a778e2c,8aea555..a6445a7
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/SchemaBasedEdmProvider.java
@@@ -68,7 -60,23 +60,29 @@@ public class SchemaBasedEdmProvider imp
    List<EdmxReference> getReferences(){
      return new ArrayList<EdmxReference>(references.values());
    }
- 
+   
+   void addReferenceSchema(String ns, SchemaBasedEdmProvider provider) {
+     this.referenceSchemas.put(ns, provider);
+   }  
+   
+   void addVocabularySchema(String ns, SchemaBasedEdmProvider provider) {
+     this.coreVocabularySchemas.put(ns, provider);
+   }
+   
++  void addReference(EdmxReference reference) {
++    for (EdmxReferenceInclude include : reference.getIncludes()) {
++      this.references.put(include.getNamespace(), reference);
++    }
++  }  
++  
+   CsdlSchema getVocabularySchema(String ns) {
+     SchemaBasedEdmProvider provider = this.coreVocabularySchemas.get(ns);
+     if (provider != null) {
+       return provider.getSchema(ns, false);
+     }
+     return null;
+   }
+   
    CsdlSchema getSchema(String ns) {
      return getSchema(ns, true);
    }  
@@@ -315,6 -297,6 +303,16 @@@
          }
        }
      }
++    for (SchemaBasedEdmProvider p:this.coreVocabularySchemas.values()) {
++      for (CsdlSchema s:p.getSchemas()) {
++        if (s.getAlias() != null) {
++          CsdlAliasInfo ai = new CsdlAliasInfo();
++          ai.setAlias(s.getAlias());
++          ai.setNamespace(s.getNamespace());
++          list.add(ai);
++        }        
++      }
++    }
      return list;
    }
  
@@@ -386,31 -368,21 +384,8 @@@
    public CsdlAnnotations getAnnotationsGroup(FullQualifiedName targetName, String qualifier) throws ODataException {
      CsdlSchema schema = getSchema(targetName.getNamespace());
      if (schema != null) {
--      return schema.getAnnotationGroup(targetName.getName(), qualifier);
++      return schema.getAnnotationGroup(targetName.getFullQualifiedNameAsString(), qualifier);
      }
      return null;
--  }
--
--  void addReferences(ArrayList<EdmxReference> references) {
--    if (references != null && !references.isEmpty()) {
--      for (EdmxReference ref:references) {
--        for (EdmxReferenceInclude include : ref.getIncludes()) {
--          if (include.getAlias() != null) {
--            this.references.put(include.getAlias(), ref);
--          }
--          this.references.put(include.getNamespace(), ref);
--        }
-       }
-     }
-   }
- 
-   public void setXMLBase(String base) {
-     if (base != null) {
-       if (base.endsWith("/")) {
-         this.xmlBase = base;
-       } else {
-         this.xmlBase = base+"/";
--      }
--    }
    } 
  }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
index d71c54d,75c12ad..0c6288a
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/core/MetadataParserAnnotationsTest.java
@@@ -27,6 -27,6 +27,7 @@@ import java.util.Arrays
  
  import org.apache.olingo.commons.api.edm.FullQualifiedName;
  import org.apache.olingo.commons.api.edm.provider.CsdlAnnotation;
++import org.apache.olingo.commons.api.edm.provider.CsdlAnnotations;
  import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
  import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
  import org.apache.olingo.commons.api.edm.provider.CsdlTerm;
@@@ -211,5 -211,5 +212,12 @@@ public class MetadataParserAnnotationsT
    public void checkCoreVocabularies() throws ODataException {
      CsdlTerm term = this.provider.getTerm(new FullQualifiedName("Org.OData.Core.V1", "Description"));
      assertEquals("Edm.String", term.getType());
++  }
++  
++  @Test
++  public void testAnnotationGroup() throws ODataException {
++    CsdlAnnotations annotations = this.provider.getAnnotationsGroup(
++        new FullQualifiedName("Org.OData.AnnoatationTest.TagX"), null);
++    assertEquals(3, annotations.getAnnotations().size());
    }  
  }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
index 4d2dbb9,4d2dbb9..c2ca7a6
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
@@@ -566,6 -566,6 +566,7 @@@ public class TripPinHandler implements 
    
    @Override
    public void processError(ODataServerError error, ErrorResponse response) {
++    error.getException().printStackTrace();
      response.writeError(error);
    }
  }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
index 3beb274,ec0c7c7..114a1f3
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinServiceTest.java
@@@ -114,21 -114,24 +114,31 @@@ public class TripPinServiceTest 
    }
  
    @Test
-   public void testEntitySet() throws Exception {
-     HttpRequest req = new HttpGet(baseURL+"/People");
-     req.setHeader("Content-Type", "application/json;odata.metadata=minimal");
+   public void testXMLInvalidChars() throws Exception {
+     HttpRequest req = new HttpGet(baseURL+"/Airlines('FM')");
+     req.setHeader("Accept", "application/xml");
  
      HttpResponse response = httpSend(req, 200);
-     JsonNode node = getJSONNode(response);
- 
-     assertEquals("$metadata#People", node.get("@odata.context").asText());
-     assertEquals(baseURL+"/People?$skiptoken=8", node.get("@odata.nextLink").asText());
- 
-     JsonNode person = ((ArrayNode)node.get("value")).get(0);
-     assertEquals("russellwhyte", person.get("UserName").asText());
+     String actual = IOUtils.toString(response.getEntity().getContent());
+     String expected = 
+         "<m:properties>"
+         +     "<d:AirlineCode>FM</d:AirlineCode>"
+         +     "<d:Name>Shanghai xxxAirlinexxx</d:Name>" 
+         +     "<d:Picture m:null=\"true\"/>" 
+         +  "</m:properties>"  
+         + "</a:content>"  
+         +"</a:entry>";
+     assertTrue(actual.endsWith(expected));
    }
 +
 +  @Test
++  public void testmetadata() throws Exception {
++    HttpRequest req = new HttpGet(baseURL+"/$metadata");
++    HttpResponse response = httpSend(req, 200);
++    IOUtils.toString(response.getEntity().getContent());
++  }
+   
+   @Test
    public void testReadEntitySetWithPaging() throws Exception {
      String url = baseURL+"/People";
      HttpRequest request = new HttpGet(url);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core-ext/src/test/resources/annotations.xml
----------------------------------------------------------------------
diff --cc lib/server-core-ext/src/test/resources/annotations.xml
index 1c5281a,3c8570f..ca581f0
--- a/lib/server-core-ext/src/test/resources/annotations.xml
+++ b/lib/server-core-ext/src/test/resources/annotations.xml
@@@ -148,6 -151,6 +151,20 @@@
  					</Apply>
  				</UrlRef>
  			</Annotation>
++      <TypeDefinition Name="TagX" UnderlyingType="Edm.Boolean">
++        <Annotation Term="Core.Description" String="This is the type to use for all tagging terms" />
++      </TypeDefinition>			
++      <Annotations
++        Target="Org.OData.AnnoatationTest.TagX">
++        <Annotation Term="Org.OData.Core.V1.DereferenceableIDs"
++          Bool="true" />
++        <Annotation Term="Org.OData.Core.V1.ConventionalIDs"
++          Bool="true" />
++        <Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel">
++          <EnumMember>Org.OData.Capabilities.V1.ConformanceLevelType/Advanced
++          </EnumMember>
++        </Annotation>
++      </Annotations>			
  		</Schema>
  	</edmx:DataServices>
  </edmx:Edmx>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8d1d4c6/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
index a0fd021,a0fd021..55c7ede
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentXmlSerializer.java
@@@ -450,7 -450,7 +450,10 @@@ public class MetadataDocumentXmlSeriali
        break;
      case Record:
        EdmRecord asRecord = dynExp.asRecord();
--      writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(asRecord.getType(), false));
++      EdmStructuredType type = asRecord.getType();
++      if (type != null) {
++        writer.writeAttribute(XML_TYPE, getAliasedFullQualifiedName(type, false));
++      }
        for (EdmPropertyValue propValue : asRecord.getPropertyValues()) {
          writer.writeStartElement(XML_PROPERTY_Value);
          writer.writeAttribute(XML_PROPERTY, propValue.getProperty());