diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java index 85ae888ee..6dc2f074d 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java @@ -18,11 +18,6 @@ */ package org.apache.olingo.client.api.communication; -import java.io.IOException; -import java.io.StringReader; -import java.util.Collections; -import java.util.List; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.StatusLine; import org.apache.olingo.commons.api.domain.ODataError; @@ -60,34 +55,10 @@ public class ODataClientErrorException extends RuntimeException { */ public ODataClientErrorException(final StatusLine statusLine, final ODataError error) { super((StringUtils.isBlank(error.getCode()) ? StringUtils.EMPTY : "(" + error.getCode() + ") ") - + error.getMessageValue() + " [" + statusLine.toString() + "]"); + + error.getMessage() + " [" + statusLine.toString() + "]"); this.statusLine = statusLine; this.error = error; - - if (this.error.getInnerErrorType() != null && this.error.getInnerErrorMessage() != null) { - final RuntimeException cause = - new RuntimeException(this.error.getInnerErrorType() + ": " + this.error.getInnerErrorMessage()); - - if (this.error.getInnerErrorStacktrace() != null) { - List stLines; - try { - stLines = IOUtils.readLines(new StringReader(this.error.getInnerErrorStacktrace())); - } catch (IOException e) { - stLines = Collections.emptyList(); - } - StackTraceElement[] stElements = new StackTraceElement[stLines.size()]; - for (int i = 0; i < stLines.size(); i++) { - final String stLine = stLines.get(i).substring(stLines.get(i).indexOf("at ") + 3); - final int lastDotPos = stLine.lastIndexOf('.'); - stElements[i] = new StackTraceElement( - stLine.substring(0, lastDotPos), stLine.substring(lastDotPos + 1), null, 0); - } - cause.setStackTrace(stElements); - } - - initCause(cause); - } } /** diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java index 65cca8de6..12696a6d6 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java @@ -24,7 +24,6 @@ import java.io.InputStream; import java.lang.reflect.Constructor; import java.net.URI; import java.util.Collection; -import java.util.Collections; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; @@ -52,8 +51,8 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.format.ODataMediaFormat; import org.apache.olingo.commons.api.format.ODataPubFormat; import org.apache.olingo.commons.api.format.ODataValueFormat; -import org.apache.olingo.commons.core.data.JSONErrorImpl; -import org.apache.olingo.commons.core.data.XMLErrorImpl; +import org.apache.olingo.commons.core.data.JSONODataErrorImpl; +import org.apache.olingo.commons.core.data.XMLODataErrorImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -479,19 +478,13 @@ public class ODataRequestImpl implements ODataRequest { private ODataError getGenericError(final int code, final String errorMsg, final boolean isXML) { final ODataError error; if (isXML) { - error = new XMLErrorImpl(); - final XMLErrorImpl.Message msg = new XMLErrorImpl.Message( - Collections.singletonMap("", (Object) errorMsg)); - - ((XMLErrorImpl) error).setMessage(msg); - ((XMLErrorImpl) error).setCode(String.valueOf(code)); + error = new XMLODataErrorImpl(); + ((XMLODataErrorImpl) error).setCode(String.valueOf(code)); + ((XMLODataErrorImpl) error).setMessage(errorMsg); } else { - error = new JSONErrorImpl(); - final JSONErrorImpl.Message msg = new JSONErrorImpl.Message(); - msg.setValue(errorMsg); - - ((JSONErrorImpl) error).setMessage(msg); - ((JSONErrorImpl) error).setCode(String.valueOf(code)); + error = new JSONODataErrorImpl(); + ((JSONODataErrorImpl) error).setCode(String.valueOf(code)); + ((JSONODataErrorImpl) error).setMessage(errorMsg); } return error; diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/ErrorTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/ErrorTestITCase.java index 04c41de26..efb818b87 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/ErrorTestITCase.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/ErrorTestITCase.java @@ -99,7 +99,6 @@ public class ErrorTestITCase extends AbstractTestITCase { } catch (ODataClientErrorException e) { LOG.error("ODataClientErrorException found", e); assertEquals(400, e.getStatusLine().getStatusCode()); - assertNotNull(e.getCause()); assertNotNull(e.getODataError()); } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/ErrorTest.java index 0b10d51c5..b2cf8e372 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/ErrorTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/ErrorTest.java @@ -18,8 +18,8 @@ */ package org.apache.olingo.client.core.v3; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import org.apache.olingo.client.api.v3.ODataClient; import org.apache.olingo.commons.api.domain.ODataError; @@ -43,7 +43,7 @@ public class ErrorTest extends AbstractTest { private void simple(final ODataPubFormat format) { final ODataError error = error("error", format); - assertNull(error.getInnerErrorStacktrace()); + assertEquals("The URL representing the root of the service only supports GET requests.", error.getMessage()); } @Test @@ -58,7 +58,7 @@ public class ErrorTest extends AbstractTest { private void stacktrace(final ODataPubFormat format) { final ODataError error = error("stacktrace", format); - assertNotNull(error.getInnerErrorStacktrace()); + assertEquals("Unsupported media type requested.", error.getMessage()); } @Test diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java new file mode 100644 index 000000000..c89fa3934 --- /dev/null +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/ErrorTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.client.core.v4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.apache.olingo.client.api.v4.ODataClient; +import org.apache.olingo.commons.api.domain.ODataError; +import org.apache.olingo.commons.api.format.ODataPubFormat; +import org.apache.olingo.client.core.AbstractTest; +import org.junit.Test; + +public class ErrorTest extends AbstractTest { + + @Override + protected ODataClient getClient() { + return v4Client; + } + + private ODataError error(final String name, final ODataPubFormat format) { + final ODataError error = getClient().getDeserializer().toError( + getClass().getResourceAsStream(name + "." + getSuffix(format)), format == ODataPubFormat.ATOM); + assertNotNull(error); + return error; + } + + private void simple(final ODataPubFormat format) { + final ODataError error = error("error", format); + assertEquals("501", error.getCode()); + assertEquals("Unsupported functionality", error.getMessage()); + assertEquals("query", error.getTarget()); + } + + @Test + public void jsonSimple() { + simple(ODataPubFormat.JSON); + } + + @Test + public void atomSimple() { + simple(ODataPubFormat.ATOM); + } + +} diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v3/error.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v3/error.xml index 2ef78ad9d..9d999ff1b 100644 --- a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v3/error.xml +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v3/error.xml @@ -21,5 +21,5 @@ --> - The URI 'http://192.168.0.160:8080/DefaultService.svc/Customer(100)' is not valid for POST operation. For POST operations, the URI must refer to a service operation or an entity set. + The URL representing the root of the service only supports GET requests. diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.json new file mode 100644 index 000000000..30a50d874 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.json @@ -0,0 +1,14 @@ +{ + "error": { + "code": "501", + "message": "Unsupported functionality", + "target": "query", + "details": [ + { + "code": "301", + "target": "$search", + "message": "$search query option not supported" + } + ] + } +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.xml new file mode 100644 index 000000000..149b799b3 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/error.xml @@ -0,0 +1,31 @@ + + + + 501 + Unsupported functionality + query +
+ + 301 + $search query option not supported + $search + +
+
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java index f41c30cfa..a1aec31aa 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java @@ -224,4 +224,11 @@ public interface Constants { public static final String ATOM_ATTR_METADATAETAG = "metadata-etag"; + // error stuff + public static final String ERROR_CODE = "code"; + + public static final String ERROR_MESSAGE = "message"; + + public static final String ERROR_TARGET = "target"; + } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java index 29939643c..fc309d30d 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/domain/ODataError.java @@ -30,38 +30,18 @@ public interface ODataError { */ String getCode(); - /** - * Gets error message language. - * - * @return error message language. - */ - String getMessageLang(); - /** * Gets error message. * * @return error message. */ - String getMessageValue(); + String getMessage(); /** - * Gets inner error message. + * Gets error target. * - * @return inner error message. + * @return error message. */ - String getInnerErrorMessage(); + String getTarget(); - /** - * Gets inner error type. - * - * @return inner error type. - */ - String getInnerErrorType(); - - /** - * Gets inner error stack-trace. - * - * @return inner error stack-trace - */ - String getInnerErrorStacktrace(); } diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java index 5442d1d9d..c6354ecbe 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/constants/ODataServiceVersion.java @@ -69,6 +69,7 @@ public enum ODataServiceVersion { public static final String JSON_ASSOCIATION_LINK = "jsonAssociationLink"; public static final String JSON_NAVIGATION_LINK = "jsonNavigationLink"; + public static final String JSON_ERROR = "jsonError"; private static final Map V30_NAMESPACES = Collections.unmodifiableMap(new HashMap() { @@ -100,6 +101,7 @@ public enum ODataServiceVersion { put(JSON_MEDIA_ETAG, "odata.mediaEtag"); put(JSON_ASSOCIATION_LINK, "@odata.associationLinkUrl"); put(JSON_NAVIGATION_LINK, "@odata.navigationLinkUrl"); + put(JSON_ERROR, "odata.error"); } }); @@ -133,6 +135,7 @@ public enum ODataServiceVersion { put(JSON_MEDIA_ETAG, "@odata.mediaEtag"); put(JSON_ASSOCIATION_LINK, "@odata.associationLink"); put(JSON_NAVIGATION_LINK, "@odata.navigationLink"); + put(JSON_ERROR, "error"); } }); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java index 656207c59..e9338f1a3 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java @@ -60,6 +60,12 @@ abstract class AbstractAtomDealer { protected final QName v4PropertyValueQName; + protected final QName errorCodeQName; + + protected final QName errorMessageQName; + + protected final QName errorTargetQName; + public AbstractAtomDealer(final ODataServiceVersion version) { this.version = version; @@ -90,6 +96,13 @@ abstract class AbstractAtomDealer { new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_ENTRY_REF); this.v4PropertyValueQName = new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.VALUE); + + this.errorCodeQName = + new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ERROR_CODE); + this.errorMessageQName = + new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ERROR_MESSAGE); + this.errorTargetQName = + new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ERROR_TARGET); } protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException { diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorBundle.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java similarity index 58% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorBundle.java rename to lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java index 433b7540a..e5324d816 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorBundle.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataError.java @@ -18,33 +18,41 @@ */ package org.apache.olingo.commons.core.data; -import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.olingo.commons.api.domain.ODataError; -/** - * This class represents a bundle for an OData error returned as JSON. - */ -public class JSONErrorBundle extends AbstractPayloadObject { +public abstract class AbstractODataError implements ODataError { - private static final long serialVersionUID = -4784910226259754450L; + private String code; - @JsonProperty("odata.error") - private JSONErrorImpl error; + private String message; - /** - * Gets error. - * - * @return OData error object. - */ - public JSONErrorImpl getError() { - return error; + private String target; + + @Override + public String getCode() { + return code; } - /** - * Sets error. - * - * @param error OData error object. - */ - public void setError(final JSONErrorImpl error) { - this.error = error; + 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; + } + } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractProperty.java similarity index 96% rename from lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java rename to lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractProperty.java index e005f98fe..940bf8907 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractProperty.java @@ -25,7 +25,7 @@ import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.Value; -public abstract class AbstractPropertyImpl implements Property { +public abstract class AbstractProperty implements Property { private String name; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java index c2ffd8e6b..a78680331 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java @@ -386,11 +386,69 @@ public class AtomDeserializer extends AbstractAtomDealer { return getContainer(start, feed(reader, start)); } + private XMLODataErrorImpl error(final XMLEventReader reader, final StartElement start) throws XMLStreamException { + final XMLODataErrorImpl error = new XMLODataErrorImpl(); + + boolean setCode = false; + boolean codeSet = false; + boolean setMessage = false; + boolean messageSet = false; + boolean setTarget = false; + boolean targetSet = false; + + boolean foundEndElement = false; + while (reader.hasNext() && !foundEndElement) { + final XMLEvent event = reader.nextEvent(); + + if (event.isStartElement()) { + if (errorCodeQName.equals(event.asStartElement().getName())) { + setCode = true; + } else if (errorMessageQName.equals(event.asStartElement().getName())) { + setMessage = true; + } else if (errorTargetQName.equals(event.asStartElement().getName())) { + setTarget = true; + } + } + + if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) { + if (setCode && !codeSet) { + error.setCode(event.asCharacters().getData()); + setCode = false; + codeSet = true; + } + if (setMessage && !messageSet) { + error.setMessage(event.asCharacters().getData()); + setMessage = false; + messageSet = true; + } + if (setTarget && !targetSet) { + error.setTarget(event.asCharacters().getData()); + setTarget = false; + targetSet = true; + } + } + + if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) { + foundEndElement = true; + } + } + + return error; + } + + private Container error(final InputStream input) throws XMLStreamException { + final XMLEventReader reader = FACTORY.createXMLEventReader(input); + final StartElement start = skipBeforeFirstStartElement(reader); + return getContainer(start, error(reader, start)); + } + @SuppressWarnings("unchecked") public Container read(final InputStream input, final Class reference) throws XMLStreamException { - if (AtomFeedImpl.class.equals(reference)) { + if (XMLODataErrorImpl.class.equals(reference)) { + return (Container) error(input); + } else if (AtomFeedImpl.class.equals(reference)) { return (Container) feed(input); } else if (AtomEntryImpl.class.equals(reference)) { return (Container) entry(input); diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyImpl.java index 9688db2d1..e0018bcd2 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomPropertyImpl.java @@ -18,7 +18,7 @@ */ package org.apache.olingo.commons.core.data; -public class AtomPropertyImpl extends AbstractPropertyImpl { +public class AtomPropertyImpl extends AbstractProperty { private static final long serialVersionUID = 48748492242474814L; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorImpl.java deleted file mode 100644 index 4c6cb4a44..000000000 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONErrorImpl.java +++ /dev/null @@ -1,237 +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 com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.olingo.commons.api.domain.ODataError; - -/** - * This class represents an OData error returned as JSON. - */ -public class JSONErrorImpl extends AbstractPayloadObject implements ODataError { - - private static final long serialVersionUID = -3476499168507242932L; - - /** - * Error message. - */ - public static class Message extends AbstractPayloadObject { - - private static final long serialVersionUID = 2577818040815637859L; - - private String lang; - - private String value; - - /** - * Gets language. - * - * @return language. - */ - public String getLang() { - return lang; - } - - /** - * Sets language. - * - * @param lang language. - */ - public void setLang(final String lang) { - this.lang = lang; - } - - /** - * Gets message. - * - * @return message. - */ - public String getValue() { - return value; - } - - /** - * Sets message. - * - * @param value message. - */ - public void setValue(final String value) { - this.value = value; - } - } - - /** - * Inner error. - */ - static class InnerError extends AbstractPayloadObject { - - private static final long serialVersionUID = -3920947476143537640L; - - private String message; - - private String type; - - private String stacktrace; - - private InnerError internalexception; - - /** - * Gets inner message. - * - * @return message. - */ - public String getMessage() { - return message; - } - - /** - * Sets inner message. - * - * @param message message. - */ - public void setMessage(final String message) { - this.message = message; - } - - /** - * Gets type. - * - * @return type. - */ - public String getType() { - return type; - } - - /** - * Sets type. - * - * @param type type. - */ - public void setType(final String type) { - this.type = type; - } - - /** - * Gets stack-trace. - * - * @return stack-trace. - */ - public String getStacktrace() { - return stacktrace; - } - - /** - * Sets stack-trace. - * - * @param stacktrace stack-trace. - */ - public void setStacktrace(final String stacktrace) { - this.stacktrace = stacktrace; - } - - public InnerError getInternalexception() { - return internalexception; - } - - public void setInternalexception(final InnerError internalexception) { - this.internalexception = internalexception; - } - } - - private String code; - - @JsonProperty(value = "message") - private Message message; - - @JsonProperty(value = "innererror", required = false) - private InnerError innererror; - - /** - * {@inheritDoc } - */ - @Override - public String getCode() { - return code; - } - - /** - * Sets error code. - * - * @param code error code. - */ - public void setCode(final String code) { - this.code = code; - } - - /** - * {@inheritDoc } - */ - @JsonIgnore - @Override - public String getMessageLang() { - return this.message == null ? null : this.message.getLang(); - } - - /** - * {@inheritDoc } - */ - @JsonIgnore - @Override - public String getMessageValue() { - return this.message == null ? null : this.message.getValue(); - } - - /** - * Sets the value of the message property. - * - * @param value allowed object is {@link Error.Message } - * - */ - public void setMessage(final Message value) { - this.message = value; - } - - /** - * {@inheritDoc } - */ - @JsonIgnore - @Override - public String getInnerErrorMessage() { - return this.innererror == null ? null : this.innererror.getMessage(); - } - - /** - * {@inheritDoc } - */ - @JsonIgnore - @Override - public String getInnerErrorType() { - return this.innererror == null ? null : this.innererror.getType(); - } - - /** - * {@inheritDoc } - */ - @JsonIgnore - @Override - public String getInnerErrorStacktrace() { - return this.innererror == null ? null : this.innererror.getStacktrace(); - } -} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java new file mode 100644 index 000000000..f033de16d --- /dev/null +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorDeserializer.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.commons.core.data; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import org.apache.olingo.commons.api.Constants; + +public class JSONODataErrorDeserializer extends AbstractJsonDeserializer { + + @Override + protected JSONODataErrorImpl doDeserialize(final JsonParser parser, final DeserializationContext ctxt) + throws IOException, JsonProcessingException { + + final JSONODataErrorImpl error = new JSONODataErrorImpl(); + + final ObjectNode tree = parser.getCodec().readTree(parser); + if (tree.has(jsonError)) { + final JsonNode errorNode = tree.get(jsonError); + + if (errorNode.has(Constants.ERROR_CODE)) { + error.setCode(errorNode.get(Constants.ERROR_CODE).textValue()); + } + if (errorNode.has(Constants.ERROR_MESSAGE)) { + final JsonNode message = errorNode.get(Constants.ERROR_MESSAGE); + if (message.isValueNode()) { + error.setMessage(message.textValue()); + } else if (message.isObject()) { + error.setMessage(message.get(Constants.VALUE).asText()); + } + } + if (errorNode.has(Constants.ERROR_TARGET)) { + error.setTarget(errorNode.get(Constants.ERROR_TARGET).textValue()); + } + } + + return error; + } + +} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorImpl.java new file mode 100644 index 000000000..c455d2d47 --- /dev/null +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONODataErrorImpl.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.commons.core.data; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = JSONODataErrorDeserializer.class) +public class JSONODataErrorImpl extends AbstractODataError { + +} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyImpl.java index 1ef029433..101866605 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/JSONPropertyImpl.java @@ -26,7 +26,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; */ @JsonSerialize(using = JSONPropertySerializer.class) @JsonDeserialize(using = JSONPropertyDeserializer.class) -public class JSONPropertyImpl extends AbstractPropertyImpl { +public class JSONPropertyImpl extends AbstractProperty { private static final long serialVersionUID = 553414431536637434L; diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonDeserializer.java index fa6e38ffc..7b0524806 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/ODataJacksonDeserializer.java @@ -52,6 +52,8 @@ public abstract class ODataJacksonDeserializer extends JsonDeserializer { protected String jsonNavigationLink; + protected String jsonError; + protected abstract T doDeserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException; @@ -76,6 +78,7 @@ public abstract class ODataJacksonDeserializer extends JsonDeserializer { jsonMediaETag = version.getJSONMap().get(ODataServiceVersion.JSON_MEDIA_ETAG); jsonAssociationLink = version.getJSONMap().get(ODataServiceVersion.JSON_ASSOCIATION_LINK); jsonNavigationLink = version.getJSONMap().get(ODataServiceVersion.JSON_NAVIGATION_LINK); + jsonError = version.getJSONMap().get(ODataServiceVersion.JSON_ERROR); return doDeserialize(jp, ctxt); } diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLErrorImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLErrorImpl.java deleted file mode 100644 index a8c3d84d3..000000000 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLErrorImpl.java +++ /dev/null @@ -1,213 +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 com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText; -import java.util.Map; -import org.apache.olingo.commons.api.domain.ODataError; - -/** - * This class represents an OData error returned as JSON. - */ -public class XMLErrorImpl extends AbstractPayloadObject implements ODataError { - - private static final long serialVersionUID = -3476499168507242932L; - - @JacksonXmlText(false) - private String code; - - @JsonProperty - private Message message; - - @JsonProperty(required = false) - private InnerError innererror; - - @Override - public String getCode() { - return code; - } - - /** - * Sets error code. - * - * @param code error code. - */ - public void setCode(final String code) { - this.code = code; - } - - @JsonIgnore - @Override - public String getMessageLang() { - return this.message == null ? null : this.message.getLang(); - } - - @JsonIgnore - @Override - public String getMessageValue() { - return this.message == null ? null : this.message.getValue(); - } - - /** - * Sets the value of the message property. - * - * @param value allowed object is {@link Error.Message } - * - */ - public void setMessage(final Message value) { - this.message = value; - } - - @JsonIgnore - @Override - public String getInnerErrorMessage() { - return this.innererror == null ? null : this.innererror.getMessage().getValue(); - } - - @JsonIgnore - @Override - public String getInnerErrorType() { - return this.innererror == null ? null : this.innererror.getType().getValue(); - } - - @JsonIgnore - @Override - public String getInnerErrorStacktrace() { - return this.innererror == null ? null : this.innererror.getStacktrace().getValue(); - } - - static class TextChildContainer extends AbstractPayloadObject { - - private static final long serialVersionUID = -8908394095210115904L; - - public TextChildContainer() { - super(); - } - - public TextChildContainer(final String value) { - super(); - this.value = value; - } - - @JsonCreator - public TextChildContainer(final Map props) { - super(); - this.value = (String) props.get(""); - } - - private String value; - - public String getValue() { - return value; - } - - public void setValue(final String value) { - this.value = value; - } - } - - /** - * Error message. - */ - public static class Message extends TextChildContainer { - - private static final long serialVersionUID = 2577818040815637859L; - - private String lang; - - public Message() { - super(); - } - - @JsonCreator - public Message(final Map props) { - super(props); - this.lang = (String) props.get("lang"); - } - - /** - * Gets language. - * - * @return language. - */ - public String getLang() { - return lang; - } - - /** - * Sets language. - * - * @param lang language. - */ - public void setLang(final String lang) { - this.lang = lang; - } - } - - /** - * Inner error. - */ - static class InnerError extends AbstractPayloadObject { - - private static final long serialVersionUID = -3920947476143537640L; - - private TextChildContainer message; - - private TextChildContainer type; - - private TextChildContainer stacktrace; - - private InnerError internalexception; - - public TextChildContainer getMessage() { - return message; - } - - public void setMessage(final TextChildContainer message) { - this.message = message; - } - - public TextChildContainer getType() { - return type; - } - - public void setType(final TextChildContainer type) { - this.type = type; - } - - public TextChildContainer getStacktrace() { - return stacktrace; - } - - public void setStacktrace(final TextChildContainer stacktrace) { - this.stacktrace = stacktrace; - } - - public InnerError getInternalexception() { - return internalexception; - } - - public void setInternalexception(final InnerError internalexception) { - this.internalexception = internalexception; - } - } -} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLODataErrorImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLODataErrorImpl.java new file mode 100644 index 000000000..36cb68275 --- /dev/null +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/XMLODataErrorImpl.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.commons.core.data; + +public class XMLODataErrorImpl extends AbstractODataError { + +} diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java index bf4bd5708..616766b90 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java @@ -39,10 +39,10 @@ import org.apache.olingo.commons.core.data.AtomEntryImpl; import org.apache.olingo.commons.core.data.AtomFeedImpl; import org.apache.olingo.commons.core.data.AtomPropertyImpl; import org.apache.olingo.commons.core.data.JSONEntryImpl; -import org.apache.olingo.commons.core.data.JSONErrorBundle; import org.apache.olingo.commons.core.data.JSONFeedImpl; +import org.apache.olingo.commons.core.data.JSONODataErrorImpl; import org.apache.olingo.commons.core.data.JSONPropertyImpl; -import org.apache.olingo.commons.core.data.XMLErrorImpl; +import org.apache.olingo.commons.core.data.XMLODataErrorImpl; public abstract class AbstractODataDeserializer extends AbstractJacksonTool implements CommonODataDeserializer { @@ -80,8 +80,8 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl @Override public ODataError toError(final InputStream input, final boolean isXML) { return isXML - ? this.xml(input, XMLErrorImpl.class).getObject() - : this.json(input, JSONErrorBundle.class).getObject().getError(); + ? this.atom(input, XMLODataErrorImpl.class).getObject() + : this.json(input, JSONODataErrorImpl.class).getObject(); } /* @@ -90,21 +90,21 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl @SuppressWarnings("unchecked") protected Container xml(final InputStream input, final Class reference) { try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final XMLEventReader reader = AtomDeserializer.FACTORY.createXMLEventReader(input); final StartElement start = atomDeserializer.skipBeforeFirstStartElement(reader); - final XMLEventWriter writer = XMLOutputFactory.newFactory().createXMLEventWriter(bos); + final XMLEventWriter writer = XMLOutputFactory.newFactory().createXMLEventWriter(baos); writer.add(start); writer.add(reader); writer.flush(); writer.close(); return (Container) atomDeserializer.getContainer( - start, getXmlMapper().readValue(new ByteArrayInputStream(bos.toByteArray()), reference)); - + start, getXmlMapper().readValue(new ByteArrayInputStream(baos.toByteArray()), reference)); } catch (Exception e) { + e.printStackTrace(); throw new IllegalArgumentException("While deserializing " + reference.getName(), e); } }