This commit is contained in:
Francesco Chicchiriccò 2014-07-10 17:18:58 +02:00
commit bc033b0f3b
15 changed files with 417 additions and 191 deletions

View File

@ -28,7 +28,6 @@ import org.apache.olingo.client.api.http.HttpClientException;
import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
import org.apache.olingo.commons.core.data.ODataErrorImpl;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,7 +39,7 @@ public abstract class AbstractRequest {
protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class); protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class);
private ODataError getGenericError(final int code, final String errorMsg) { private ODataError getGenericError(final int code, final String errorMsg) {
final ODataErrorImpl error = new ODataErrorImpl(); final ODataError error = new ODataError();
error.setCode(String.valueOf(code)); error.setCode(String.valueOf(code));
error.setMessage(errorMsg); error.setMessage(errorMsg);
return error; return error;

View File

@ -24,40 +24,109 @@ import java.util.Map;
/** /**
* OData error. * OData error.
*/ */
public interface ODataError { public class ODataError {
private String code;
private String message;
private String target;
private List<ODataErrorDetail> details;
private Map<String, String> innerError;
/** /**
* Gets error code. * The value for the code name/value pair is a language-independent string. Its value is a service-defined error code.
* * This code serves as a sub-status for the HTTP error code specified in the response. MAY be null.
* @return error code. * @return the error code as a string
*/ */
String getCode(); public String getCode() {
return code;
}
/** /**
* Gets error message. * The value for the code name/value pair is a language-independent string. Its value is a service-defined error code.
* * This code serves as a sub-status for the HTTP error code specified in the response. MAY be null.
* @return error message. * @param code
* @return this for method chaining
*/ */
String getMessage(); public ODataError setCode(String code) {
this.code = code;
return this;
}
/** /**
* Gets error target. * The value for the message name/value pair MUST be a human-readable, language-dependent representation of the error.
* * MUST not be null
* @return error message. * @return the message string
*/ */
String getTarget(); public String getMessage() {
return message;
}
/**
* The value for the message name/value pair MUST be a human-readable, language-dependent representation of the error.
* MUST not be null
* @param message
* @return this for method chaining
*/
public ODataError setMessage(String message) {
this.message = message;
return this;
}
/**
* The value for the target name/value pair is the target of the particular error (for example, the name of the
* property in error). MAY be null.
* @return the target string
*/
public String getTarget() {
return target;
}
/**
* The value for the target name/value pair is the target of the particular error (for example, the name of the
* property in error). MAY be null.
* @param target
* @return this for method chaining
*/
public ODataError setTarget(String target) {
this.target = target;
return this;
}
/** /**
* Gets error details. * Gets error details.
* *
* @return ODataErrorDetail list. * @return ODataErrorDetail list.
*/ */
List<ODataErrorDetail> getDetails(); public List<ODataErrorDetail> getDetails() {
return details;
}
/**
* Sets error details.
*
* @return this for method chaining.
*/
public ODataError setDetails(List<ODataErrorDetail> details) {
this.details = details;
return this;
}
/** /**
* Gets server defined key-value pairs for debug environment only. * Gets server defined key-value pairs for debug environment only.
* *
* @return a pair representing server defined object. * @return a pair representing server defined object. MAY be null.
*/ */
Map<String, String> getInnerError(); public Map<String, String> getInnerError() {
return innerError;
}
/**
* Sets server defined key-value pairs for debug environment only.
*
* @return this for method chaining.
*/
public ODataError setInnerError(Map<String, String> innerError) {
this.innerError = innerError;
return this;
}
} }

View File

@ -23,26 +23,51 @@ package org.apache.olingo.commons.api.domain;
* {"code": "301","target": "$search" ,"message": "$search query option not supported"} * {"code": "301","target": "$search" ,"message": "$search query option not supported"}
* ],...}}</tt>. * ],...}}</tt>.
*/ */
public interface ODataErrorDetail { public class ODataErrorDetail {
private String code;
private String message;
private String target;
/** /**
* Gets error code. * Gets error code.
* *
* @return error code. * @return error code.
*/ */
String getCode(); public String getCode() {
return code;
}
public ODataErrorDetail setCode(final String code) {
this.code = code;
return this;
}
/** /**
* Gets error message. * Gets error message.
* *
* @return error message. * @return error message.
*/ */
String getMessage(); public String getMessage() {
return message;
}
public ODataErrorDetail setMessage(final String message) {
this.message = message;
return this;
}
/** /**
* Gets error target. * Gets error target.
* *
* @return error message. * @return error message.
*/ */
String getTarget(); public String getTarget() {
return target;
}
public ODataErrorDetail setTarget(final String target) {
this.target = target;
return this;
}
} }

View File

@ -1,57 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.commons.core.data;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
public class ODataErrorDetailImpl implements ODataErrorDetail {
private String code;
private String message;
private String target;
@Override
public String getCode() {
return code;
}
public void setCode(final String code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(final String message) {
this.message = message;
}
@Override
public String getTarget() {
return target;
}
public void setTarget(final String target) {
this.target = target;
}
}

View File

@ -1,89 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.commons.core.data;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
/**
* Example:
* <tt>
* {
* "error": { "code": "501", "message": "Unsupported functionality", "target": "query", "details": [ { "code": "301",
* "target": "$search", "message": "$search query option not supported" } ], "innererror": { "trace": [...], "context":
* {...} } } }
* </tt>.
*/
public class ODataErrorImpl implements ODataError {
private String code;
private String message;
private String target;
private List<ODataErrorDetail> details;
private Map<String, String> innerError = new LinkedHashMap<String, String>();
@Override
public String getCode() {
return code;
}
public void setCode(final String code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(final String message) {
this.message = message;
}
@Override
public String getTarget() {
return target;
}
public void setTarget(final String target) {
this.target = target;
}
@Override
public List<ODataErrorDetail> getDetails() {
return details;
}
public void setDetails(final List<ODataErrorDetail> detail) {
details = detail;
}
@Override
public Map<String, String> getInnerError() {
return innerError;
}
}

View File

@ -66,7 +66,6 @@ import org.apache.olingo.commons.core.data.EntityImpl;
import org.apache.olingo.commons.core.data.EntitySetImpl; import org.apache.olingo.commons.core.data.EntitySetImpl;
import org.apache.olingo.commons.core.data.LinkImpl; import org.apache.olingo.commons.core.data.LinkImpl;
import org.apache.olingo.commons.core.data.LinkedComplexValueImpl; import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
import org.apache.olingo.commons.core.data.ODataErrorImpl;
import org.apache.olingo.commons.core.data.PropertyImpl; import org.apache.olingo.commons.core.data.PropertyImpl;
import org.apache.olingo.commons.core.data.v3.LinkCollectionImpl; import org.apache.olingo.commons.core.data.v3.LinkCollectionImpl;
import org.apache.olingo.commons.core.data.v4.DeltaImpl; import org.apache.olingo.commons.core.data.v4.DeltaImpl;
@ -849,7 +848,7 @@ public class AtomDeserializer extends AbstractAtomDealer implements ODataDeseria
} }
private ODataError error(final XMLEventReader reader, final StartElement start) throws XMLStreamException { private ODataError error(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
final ODataErrorImpl error = new ODataErrorImpl(); final ODataError error = new ODataError();
boolean setCode = false; boolean setCode = false;
boolean codeSet = false; boolean codeSet = false;

View File

@ -20,6 +20,7 @@ package org.apache.olingo.commons.core.serialization;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -27,7 +28,6 @@ import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.domain.ODataError; import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail; import org.apache.olingo.commons.api.domain.ODataErrorDetail;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.data.ODataErrorImpl;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@ -41,7 +41,7 @@ public class JsonODataErrorDeserializer extends JsonDeserializer {
protected ODataError doDeserialize(final JsonParser parser) throws IOException { protected ODataError doDeserialize(final JsonParser parser) throws IOException {
final ODataErrorImpl error = new ODataErrorImpl(); final ODataError error = new ODataError();
final ObjectNode tree = parser.getCodec().readTree(parser); final ObjectNode tree = parser.getCodec().readTree(parser);
if (tree.has(jsonError)) { if (tree.has(jsonError)) {
@ -73,12 +73,14 @@ public class JsonODataErrorDeserializer extends JsonDeserializer {
error.setDetails(details); error.setDetails(details);
} }
if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) { if (errorNode.hasNonNull(Constants.ERROR_INNERERROR)) {
HashMap<String, String> innerErrorMap = new HashMap<String, String>();
final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR); final JsonNode innerError = errorNode.get(Constants.ERROR_INNERERROR);
for (final Iterator<String> itor = innerError.fieldNames(); itor.hasNext();) { for (final Iterator<String> itor = innerError.fieldNames(); itor.hasNext();) {
final String keyTmp = itor.next(); final String keyTmp = itor.next();
final String val = innerError.get(keyTmp).toString(); final String val = innerError.get(keyTmp).toString();
error.getInnerError().put(keyTmp, val); innerErrorMap.put(keyTmp, val);
} }
error.setInnerError(innerErrorMap);
} }
} }

View File

@ -25,7 +25,6 @@ import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.ResWrap; import org.apache.olingo.commons.api.data.ResWrap;
import org.apache.olingo.commons.api.domain.ODataErrorDetail; import org.apache.olingo.commons.api.domain.ODataErrorDetail;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.data.ODataErrorDetailImpl;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@ -38,7 +37,7 @@ public class JsonODataErrorDetailDeserializer extends JsonDeserializer {
protected ResWrap<ODataErrorDetail> doDeserialize(final JsonParser parser) throws IOException { protected ResWrap<ODataErrorDetail> doDeserialize(final JsonParser parser) throws IOException {
final ODataErrorDetailImpl error = new ODataErrorDetailImpl(); final ODataErrorDetail error = new ODataErrorDetail();
final JsonNode errorNode = parser.getCodec().readTree(parser); final JsonNode errorNode = parser.getCodec().readTree(parser);
if (errorNode.has(Constants.ERROR_CODE)) { if (errorNode.has(Constants.ERROR_CODE)) {
error.setCode(errorNode.get(Constants.ERROR_CODE).textValue()); error.setCode(errorNode.get(Constants.ERROR_CODE).textValue());

View File

@ -23,6 +23,7 @@ import java.io.InputStream;
import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEntityType;
@ -38,4 +39,11 @@ public interface ODataSerializer {
InputStream entity(EdmEntityType edmEntityType, Entity entity, ContextURL contextURL); InputStream entity(EdmEntityType edmEntityType, Entity entity, ContextURL contextURL);
InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL); InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ContextURL contextURL);
/**
* Writes an ODataError into an InputStream
* @param error the main error
* @return inputStream containing the OData formatted error
*/
InputStream error(ODataError error);
} }

View File

@ -69,12 +69,35 @@
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.antlr</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources/antlr4</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId> <artifactId>antlr4-maven-plugin</artifactId>
<version>${antlr.version}</version> <version>${antlr.version}</version>
<executions> <executions>

View File

@ -28,6 +28,7 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEntityType;
@ -86,4 +87,9 @@ public class ODataXmlSerializerImpl implements ODataSerializer {
throw new ODataRuntimeException("Entityset serialization not implemented for XML format"); throw new ODataRuntimeException("Entityset serialization not implemented for XML format");
} }
@Override
public InputStream error(ODataError error) {
throw new ODataRuntimeException("error serialization not implemented for XML format");
}
} }

View File

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.core.serializer.json;
import java.io.IOException;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
public class ODataErrorSerializer {
private static final String ERROR = "error";
private static final String CODE = "code";
private static final String MESSAGE = "message";
private static final String TARGET = "target";
private static final String DETAILS = "details";
public void writeErrorDocument(JsonGenerator json, ODataError error) throws IOException {
if (error == null) {
throw new ODataRuntimeException("ODataError object MUST NOT be null!");
}
json.writeStartObject();
json.writeFieldName(ERROR);
json.writeStartObject();
writeODataError(json, error.getCode(), error.getMessage(), error.getTarget());
if (error.getDetails() != null) {
json.writeArrayFieldStart(DETAILS);
for (ODataErrorDetail detail : error.getDetails()) {
json.writeStartObject();
writeODataError(json, detail.getCode(), detail.getMessage(), detail.getTarget());
json.writeEndObject();
}
json.writeEndArray();
}
json.writeEndObject();
json.writeEndObject();
}
private void writeODataError(JsonGenerator json, String code, String message, String target) throws IOException,
JsonGenerationException {
if (code == null) {
json.writeNullField(CODE);
} else {
json.writeStringField(CODE, code);
}
if (message == null) {
json.writeNullField(MESSAGE);
} else {
json.writeStringField(MESSAGE, message);
}
if (target != null) {
json.writeStringField(TARGET, target);
}
}
}

View File

@ -18,24 +18,37 @@
*/ */
package org.apache.olingo.server.core.serializer.json; package org.apache.olingo.server.core.serializer.json;
import com.fasterxml.jackson.core.JsonFactory; import java.io.BufferedWriter;
import com.fasterxml.jackson.core.JsonGenerator; import java.io.IOException;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.data.*; import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.edm.*; import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.LinkedComplexValue;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory; import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer; import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.BufferedWriter; import com.fasterxml.jackson.core.JsonFactory;
import java.io.IOException; import com.fasterxml.jackson.core.JsonGenerator;
import java.io.InputStream; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import java.io.OutputStreamWriter;
import java.util.List;
public class ODataJsonSerializer implements ODataSerializer { public class ODataJsonSerializer implements ODataSerializer {
@ -172,7 +185,7 @@ public class ODataJsonSerializer implements ODataSerializer {
writePrimitive(edmProperty, property, json); writePrimitive(edmProperty, property, json);
} else if (property.isLinkedComplex()) { } else if (property.isLinkedComplex()) {
writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json); writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), json);
} else if(property.isComplex()) { } else if (property.isComplex()) {
writeComplexValue(edmProperty, property.asComplex(), json); writeComplexValue(edmProperty, property.asComplex(), json);
} else { } else {
throw new ODataRuntimeException("Property type not yet supported!"); throw new ODataRuntimeException("Property type not yet supported!");
@ -180,6 +193,7 @@ public class ODataJsonSerializer implements ODataSerializer {
} }
} }
private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json) private void writeCollection(EdmProperty edmProperty, Property property, JsonGenerator json)
throws IOException, EdmPrimitiveTypeException { throws IOException, EdmPrimitiveTypeException {
json.writeStartArray(); json.writeStartArray();
@ -243,7 +257,7 @@ public class ODataJsonSerializer implements ODataSerializer {
} }
private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties, private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
JsonGenerator json) throws IOException, EdmPrimitiveTypeException { JsonGenerator json) throws IOException, EdmPrimitiveTypeException {
final EdmComplexType type = (EdmComplexType) edmProperty.getType(); final EdmComplexType type = (EdmComplexType) edmProperty.getType();
json.writeStartObject(); json.writeStartObject();
for (final String propertyName : type.getPropertyNames()) { for (final String propertyName : type.getPropertyNames()) {
@ -261,4 +275,18 @@ public class ODataJsonSerializer implements ODataSerializer {
} }
return null; return null;
} }
@Override
public InputStream error(ODataError error) {
CircleStreamBuffer buffer = new CircleStreamBuffer();
try {
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
ODataErrorSerializer ser = new ODataErrorSerializer();
ser.writeErrorDocument(json, error);
json.close();
} catch (final IOException e) {
throw new ODataRuntimeException(e);
}
return buffer.getInputStream();
}
} }

View File

@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.core.serializer.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.domain.ODataError;
import org.apache.olingo.commons.api.domain.ODataErrorDetail;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
public class ODataErrorSerializerTest {
ODataSerializer ser;
@Before
public void before() {
ser = OData.newInstance().createSerializer(ODataFormat.JSON);
}
@Test
public void basicODataErrorNoCode() throws Exception {
ODataError error = new ODataError();
error.setMessage("ErrorMessage");
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":null,\"message\":\"ErrorMessage\"}}", jsonString);
}
@Test
public void basicODataErrorWithCode() throws Exception {
ODataError error = new ODataError();
error.setCode("Code").setMessage("ErrorMessage");
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":\"Code\",\"message\":\"ErrorMessage\"}}", jsonString);
}
@Test
public void basicODataErrorWithCodeAndTarget() throws Exception {
ODataError error = new ODataError();
error.setCode("Code").setMessage("ErrorMessage").setTarget("Target");
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":\"Code\",\"message\":\"ErrorMessage\",\"target\":\"Target\"}}", jsonString);
}
@Test(expected = ODataRuntimeException.class)
public void nullErrorResultsInException() throws Exception {
ser.error(null);
}
@Test
public void emptyDetailsList() throws Exception {
ODataError error = new ODataError();
error.setMessage("ErrorMessage").setDetails(new ArrayList<ODataErrorDetail>());
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":null,\"message\":\"ErrorMessage\",\"details\":[]}}", jsonString);
}
@Test
public void nothingSetAtODataErrorObject() throws Exception {
ODataError error = new ODataError();
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":null,\"message\":null}}", jsonString);
}
@Test
public void singleDetailNothingSet() throws Exception {
List<ODataErrorDetail> details = new ArrayList<ODataErrorDetail>();
details.add(new ODataErrorDetail());
ODataError error = new ODataError().setDetails(details);
InputStream stream = ser.error(error);
String jsonString = IOUtils.toString(stream);
assertEquals("{\"error\":{\"code\":null,\"message\":null,\"details\":[{\"code\":null,\"message\":null}]}}",
jsonString);
}
@Test
public void verifiedWithJacksonParser() throws Exception {
List<ODataErrorDetail> details = new ArrayList<ODataErrorDetail>();
details.add(new ODataErrorDetail().setCode("detailCode").setMessage("detailMessage").setTarget("detailTarget"));
ODataError error = new ODataError().setCode("Code").setMessage("Message").setTarget("Target").setDetails(details);
InputStream stream = ser.error(error);
JsonNode tree = new ObjectMapper().readTree(stream);
assertNotNull(tree);
tree = tree.get("error");
assertNotNull(tree);
assertEquals("Code", tree.get("code").textValue());
assertEquals("Message", tree.get("message").textValue());
assertEquals("Target", tree.get("target").textValue());
tree = tree.get("details");
assertNotNull(tree);
assertEquals(JsonNodeType.ARRAY, tree.getNodeType());
tree = tree.get(0);
assertNotNull(tree);
assertEquals("detailCode", tree.get("code").textValue());
assertEquals("detailMessage", tree.get("message").textValue());
assertEquals("detailTarget", tree.get("target").textValue());
}
}

View File

@ -18,6 +18,9 @@
*/ */
package org.apache.olingo.server.tecsvc.data; package org.apache.olingo.server.tecsvc.data;
import java.io.InputStream;
import java.util.List;
import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.EntitySet;
@ -39,9 +42,6 @@ import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.io.InputStream;
import java.util.List;
/** /**
*/ */
public class JsonDataProviderTest { public class JsonDataProviderTest {