diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataTranslatedException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataTranslatedException.java index 1dbb81050..b7477b95b 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataTranslatedException.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataTranslatedException.java @@ -29,7 +29,7 @@ import org.apache.olingo.commons.api.ODataException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ODataTranslatedException extends ODataException { +public abstract class ODataTranslatedException extends ODataException { private static final long serialVersionUID = -1210541002198287561L; private static final Logger log = LoggerFactory.getLogger(ODataTranslatedException.class); @@ -39,24 +39,16 @@ public class ODataTranslatedException extends ODataException { protected static interface MessageKey {} - public static enum MessageKeys implements MessageKey { - AMBIGUOUS_XHTTP_METHOD, - HTTP_METHOD_NOT_IMPLEMENTED, - PROCESSOR_NOT_IMPLEMENTED, - FUNCTIONALITY_NOT_IMPLEMENTED, - ODATA_VERSION_NOT_SUPPORTED, - } - private MessageKey messageKey; private Object[] parameters; - public ODataTranslatedException(String developmentMessage, MessageKey messageKey, String... parameters) { + protected ODataTranslatedException(String developmentMessage, MessageKey messageKey, String... parameters) { super(developmentMessage); this.messageKey = messageKey; this.parameters = parameters; } - public ODataTranslatedException(String developmentMessage, Throwable cause, MessageKey messageKey, + protected ODataTranslatedException(String developmentMessage, Throwable cause, MessageKey messageKey, String... parameters) { super(developmentMessage, cause); this.messageKey = messageKey; @@ -90,17 +82,12 @@ public class ODataTranslatedException extends ODataException { } private ResourceBundle createResourceBundle(final Locale locale) { - ResourceBundle bundle = null; try { - if (locale == null) { - bundle = ResourceBundle.getBundle(BUNDLE_NAME, DEFAULT_LOCALE); - } else { - bundle = ResourceBundle.getBundle(BUNDLE_NAME, locale); - } - } catch (final Exception e) { + return ResourceBundle.getBundle(BUNDLE_NAME, locale == null ? DEFAULT_LOCALE : locale); + } catch (final MissingResourceException e) { log.error(e.getMessage(), e); + return null; } - return bundle; } private ODataErrorMessage buildMessage(ResourceBundle bundle, Locale locale) { @@ -113,7 +100,7 @@ public class ODataTranslatedException extends ODataException { f.format(message, parameters); f.close(); Locale usedLocale = bundle.getLocale(); - if (usedLocale == Locale.ROOT || Locale.ROOT.equals(usedLocale)) { + if (Locale.ROOT.equals(usedLocale)) { usedLocale = DEFAULT_LOCALE; } return new ODataErrorMessage(builder.toString(), usedLocale); diff --git a/lib/server-api/src/main/resources/i18n.properties b/lib/server-api/src/main/resources/i18n.properties deleted file mode 100644 index 7a7fbe933..000000000 --- a/lib/server-api/src/main/resources/i18n.properties +++ /dev/null @@ -1,40 +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. -#------------------------------------------------------------------------------- -# Basic Apache Olingo exception messages -# -ODataTranslatedException.AMBIGUOUS_XHTTP_METHOD=x-http-method header '%1$s' and x-http-method-override header '%2$s' are not the same. -ODataTranslatedException.HTTP_METHOD_NOT_IMPLEMENTED=Invalid HTTP method given: '%1$s'. -ODataTranslatedException.PROCESSOR_NOT_IMPLEMENTED=No processor for interface '%1$s' registered. -ODataTranslatedException.FUNCTIONALITY_NOT_IMPLEMENTED=The requested functionality has not been implemented (yet). -ODataTranslatedException.ODATA_VERSION_NOT_SUPPORTED=OData version '%1$s' is not supported. -ContentNegotiatorException.WRONG_CHARSET_IN_HEADER=The HTTP header '%1$s' with value '%2$s' contains an invalid character-set specification. -ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPES=The content-type range '%1$s' is not supported. -ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported. -ContentNegotiatorException.UNSUPPORTED_FORMAT_OPTION=The $format option '%1$s' is not supported. - -ODataSerializerException.NOT_IMPLEMENTED=The requested serialization method has not been implemented yet. -ODataSerializerException.UNSUPPORTED_FORMAT=The format '%1$s' is not supported. -ODataSerializerException.JSON_METADATA=The metadata document cannot be provided in JSON format. -ODataSerializerException.IO_EXCEPTION=An I/O exception occurred. -ODataSerializerException.NULL_INPUT=The input 'null' is not allowed here. -ODataSerializerException.NO_CONTEXT_URL=No context URL has been provided. -ODataSerializerException.UNSUPPORTED_PROPERTY_TYPE=The type of the property '%1$s' is not yet supported. -ODataSerializerException.INCONSISTENT_PROPERTY_TYPE=An inconsistency has been detected in the type definition of property '%1$s'. -ODataSerializerException.MISSING_PROPERTY=The non-nullable property '%1$s' is missing. -ODataSerializerException.WRONG_PROPERTY_VALUE=The value '%2$s' is not valid for property '%1$s'. diff --git a/lib/server-api/src/test/java/org/apache/olingo/server/api/TranslatedExceptionsTest.java b/lib/server-api/src/test/java/org/apache/olingo/server/api/TranslatedExceptionsTest.java index ba145b94b..5047f3ea2 100644 --- a/lib/server-api/src/test/java/org/apache/olingo/server/api/TranslatedExceptionsTest.java +++ b/lib/server-api/src/test/java/org/apache/olingo/server/api/TranslatedExceptionsTest.java @@ -18,9 +18,10 @@ */ package org.apache.olingo.server.api; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThat; import java.util.Locale; @@ -30,112 +31,121 @@ import org.junit.Test; public class TranslatedExceptionsTest { private static final String DEV = "devMessage"; - private static enum Keys implements ODataTranslatedException.MessageKey { - BASIC, ONEPARAM, TWOPARAM, NOMESSAGE - } - public TranslatedExceptionsTest() { - // for test reason we assume a system with a default Locale.ENGLISH - Locale.setDefault(Locale.ENGLISH); + private static class TestException extends ODataTranslatedException { + private static final long serialVersionUID = -7199975861656921724L; + public static enum Keys implements MessageKey { + BASIC, ONEPARAM, TWOPARAM, NOMESSAGE, ONLY_ROOT, ONLY_GERMAN + } + protected TestException(final MessageKey messageKey, final String... parameters) { + super(DEV, messageKey, parameters); + } } @Test public void basic() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.BASIC); + TestException exp = new TestException(TestException.Keys.BASIC); assertEquals(DEV, exp.getMessage()); + assertEquals(DEV, exp.toString()); + assertEquals("Test Default", exp.getLocalizedMessage()); + assertEquals(TestException.Keys.BASIC, exp.getMessageKey()); - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); - assertNotNull(translatedMessage); - assertEquals("Test Default", translatedMessage.getMessage()); - - translatedMessage = exp.getTranslatedMessage(Locale.ENGLISH); - assertNotNull(translatedMessage); - assertEquals("Test Default", translatedMessage.getMessage()); - assertEquals(Locale.ENGLISH, translatedMessage.getLocale()); - - translatedMessage = exp.getTranslatedMessage(Locale.UK); - assertNotNull(translatedMessage); - assertEquals("Test Default", translatedMessage.getMessage()); - - translatedMessage = exp.getTranslatedMessage(Locale.GERMAN); - assertNotNull(translatedMessage); - assertEquals("Test DE", translatedMessage.getMessage()); - assertEquals(Locale.GERMAN, translatedMessage.getLocale()); - - translatedMessage = exp.getTranslatedMessage(Locale.GERMANY); - assertNotNull(translatedMessage); - assertEquals("Test DE", translatedMessage.getMessage()); - assertEquals(Locale.GERMAN, translatedMessage.getLocale()); + checkTranslatedMessage(exp.getTranslatedMessage(null), "Test Default", Locale.ENGLISH); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.ENGLISH), "Test Default", Locale.ENGLISH); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.UK), "Test Default", Locale.ENGLISH); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.GERMAN), "Test DE", Locale.GERMAN); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.GERMANY), "Test DE", Locale.GERMAN); } @Test public void unusedParametersMustNotResultInAnException() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.BASIC, "unusedParam1", "unusedParam2"); + TestException exp = new TestException(TestException.Keys.BASIC, "unusedParam1", "unusedParam2"); assertEquals(DEV, exp.getMessage()); - - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); - assertNotNull(translatedMessage); - assertEquals("Test Default", translatedMessage.getMessage()); + checkTranslatedMessage(exp.getTranslatedMessage(null), "Test Default", Locale.ENGLISH); } @Test public void useOneParameter() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.ONEPARAM, "usedParam1"); + TestException exp = new TestException(TestException.Keys.ONEPARAM, "usedParam1"); assertEquals(DEV, exp.getMessage()); - - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); - assertNotNull(translatedMessage); - assertEquals("Param1: usedParam1", translatedMessage.getMessage()); + checkTranslatedMessage(exp.getTranslatedMessage(null), "Param1: usedParam1", Locale.ENGLISH); } @Test public void useOneParameterExpectedButMultipleGiven() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.ONEPARAM, "usedParam1", "unusedParam2"); + TestException exp = new TestException(TestException.Keys.ONEPARAM, "usedParam1", "unusedParam2"); assertEquals(DEV, exp.getMessage()); - - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); - assertNotNull(translatedMessage); - assertEquals("Param1: usedParam1", translatedMessage.getMessage()); + checkTranslatedMessage(exp.getTranslatedMessage(null), "Param1: usedParam1", Locale.ENGLISH); } @Test - public void useTwoParameter() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.TWOPARAM, "usedParam1", "usedParam2"); + public void useTwoParameters() { + TestException exp = new TestException(TestException.Keys.TWOPARAM, "usedParam1", "usedParam2"); assertEquals(DEV, exp.getMessage()); - - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); - assertNotNull(translatedMessage); - assertEquals("Param1: usedParam1 Param2: usedParam2", translatedMessage.getMessage()); + checkTranslatedMessage(exp.getTranslatedMessage(null), "Param1: usedParam1 Param2: usedParam2", Locale.ENGLISH); } @Test - public void parametersNotGivenAltoughNeeded() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.ONEPARAM); + public void parametersNotGivenAlthoughNeeded() { + TestException exp = new TestException(TestException.Keys.ONEPARAM); assertEquals(DEV, exp.getMessage()); ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); assertNotNull(translatedMessage); - assertTrue(translatedMessage.getMessage().contains("Missing replacement for place holder in message")); + assertThat(translatedMessage.getMessage(), containsString("Missing replacement for place holder in message")); + } + + @Test + public void noMessageKey() { + TestException exp = new TestException(null); + assertEquals(DEV, exp.getMessage()); + + ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); + assertNotNull(translatedMessage); + assertEquals(DEV, translatedMessage.getMessage()); } @Test public void noMessageForKey() { - ODataTranslatedException exp = new ODataTranslatedException(DEV, Keys.NOMESSAGE); + TestException exp = new TestException(TestException.Keys.NOMESSAGE); assertEquals(DEV, exp.getMessage()); ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); assertNotNull(translatedMessage); - assertTrue(translatedMessage.getMessage().contains("Missing message for key")); + assertThat(translatedMessage.getMessage(), containsString("Missing message for key")); } @Test public void keyForRootBundleButNotPresentInDerivedBundle() { - ODataTranslatedException exp = - new ODataTranslatedException(DEV, ODataTranslatedException.MessageKeys.HTTP_METHOD_NOT_IMPLEMENTED, "param1"); + TestException exp = new TestException(TestException.Keys.ONLY_ROOT); assertEquals(DEV, exp.getMessage()); - ODataErrorMessage translatedMessage = exp.getTranslatedMessage(Locale.GERMAN); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.GERMAN), "Root message", Locale.GERMAN); + checkTranslatedMessage(exp.getTranslatedMessage(Locale.ROOT), "Root message", Locale.ENGLISH); + } + + @Test + public void defaultLocale() { + TestException exp = new TestException(TestException.Keys.ONLY_GERMAN); + assertEquals(DEV, exp.getMessage()); + + Locale.setDefault(Locale.GERMAN); + ODataErrorMessage translatedMessage = exp.getTranslatedMessage(null); assertNotNull(translatedMessage); - assertEquals("Invalid HTTP method given: 'param1'.", translatedMessage.getMessage()); + assertThat(translatedMessage.getMessage(), containsString("Missing message for key")); + assertEquals(Locale.ENGLISH, translatedMessage.getLocale()); + + Locale.setDefault(Locale.ENGLISH); + translatedMessage = exp.getTranslatedMessage(null); + assertNotNull(translatedMessage); + assertThat(translatedMessage.getMessage(), containsString("Missing message for key")); + assertEquals(Locale.ENGLISH, translatedMessage.getLocale()); + } + + private void checkTranslatedMessage(final ODataErrorMessage translatedMessage, + final String expectedText, final Locale expectedLocale) { + assertNotNull(translatedMessage); + assertEquals(expectedText, translatedMessage.getMessage()); + assertEquals(expectedLocale, translatedMessage.getLocale()); } } diff --git a/lib/server-api/src/test/resources/i18n.properties b/lib/server-api/src/test/resources/i18n.properties new file mode 100644 index 000000000..58c31b360 --- /dev/null +++ b/lib/server-api/src/test/resources/i18n.properties @@ -0,0 +1,21 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +# Basic Apache Olingo exception messages +# +TestException.ONLY_ROOT=Root message \ No newline at end of file diff --git a/lib/server-api/src/test/resources/i18n_de.properties b/lib/server-api/src/test/resources/i18n_de.properties index c897e1f32..b91948306 100644 --- a/lib/server-api/src/test/resources/i18n_de.properties +++ b/lib/server-api/src/test/resources/i18n_de.properties @@ -16,4 +16,5 @@ # specific language governing permissions and limitations # under the License. #------------------------------------------------------------------------------- -ODataTranslatedException.BASIC=Test DE \ No newline at end of file +TestException.BASIC=Test DE +TestException.ONLY_GERMAN=Deutsche Nachricht \ No newline at end of file diff --git a/lib/server-api/src/test/resources/i18n_en.properties b/lib/server-api/src/test/resources/i18n_en.properties index 9fdbaaad2..84dd9d1ea 100644 --- a/lib/server-api/src/test/resources/i18n_en.properties +++ b/lib/server-api/src/test/resources/i18n_en.properties @@ -18,6 +18,6 @@ #------------------------------------------------------------------------------- # Basic Apache Olingo exception messages # -ODataTranslatedException.BASIC=Test Default -ODataTranslatedException.ONEPARAM=Param1: %1$s -ODataTranslatedException.TWOPARAM=Param1: %1$s Param2: %2$s \ No newline at end of file +TestException.BASIC=Test Default +TestException.ONEPARAM=Param1: %1$s +TestException.TWOPARAM=Param1: %1$s Param2: %2$s \ No newline at end of file diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java index 3b9f06883..71a69b8de 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java @@ -73,8 +73,10 @@ public class ODataHandler { processInternal(request, requestedContentType, response); - } catch (UriParserException e) { - e.printStackTrace(); + } catch (final UriParserException e) { + handleException(request, response, + ODataExceptionHelper.createServerErrorObject(e, HttpStatusCode.BAD_REQUEST.getStatusCode()), + requestedContentType); } catch (ContentNegotiatorException e) { Locale requestedLocale = null; ODataServerError serverError = @@ -138,8 +140,8 @@ public class ODataHandler { break; default: response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } @@ -176,8 +178,8 @@ public class ODataHandler { cp.readCollection(request, response, uriInfo, requestedContentType); } else { response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } else { if (request.getMethod().equals(HttpMethod.GET)) { @@ -189,8 +191,8 @@ public class ODataHandler { ep.readEntity(request, response, uriInfo, requestedContentType); } else { response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } break; @@ -206,8 +208,8 @@ public class ODataHandler { cp.readCollection(request, response, uriInfo, requestedContentType); } else { response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } else { if (request.getMethod().equals(HttpMethod.GET)) { @@ -219,15 +221,15 @@ public class ODataHandler { ep.readEntity(request, response, uriInfo, requestedContentType); } else { response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } break; default: response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("not implemented", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataHandlerException("not implemented", + ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); } } @@ -239,8 +241,8 @@ public class ODataHandler { if (maxVersion != null) { if (ODataServiceVersion.isBiggerThan(ODataServiceVersion.V40.toString(), maxVersion)) { response.setStatusCode(400); - throw new ODataTranslatedException("ODataVersion not supported: " + maxVersion, - ODataTranslatedException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion); + throw new ODataHandlerException("ODataVersion not supported: " + maxVersion, + ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion); } } } @@ -252,8 +254,8 @@ public class ODataHandler { if (p == null) { response.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); - throw new ODataTranslatedException("Processor: " + cls.getName() + " not registered.", - ODataTranslatedException.MessageKeys.PROCESSOR_NOT_IMPLEMENTED, cls.getName()); + throw new ODataHandlerException("Processor: " + cls.getName() + " not registered.", + ODataHandlerException.MessageKeys.PROCESSOR_NOT_IMPLEMENTED, cls.getName()); } return p; diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerException.java new file mode 100644 index 000000000..589504cd8 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandlerException.java @@ -0,0 +1,44 @@ +/* + * 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; + +import org.apache.olingo.server.api.ODataTranslatedException; + +/** Exception thrown during basic request handling. */ +public class ODataHandlerException extends ODataTranslatedException { + private static final long serialVersionUID = -907752788975531134L; + + public static enum MessageKeys implements MessageKey { + /** parameters: HTTP method, HTTP method */ AMBIGUOUS_XHTTP_METHOD, + /** parameter: HTTP method */ HTTP_METHOD_NOT_IMPLEMENTED, + /** parameter: processor interface */ PROCESSOR_NOT_IMPLEMENTED, + FUNCTIONALITY_NOT_IMPLEMENTED, + /** parameter: version */ ODATA_VERSION_NOT_SUPPORTED + } + + public ODataHandlerException(final String developmentMessage, final MessageKey messageKey, + final String... parameters) { + super(developmentMessage, messageKey, parameters); + } + + public ODataHandlerException(final String developmentMessage, final Throwable cause, final MessageKey messageKey, + final String... parameters) { + super(developmentMessage, cause, messageKey, parameters); + } +} diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java index 3b7a7a289..436d54fbb 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java @@ -77,11 +77,11 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { private ODataResponse handleException(Exception e) { ODataResponse resp = new ODataResponse(); - if (e instanceof ODataTranslatedException) { - ODataTranslatedException exp = (ODataTranslatedException) e; - if (exp.getMessageKey() == ODataTranslatedException.MessageKeys.AMBIGUOUS_XHTTP_METHOD) { + if (e instanceof ODataHandlerException) { + ODataHandlerException exp = (ODataHandlerException) e; + if (exp.getMessageKey() == ODataHandlerException.MessageKeys.AMBIGUOUS_XHTTP_METHOD) { resp.setStatusCode(HttpStatusCode.BAD_REQUEST.getStatusCode()); - } else if (exp.getMessageKey() == ODataTranslatedException.MessageKeys.HTTP_METHOD_NOT_IMPLEMENTED) { + } else if (exp.getMessageKey() == ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_IMPLEMENTED) { resp.setStatusCode(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode()); } } @@ -156,8 +156,8 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { odRequest.setMethod(HttpMethod.valueOf(xHttpMethod)); } else { if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) { - throw new ODataTranslatedException("Ambiguous X-HTTP-Methods", - ODataTranslatedException.MessageKeys.AMBIGUOUS_XHTTP_METHOD, xHttpMethod, xHttpMethodOverride); + throw new ODataHandlerException("Ambiguous X-HTTP-Methods", + ODataHandlerException.MessageKeys.AMBIGUOUS_XHTTP_METHOD, xHttpMethod, xHttpMethodOverride); } odRequest.setMethod(HttpMethod.valueOf(xHttpMethod)); } @@ -165,8 +165,8 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { odRequest.setMethod(httpRequestMethod); } } catch (IllegalArgumentException e) { - throw new ODataTranslatedException("Invalid http method" + httpRequest.getMethod(), - ODataTranslatedException.MessageKeys.HTTP_METHOD_NOT_IMPLEMENTED, httpRequest.getMethod()); + throw new ODataHandlerException("Invalid HTTP method" + httpRequest.getMethod(), + ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_IMPLEMENTED, httpRequest.getMethod()); } } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java index 374c108ae..0c4d92c46 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java @@ -23,6 +23,7 @@ import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.misc.ParseCancellationException; @@ -140,7 +141,7 @@ public class Parser { context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource); for (PathSegmentEOFContext ctxPathSegment : ctxPathSegments) { - // add checks for batcvh entity metadata, all crossjsoin + // add checks for batch, entity, metadata, all, crossjoin uriParseTreeVisitor.visitPathSegmentEOF(ctxPathSegment); } @@ -186,8 +187,9 @@ public class Parser { || isFormatSyntaxValid(option)) { formatOption.setFormat(option.value); } else { - throw new UriParserSemanticException("Illegal value of $format option!", - UriParserSemanticException.MessageKeys.TEST); + throw new UriParserSyntaxException("Illegal value of $format option!", + UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION, + option.name, option.value); } context.contextUriInfo.setSystemQueryOption(formatOption); @@ -208,13 +210,13 @@ public class Parser { context.contextUriInfo.setSystemQueryOption(idOption); } else if (option.name.equals(SystemQueryOptionKind.LEVELS.toString())) { throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!", - UriParserSyntaxException.MessageKeys.TEST); + UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE); } else if (option.name.equals(SystemQueryOptionKind.ORDERBY.toString())) { - OrderByEOFContext ctxFilterExpression = + OrderByEOFContext ctxOrderByExpression = (OrderByEOFContext) parseRule(option.value, ParserEntryRules.Orderby); OrderByOptionImpl orderByOption = - (OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxFilterExpression); + (OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxOrderByExpression); context.contextUriInfo.setSystemQueryOption(orderByOption); } else if (option.name.equals(SystemQueryOptionKind.SEARCH.toString())) { @@ -234,8 +236,9 @@ public class Parser { try { skipOption.setValue(Integer.parseInt(option.value)); } catch (final NumberFormatException e) { - throw new UriParserSemanticException("Illegal value of $skip option!", e, - UriParserSemanticException.MessageKeys.TEST); + throw new UriParserSyntaxException("Illegal value of $skip option!", e, + UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION, + option.name, option.value); } context.contextUriInfo.setSystemQueryOption(skipOption); } else if (option.name.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) { @@ -251,8 +254,9 @@ public class Parser { try { topOption.setValue(Integer.parseInt(option.value)); } catch (final NumberFormatException e) { - throw new UriParserSemanticException("Illegal value of $top option!", e, - UriParserSemanticException.MessageKeys.TEST); + throw new UriParserSyntaxException("Illegal value of $top option!", e, + UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION, + option.name, option.value); } context.contextUriInfo.setSystemQueryOption(topOption); } else if (option.name.equals(SystemQueryOptionKind.COUNT.toString())) { @@ -262,13 +266,14 @@ public class Parser { if (option.value.equals("true") || option.value.equals("false")) { inlineCountOption.setValue(Boolean.parseBoolean(option.value)); } else { - throw new UriParserSemanticException("Illegal value of $count option!", - UriParserSemanticException.MessageKeys.TEST); + throw new UriParserSyntaxException("Illegal value of $count option!", + UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION, + option.name, option.value); } context.contextUriInfo.setSystemQueryOption(inlineCountOption); } else { throw new UriParserSyntaxException("Unknown system query option!", - UriParserSyntaxException.MessageKeys.TEST); + UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, option.name); } } } @@ -279,12 +284,10 @@ public class Parser { return context.contextUriInfo; } catch (ParseCancellationException e) { - Throwable cause = e.getCause(); - if (cause instanceof UriParserException) { - throw (UriParserException) cause; - } + throw e.getCause() instanceof UriParserException ? + (UriParserException) e.getCause() : + new UriParserSyntaxException("Syntax error", e, UriParserSyntaxException.MessageKeys.SYNTAX); } - return null; } private boolean isFormatSyntaxValid(RawUri.QueryOption option) { @@ -418,13 +421,15 @@ public class Parser { break; } - } catch (Exception weakException) { - throw new UriParserSyntaxException("Error in syntax", weakException, UriParserSyntaxException.MessageKeys.TEST); + } catch (final RecognitionException weakException) { + throw new UriParserSyntaxException("Error in syntax", weakException, + UriParserSyntaxException.MessageKeys.SYNTAX); // exceptionOnStage = 2; } - } catch (Exception hardException) { - throw new UriParserSyntaxException("Error in syntax", hardException, UriParserSyntaxException.MessageKeys.TEST); + } catch (final RecognitionException hardException) { + throw new UriParserSyntaxException("Error in syntax", hardException, + UriParserSyntaxException.MessageKeys.SYNTAX); } return ret; diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java index 13900d6c3..160cc2a5a 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java @@ -343,7 +343,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { tmp += (tmp.length() != 0 ? "," : "") + name; } throw wrap(new UriParserSemanticException("Function of functionimport '" + edmFunctionImport.getName() - + "' with parameters [" + tmp + "] not found", UriParserSemanticException.MessageKeys.TEST)); + + "' with parameters [" + tmp + "] not found", + UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, edmFunctionImport.getName(), tmp)); } uriResource.setFunction(edmFunctionImport.getUnboundFunction(names)); @@ -358,7 +359,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (lastResourcePart == null) { if (context.contextTypes.size() == 0) { throw wrap(new UriParserSemanticException("Resource part '" + odi + "' can only applied on typed " - + "resource parts", UriParserSemanticException.MessageKeys.TEST)); + + "resource parts", + UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS, odi)); } source = context.contextTypes.peek(); } else { @@ -366,7 +368,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (source.type == null) { throw wrap(new UriParserSemanticException("Resource part '" + odi + "' can only applied on typed " - + "resource parts", UriParserSemanticException.MessageKeys.TEST)); + + "resource parts", UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS, odi)); } } @@ -385,7 +387,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(source.type instanceof EdmStructuredType)) { throw wrap(new UriParserSemanticException("Can not parse'" + odi - + "'Previous path segment not a structural type.", UriParserSemanticException.MessageKeys.TEST)); + + "'Previous path segment not a structural type.", + UriParserSemanticException.MessageKeys.RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE, odi)); } EdmStructuredType structType = (EdmStructuredType) source.type; @@ -394,7 +397,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (property == null) { throw wrap(new UriParserSemanticException("Property '" + odi + "' not found in type '" + structType.getNamespace() + "." + structType.getName() + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE, + structType.getFullQualifiedName().toString(), odi)); } if (property instanceof EdmProperty) { @@ -419,7 +423,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { return null; } else { throw wrap(new UriParserSemanticException("Unkown type for property '" + property + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.UNKNOWN_PROPERTY_TYPE, property.getName())); } } else { // with namespace @@ -435,7 +439,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(filterEntityType.compatibleTo(source.type))) { throw wrap(new UriParserSemanticException( "Entity typefilter not compatible to previous path segment: " + fullFilterName.toString(), - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER, fullFilterName.toString())); } if (lastResourcePart == null) { @@ -461,7 +465,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '" + getName(filterEntityType) + "' behind '" + getName(lastPartWithKeys.getTypeFilterOnEntry()) + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartWithKeys.getTypeFilterOnEntry()), getName(filterEntityType))); } lastPartWithKeys.setEntryTypeFilter(filterEntityType); return null; @@ -470,7 +475,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { throw wrap(new UriParserSemanticException("Collection typefilters are not chainable, used '" + getName(filterEntityType) + "' behind '" + getName(lastPartWithKeys.getTypeFilterOnCollection()) + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartWithKeys.getTypeFilterOnCollection()), getName(filterEntityType))); } lastPartWithKeys.setCollectionTypeFilter(filterEntityType); return null; @@ -480,14 +486,17 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (lastPartTyped.getTypeFilter() != null) { throw wrap(new UriParserSemanticException("Typefilters are not chainable, used '" + getName(filterEntityType) + "' behind '" - + getName(lastPartTyped.getTypeFilter()) + "'", UriParserSemanticException.MessageKeys.TEST)); + + getName(lastPartTyped.getTypeFilter()) + "'", + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartTyped.getTypeFilter()), getName(filterEntityType))); } lastPartTyped.setTypeFilter(filterEntityType); return null; } else { throw wrap(new UriParserSemanticException("Path segment before '" + getName(filterEntityType) - + "' not typed", UriParserSemanticException.MessageKeys.TEST)); + + "' not typed", + UriParserSemanticException.MessageKeys.PREVIOUS_PART_NOT_TYPED, getName(filterEntityType))); } } } @@ -502,7 +511,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(filterComplexType.compatibleTo(source.type))) { throw wrap(new UriParserSemanticException( "Complex typefilter '" + getName(source.type) + "'not compatible type of previous path segment '" - + getName(filterComplexType) + "'", UriParserSemanticException.MessageKeys.TEST)); + + getName(filterComplexType) + "'", + UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER, getName(source.type))); } // is simple complex type cast @@ -529,7 +539,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '" + getName(filterComplexType) + "' behind '" + getName(lastPartWithKeys.getTypeFilterOnEntry()) + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartWithKeys.getTypeFilterOnEntry()), getName(filterComplexType))); } lastPartWithKeys.setEntryTypeFilter(filterComplexType); return null; @@ -538,7 +549,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { throw wrap(new UriParserSemanticException("Collection typefilters are not chainable, used '" + getName(filterComplexType) + "' behind '" + getName(lastPartWithKeys.getTypeFilterOnCollection()) + "'", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartWithKeys.getTypeFilterOnCollection()), getName(filterComplexType))); } lastPartWithKeys.setCollectionTypeFilter(filterComplexType); return null; @@ -549,14 +561,17 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (lastPartTyped.getTypeFilter() != null) { throw wrap(new UriParserSemanticException("Typefilters are not chainable, used '" + getName(filterComplexType) + "' behind '" - + getName(lastPartTyped.getTypeFilter()) + "'", UriParserSemanticException.MessageKeys.TEST)); + + getName(lastPartTyped.getTypeFilter()) + "'", + UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE, + getName(lastPartTyped.getTypeFilter()), getName(filterComplexType))); } lastPartTyped.setTypeFilter(filterComplexType); return null; } else { throw wrap(new UriParserSemanticException("Path segment before '" + getName(filterComplexType) - + "' not typed", UriParserSemanticException.MessageKeys.TEST)); + + "' not typed", + UriParserSemanticException.MessageKeys.PREVIOUS_PART_NOT_TYPED, getName(filterComplexType))); } } } @@ -576,7 +591,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { // do a check for bound functions (which requires a parameter list) if (ctx.vlNVO.size() == 0) { throw wrap(new UriParserSemanticException("Expected function parameters for '" + fullBindingTypeName.toString() - + "'", UriParserSemanticException.MessageKeys.TEST)); + + "'", + UriParserSemanticException.MessageKeys.FUNCTION_PARAMETERS_EXPECTED, fullBindingTypeName.toString())); } context.contextReadingFunctionParameters = true; @@ -618,7 +634,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { } throw wrap(new UriParserSemanticException("Unknown resource path segment:" + fullFilterName.toString(), - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.UNKNOWN_PART, fullFilterName.toString())); } } @@ -639,8 +655,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { UriResource obj = context.contextUriInfo.getLastResourcePart(); if (!(obj instanceof UriResourcePartTyped)) { - throw wrap(new UriParserSemanticException("any only allowed on typed path segments", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("all only allowed on typed path segments", + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "all")); } UriContext.LambdaVariables var = new UriContext.LambdaVariables(); @@ -780,7 +796,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { EdmEntityType type = edm.getEntityType(fullName); if (type == null) { throw wrap(new UriParserSemanticException("Expected EntityTypeName", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.UNKNOWN_ENTITY_TYPE, fullName.toString())); } context.contextUriInfo.setEntityTypeCast(type); @@ -866,7 +882,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { UriResourceImpl lastResourcePart = (UriResourceImpl) context.contextUriInfo.getLastResourcePart(); if (!(lastResourcePart instanceof UriResourcePartTyped)) { throw wrap(new UriParserSemanticException("any only allowed on typed path segments", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "any")); } UriContext.LambdaVariables var = new UriContext.LambdaVariables(); @@ -969,12 +985,12 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { context.contextUriInfo.addResourcePart(new UriResourceValueImpl()); } else { throw wrap(new UriParserSemanticException("$value only allowed on typed path segments", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$value")); } return null; } else { throw wrap(new UriParserSemanticException("$value only allowed on typed path segments", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$value")); } } else if (ctx.vC != null) { @@ -983,11 +999,11 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { context.contextUriInfo.addResourcePart(new UriResourceCountImpl()); } else { throw wrap(new UriParserSemanticException("$count only allowed on collection properties", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_COLLECTIONS, "$count")); } } else { throw wrap(new UriParserSemanticException("$count only allowed on typed properties", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$count")); } } else if (ctx.vR != null) { if (pathInfo instanceof UriResourcePartTyped) { @@ -995,12 +1011,12 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (type instanceof EdmEntityType) { context.contextUriInfo.addResourcePart(new UriResourceRefImpl()); } else { - throw wrap(new UriParserSemanticException("$ref only allowed on endity types", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("$ref only allowed on entity types", + UriParserSemanticException.MessageKeys.ONLY_FOR_ENTITY_TYPES, "$ref")); } } else { throw wrap(new UriParserSemanticException("$ref only allowed on typed properties", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PROPERTIES, "$ref")); } } else if (ctx.vAll != null) { @@ -1411,14 +1427,14 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { expression = (ExpressionImpl) ctx.vVO.accept(this); } catch (Exception ex) { throw wrap(new UriParserSemanticException("Invalid key value: " + valueText, - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, valueText)); } // get type of last resource part UriResource last = context.contextUriInfo.getLastResourcePart(); if (!(last instanceof UriResourcePartTyped)) { - throw wrap(new UriParserSemanticException("Paramterslist on untyped resource path segement not allowed", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Parameters list on untyped resource path segment not allowed", + UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS)); } EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType(); @@ -1439,16 +1455,16 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { // key. // for using referential constrains the last resource part must be a navigation property if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl)) { - throw wrap(new UriParserSemanticException("Not enougth keyproperties defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough key properties defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES)); } UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last; // get the partner of the navigation property EdmNavigationProperty partner = lastNav.getProperty().getPartner(); if (partner == null) { - throw wrap(new UriParserSemanticException("Not enougth keyproperties defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough key properties defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES)); } // create the keylist @@ -1466,8 +1482,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { missedKey = item; } else { // two of more keys are missing - throw wrap(new UriParserSemanticException("Not enougth referntial contrains defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough referential constraints defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_REFERENTIAL_CONSTRAINTS)); } } } @@ -1501,8 +1517,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { // get type of last resource part if (!(last instanceof UriResourcePartTyped)) { - throw wrap(new UriParserSemanticException("Parameterslist on untyped resource path segement not allowed", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Parameters list on untyped resource path segment not allowed", + UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS)); } EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType(); @@ -1517,16 +1533,16 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { // if not, check if the missing key predicates can be satisfied with help of the defined referential constrains // for using referential constrains the last resource part must be a navigation property if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl)) { - throw wrap(new UriParserSemanticException("Not enougth keyproperties defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough key properties defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES)); } UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last; // get the partner of the navigation property EdmNavigationProperty partner = lastNav.getProperty().getPartner(); if (partner == null) { - throw wrap(new UriParserSemanticException("Not enougth keyproperties defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough key properties defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES)); } // fill missing keys from referential constrains @@ -1553,8 +1569,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { return list; } - throw wrap(new UriParserSemanticException("Not enougth keyproperties defined", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Not enough key properties defined", + UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES)); } return new ArrayList(); } @@ -1658,8 +1674,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { .setKeyPredicates(list); } else { throw wrap(new UriParserSemanticException("Key properties not allowed", - UriParserSemanticException.MessageKeys.TEST)); - // throw UriSemanticError.addKrepredicatesNotAllowed(); + UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED)); } } @@ -1726,7 +1741,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { if (!(lastResource instanceof UriResourcePartTyped)) { throw wrap(new UriParserSemanticException("Resource path not typed", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.RESOURCE_PATH_NOT_TYPED)); } UriResourcePartTyped lastType = (UriResourcePartTyped) lastResource; @@ -1831,21 +1846,21 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { prevType = getTypeInformation(last).type; if (prevType == null) { - throw wrap(new UriParserSemanticException("prev segement not typed", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("prev segment not typed", + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "select")); } } if (!(prevType instanceof EdmStructuredType)) { throw wrap(new UriParserSemanticException("Previous select item is not a structural type", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_FOR_STRUCTURAL_TYPES, "select")); } EdmStructuredType structType = (EdmStructuredType) prevType; EdmElement element = structType.getProperty(odi); if (element == null) { throw wrap(new UriParserSemanticException("Previous select item has not property: " + odi, - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE, structType.getName(), odi)); } // create new segment @@ -1896,7 +1911,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { } } else { throw wrap(new UriParserSemanticException("Only Simple and Complex properties within select allowed", - UriParserSemanticException.MessageKeys.TEST)); + UriParserSemanticException.MessageKeys.ONLY_SIMPLE_AND_COMPLEX_PROPERTIES_IN_SELECT)); } } else { String namespace = ctx.vNS.getText(); @@ -1948,16 +1963,16 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { } } } else { - throw wrap(new UriParserSemanticException("prev segement must be comlex of entity type", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("prev segment must be complex of entity type", + UriParserSemanticException.MessageKeys.COMPLEX_PROPERTY_OF_ENTITY_TYPE_EXPECTED)); } } else { UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath(); UriResource last = uriInfo.getLastResourcePart(); if (!(last instanceof UriResourceTypedImpl)) { - throw wrap(new UriParserSemanticException("prev segement typed", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("prev segment typed", + UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "select")); } EdmType prevType = getTypeInformation(last).type; @@ -1973,7 +1988,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { } } } else if (prevType instanceof EdmEntityType) { - throw wrap(new UriParserSemanticException("Error", UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("Error", + UriParserSemanticException.MessageKeys.NOT_FOR_ENTITY_TYPE)); /* * EdmEntityType et = edm.getEntityType(fullName); * if (et != null) { @@ -1987,8 +2003,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { * } */ } else { - throw wrap(new UriParserSemanticException("prev segement must be comlex of entity type", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("prev segment must be complex of entity type", + UriParserSemanticException.MessageKeys.COMPLEX_PROPERTY_OF_ENTITY_TYPE_EXPECTED)); } } @@ -1999,8 +2015,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor { UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath(); UriResource last = uriInfo.getLastResourcePart(); if (!(last instanceof UriResourceTypedImpl)) { - throw wrap(new UriParserSemanticException("prev segement typed", - UriParserSemanticException.MessageKeys.TEST)); + throw wrap(new UriParserSemanticException("prev segment typed", + UriParserSemanticException.MessageKeys.PREVIOUS_PART_TYPED)); } prevType = getTypeInformation(last).type; } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserException.java index faa3c6346..5f509ce0b 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserException.java @@ -20,7 +20,7 @@ package org.apache.olingo.server.core.uri.parser; import org.apache.olingo.server.api.ODataTranslatedException; -public class UriParserException extends ODataTranslatedException { +abstract public class UriParserException extends ODataTranslatedException { private static final long serialVersionUID = -6438700016830955949L; diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java index 41d178f2a..7d742bc9a 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java @@ -18,12 +18,38 @@ */ package org.apache.olingo.server.core.uri.parser; +/** Exception thrown during URI parsing in cases where an URI part is invalid according to the Entity Data Model. */ public class UriParserSemanticException extends UriParserException { private static final long serialVersionUID = 3850285860949809622L; - + public static enum MessageKeys implements MessageKey { - TEST + /** parameters: function-import name, function parameters */ FUNCTION_NOT_FOUND, + /** parameter: resource part */ RESOURCE_PART_ONLY_FOR_TYPED_PARTS, + /** parameter: resource part */ RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE, + /** parameters: type name, property name */ PROPERTY_NOT_IN_TYPE, + /** parameter: property name */ UNKNOWN_PROPERTY_TYPE, + /** parameter: type filter */ INCOMPATIBLE_TYPE_FILTER, + /** parameters: previous type filter, last type filter */ TYPE_FILTER_NOT_CHAINABLE, + /** parameter: type filter */ PREVIOUS_PART_NOT_TYPED, + /** parameter: type */ FUNCTION_PARAMETERS_EXPECTED, + /** parameter: resource part */ UNKNOWN_PART, + /** parameter: expression */ ONLY_FOR_TYPED_PARTS, + /** parameter: entity type name */ UNKNOWN_ENTITY_TYPE, + /** parameter: expression */ ONLY_FOR_COLLECTIONS, + /** parameter: expression */ ONLY_FOR_ENTITY_TYPES, + /** parameter: expression */ ONLY_FOR_STRUCTURAL_TYPES, + /** parameter: expression */ ONLY_FOR_TYPED_PROPERTIES, + /** parameter: value */ INVALID_KEY_VALUE, + PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS, + NOT_ENOUGH_KEY_PROPERTIES, + NOT_ENOUGH_REFERENTIAL_CONSTRAINTS, + KEY_NOT_ALLOWED, + RESOURCE_PATH_NOT_TYPED, + ONLY_SIMPLE_AND_COMPLEX_PROPERTIES_IN_SELECT, + COMPLEX_PROPERTY_OF_ENTITY_TYPE_EXPECTED, + NOT_FOR_ENTITY_TYPE, + PREVIOUS_PART_TYPED } public UriParserSemanticException(String developmentMessage, MessageKey messageKey, String... parameters) { diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java index a7dfdd99a..393855b52 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java @@ -18,14 +18,18 @@ */ package org.apache.olingo.server.core.uri.parser; +/** Exception thrown during URI parsing in cases where the URI violates the URI construction rules. */ public class UriParserSyntaxException extends UriParserException { private static final long serialVersionUID = 5887744747812478226L; public static enum MessageKeys implements MessageKey { - TEST + /** parameter: query-option name */ UNKNOWN_SYSTEM_QUERY_OPTION, + /** parameters: query-option name, query-option value */ WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION, + SYNTAX, + SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE } - + public UriParserSyntaxException(String developmentMessage, MessageKey messageKey, String... parameters) { super(developmentMessage, messageKey, parameters); } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java index f17548382..d5c7c0ad1 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java @@ -50,7 +50,7 @@ public class UriValidationException extends ODataTranslatedException { /** parameter: unallowed kind before $value */ UNALLOWED_KIND_BEFORE_VALUE, /** parameter: unallowed kind before $count */ - UNALLOWED_KIND_BEFORE_COUNT, + UNALLOWED_KIND_BEFORE_COUNT } public UriValidationException(String developmentMessage, MessageKey messageKey, String... parameters) { diff --git a/lib/server-core/src/main/resources/i18n.properties b/lib/server-core/src/main/resources/i18n.properties new file mode 100644 index 000000000..1b603f40d --- /dev/null +++ b/lib/server-core/src/main/resources/i18n.properties @@ -0,0 +1,87 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +# Basic Apache Olingo exception messages +# +ODataHandlerException.AMBIGUOUS_XHTTP_METHOD=x-http-method header '%1$s' and x-http-method-override header '%2$s' are not the same. +ODataHandlerException.HTTP_METHOD_NOT_IMPLEMENTED=Invalid HTTP method given: '%1$s'. +ODataHandlerException.PROCESSOR_NOT_IMPLEMENTED=No processor for interface '%1$s' registered. +ODataHandlerException.FUNCTIONALITY_NOT_IMPLEMENTED=The requested functionality has not been implemented (yet). +ODataHandlerException.ODATA_VERSION_NOT_SUPPORTED=OData version '%1$s' is not supported. + +UriParserSyntaxException.UNKNOWN_SYSTEM_QUERY_OPTION=The system query option '%1$s' is not defined. +UriParserSyntaxException.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION=The system query option '%1$s' has the not-allowed value '%2$s'. +UriParserSyntaxException.SYNTAX=The URI is malformed. +UriParserSyntaxException.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE=The system query option '$levels' is not allowed here. + +UriParserSemanticException.FUNCTION_NOT_FOUND=The function import '%1$s' has no function with parameters '%2$s'. +UriParserSemanticException.RESOURCE_PART_ONLY_FOR_TYPED_PARTS='%1%s' is only allowed for typed parts. +UriParserSemanticException.RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE=The resource part '%1$s' must be preceded by a structural type. +UriParserSemanticException.PROPERTY_NOT_IN_TYPE=The type '%1$s' has no property '%2$s'. +UriParserSemanticException.UNKNOWN_PROPERTY_TYPE=The type of the property '%1$s' is unknown. +UriParserSemanticException.INCOMPATIBLE_TYPE_FILTER=The type filter '%1$s' is incompatible. +UriParserSemanticException.TYPE_FILTER_NOT_CHAINABLE=The type filter '%2$s' can not be chained with '%1$s'. +UriParserSemanticException.PREVIOUS_PART_NOT_TYPED=The previous part of the type filter '%1$s' is not typed. +UriParserSemanticException.FUNCTION_PARAMETERS_EXPECTED=Function parameters expected for type '%1$s'. +UriParserSemanticException.UNKNOWN_PART=The part '%1%s' is not defined. +UriParserSemanticException.ONLY_FOR_TYPED_PARTS='%1%s' is only allowed for typed parts. +UriParserSemanticException.UNKNOWN_ENTITY_TYPE=The entity type '%1%s' is not defined. +UriParserSemanticException.ONLY_FOR_COLLECTIONS='%1%s' is only allowed for collections. +UriParserSemanticException.ONLY_FOR_ENTITY_TYPES='%1%s' is only allowed for entity types. +UriParserSemanticException.ONLY_FOR_STRUCTURAL_TYPES='%1%s' is only allowed for structural types. +UriParserSemanticException.ONLY_FOR_TYPED_PROPERTIES='%1%s' is only allowed for typed properties. +UriParserSemanticException.INVALID_KEY_VALUE=The key value '%1$s' is invalid. +UriParserSemanticException.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS=A list of parameters is only allowed for typed parts. +UriParserSemanticException.NOT_ENOUGH_KEY_PROPERTIES=There are not enough key properties. +UriParserSemanticException.NOT_ENOUGH_REFERENTIAL_CONSTRAINTS=There are not enough referential constraints. +UriParserSemanticException.KEY_NOT_ALLOWED=A key is not allowed. +UriParserSemanticException.RESOURCE_PATH_NOT_TYPED=The resource path is not typed. +UriParserSemanticException.ONLY_SIMPLE_AND_COMPLEX_PROPERTIES_IN_SELECT=Only simple and complex properties are allowed in selection. +UriParserSemanticException.COMPLEX_PROPERTY_OF_ENTITY_TYPE_EXPECTED=A complex property of an entity type is expected. +UriParserSemanticException.NOT_FOR_ENTITY_TYPE=Not allowed for entity type. +UriParserSemanticException.PREVIOUS_PART_TYPED=The previous part is typed. + +UriValidationException.UNSUPPORTED_QUERY_OPTION=The query option '%1$s' is not supported. +UriValidationException.UNSUPPORTED_URI_KIND=The URI kind '%1$s' is not supported. +UriValidationException.UNSUPPORTED_URI_RESOURCE_KIND=The URI resource kind '%1$s' is not supported. +UriValidationException.UNSUPPORTED_FUNCTION_RETURN_TYPE=The function return type '%1$s' is not supported. +UriValidationException.UNSUPPORTED_ACTION_RETURN_TYPE=The action return type '%1$s' is not supported. +UriValidationException.UNSUPPORTED_HTTP_METHOD=The HTTP method '%1$s' is not supported. +UriValidationException.SYSTEM_QUERY_OPTION_NOT_ALLOWED=The system query option '%1$s' is not allowed. +UriValidationException.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD=The system query option '%1$s' is not allowed for HTTP method '%2$s'. +UriValidationException.INVALID_KEY_PROPERTY=The key property '%1$s' is invalid. +UriValidationException.LAST_SEGMENT_NOT_TYPED=The last segment '%1$s' is not typed. +UriValidationException.SECOND_LAST_SEGMENT_NOT_TYPED=The second last segment '%1$s' is not typed. +UriValidationException.UNALLOWED_KIND_BEFORE_VALUE=The kind '%1$s' is not allowed before '$value'. +UriValidationException.UNALLOWED_KIND_BEFORE_COUNT=The kind '%1$s' is not allowed before '$count'. + +ContentNegotiatorException.WRONG_CHARSET_IN_HEADER=The HTTP header '%1$s' with value '%2$s' contains an invalid character-set specification. +ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPES=The content-type range '%1$s' is not supported. +ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported. +ContentNegotiatorException.UNSUPPORTED_FORMAT_OPTION=The $format option '%1$s' is not supported. + +ODataSerializerException.NOT_IMPLEMENTED=The requested serialization method has not been implemented yet. +ODataSerializerException.UNSUPPORTED_FORMAT=The format '%1$s' is not supported. +ODataSerializerException.JSON_METADATA=The metadata document cannot be provided in JSON format. +ODataSerializerException.IO_EXCEPTION=An I/O exception occurred. +ODataSerializerException.NULL_INPUT=The input 'null' is not allowed here. +ODataSerializerException.NO_CONTEXT_URL=No context URL has been provided. +ODataSerializerException.UNSUPPORTED_PROPERTY_TYPE=The type of the property '%1$s' is not yet supported. +ODataSerializerException.INCONSISTENT_PROPERTY_TYPE=An inconsistency has been detected in the type definition of property '%1$s'. +ODataSerializerException.MISSING_PROPERTY=The non-nullable property '%1$s' is missing. +ODataSerializerException.WRONG_PROPERTY_VALUE=The value '%2$s' is not valid for property '%1$s'. diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java index 3e4dde47a..b35e40da5 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java @@ -29,6 +29,7 @@ import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ODataTranslatedException; @@ -42,6 +43,7 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.tecsvc.data.DataProvider; import java.util.List; +import java.util.Locale; public class TechnicalProcessor implements EntityCollectionProcessor, EntityProcessor { @@ -81,6 +83,8 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()); } catch (final ODataTranslatedException e) { response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()); + } catch (final ODataApplicationException e) { + response.setStatusCode(e.getStatusCode()); } } @@ -106,6 +110,8 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()); } catch (final ODataTranslatedException e) { response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()); + } catch (final ODataApplicationException e) { + response.setStatusCode(e.getStatusCode()); } } @@ -136,20 +142,20 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc && uriInfo.getTopOption() == null; } - private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataTranslatedException { + private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException { final List resourcePaths = uriInfo.getUriResourceParts(); if (resourcePaths.size() != 1) { - throw new ODataTranslatedException("Invalid resource path.", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataApplicationException("Invalid resource path.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) { - throw new ODataTranslatedException("Invalid resource type.", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataApplicationException("Invalid resource type.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0); if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) { - throw new ODataTranslatedException("Type filters are not supported.", - ODataTranslatedException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); + throw new ODataApplicationException("Type filters are not supported.", + HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); } return uriResource.getEntitySet(); } diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java index 423c685e9..60a0e1313 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java @@ -900,11 +900,11 @@ public class TestFullResourcePath { @Test public void runCrossjoinError() throws Exception { - testUri.runEx("$crossjoin").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); - testUri.runEx("$crossjoin/error").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); - testUri.runEx("$crossjoin()").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + testUri.runEx("$crossjoin").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + testUri.runEx("$crossjoin/error").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + testUri.runEx("$crossjoin()").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); // testUri.runEx("$crossjoin(ESKeyNav, ESTwoKeyNav)/invalid") - // .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + // .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); } @Test @@ -921,10 +921,10 @@ public class TestFullResourcePath { @Test public void runEntityIdError() { // TODO planned: move to validator - // testUri.runEx("$entity").isExSyntax(0); - // testUri.runEx("$entity?$idfalse=ESKeyNav(1)").isExSyntax(0); - // testUri.runEx("$entity/com.sap.odata.test1.invalidType?$id=ESKeyNav(1)").isExSemantic(0); - // testUri.runEx("$entity/invalid?$id=ESKeyNav(1)").isExSyntax(0); + // testUri.runEx("$entity").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + // testUri.runEx("$entity?$idfalse=ESKeyNav(1)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + // testUri.runEx("$entity/com.sap.odata.test1.invalidType?$id=ESKeyNav(1)").isExSemantic(); + // testUri.runEx("$entity/invalid?$id=ESKeyNav(1)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); } @Test @@ -947,44 +947,54 @@ public class TestFullResourcePath { @Test public void runEsNameError() { - testUri.runEx("ESAllPrim/$count/$ref").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim/$ref/$count").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim/$ref/invalid").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim/$count/invalid").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim(1)/whatever").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - // testUri.runEx("ESAllPrim(PropertyInt16='1')").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim(PropertyInt16)").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim(PropertyInt16=)").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); - testUri.runEx("ESAllPrim(PropertyInt16=1,Invalid='1')").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("ESAllPrim/$count/$ref") + .isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PROPERTIES); + testUri.runEx("ESAllPrim/$ref/$count") + .isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS); + testUri.runEx("ESAllPrim/$ref/invalid") + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); + testUri.runEx("ESAllPrim/$count/invalid") + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); + testUri.runEx("ESAllPrim(1)/whatever") + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); + // testUri.runEx("ESAllPrim(PropertyInt16='1')") + // .isExSemantic(UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE); + testUri.runEx("ESAllPrim(PropertyInt16)") + .isExSemantic(UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE); + testUri.runEx("ESAllPrim(PropertyInt16=)") + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); + testUri.runEx("ESAllPrim(PropertyInt16=1,Invalid='1')") + .isExSemantic(UriParserSemanticException.MessageKeys.NOT_ENOUGH_KEY_PROPERTIES); testUri.runEx("ETBaseTwoKeyTwoPrim/com.sap.odata.test1.ETBaseTwoKeyTwoPrim" - + "/com.sap.odata.test1.ETTwoBaseTwoKeyTwoPrim").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + + "/com.sap.odata.test1.ETTwoBaseTwoKeyTwoPrim") + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim/com.sap.odata.test1.ETBaseTwoKeyTwoPrim(1)/com.sap.odata.test1.ETAllKey") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim(1)/com.sap.odata.test1.ETBaseTwoKeyTwoPrim('1')/com.sap.odata.test1.ETAllKey") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim(1)/com.sap.odata.test1.ETBaseTwoKeyTwoPrim" + "/com.sap.odata.test1.ETTwoBaseTwoKeyTwoPrim") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim/com.sap.odata.test1.ETBaseTwoKeyTwoPrim" + "/com.sap.odata.test1.ETTwoBaseTwoKeyTwoPrim(1)") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim/com.sap.odata.test1.ETAllKey") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ETBaseTwoKeyTwoPrim()") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); testUri.runEx("ESAllNullable(1)/CollPropertyString/$value") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS); testUri.runEx("ETMixPrimCollComp(1)/ComplexProperty/$value") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS); } @Test @@ -1105,16 +1115,14 @@ public class TestFullResourcePath { @Test public void runEsNameKeyCast() throws Exception { - /* - * testUri.runEx("ESTwoPrim(1)/com.sap.odata.test1.ETBase(1)") - * .isExSemantic(UriParserSemanticException.MessageKeys.TEST); - * - * testUri.runEx("ESTwoPrim/com.sap.odata.test1.ETBase(1)/com.sap.odata.test1.ETTwoBase(1)") - * .isExSemantic(UriParserSemanticException.MessageKeys.TEST); - * - * testUri.runEx("ESBase/com.sap.odata.test1.ETTwoPrim(1)") - * .isExSemantic(UriParserSemanticException.MessageKeys.TEST); - */ + // testUri.runEx("ESTwoPrim(1)/com.sap.odata.test1.ETBase(1)") + // .isExSemantic(UriParserSemanticException.MessageKeys.xxx); + + // testUri.runEx("ESTwoPrim/com.sap.odata.test1.ETBase(1)/com.sap.odata.test1.ETTwoBase(1)") + // .isExSemantic(UriParserSemanticException.MessageKeys.xxx); + + testUri.runEx("ESBase/com.sap.odata.test1.ETTwoPrim(1)") + .isExSemantic(UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER); testUri.run("ESTwoPrim(1)/com.sap.odata.test1.ETBase") .isKind(UriInfoKind.resource).goPath() @@ -1806,8 +1814,10 @@ public class TestFullResourcePath { @Test public void runFunctionImpError() { - testUri.runEx("FICRTCollCTTwoPrimParam()").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("FICRTCollCTTwoPrimParam(invalidParam=2)").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("FICRTCollCTTwoPrimParam()") + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND); + testUri.runEx("FICRTCollCTTwoPrimParam(invalidParam=2)") + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND); } @Test @@ -2515,8 +2525,10 @@ public class TestFullResourcePath { .isEntitySet("ESKeyNav") .isTopText("-3"); - testUri.runEx("ESKeyNav?$top=undefined").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESKeyNav?$top=").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("ESKeyNav?$top=undefined") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESKeyNav?$top=") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); } @Test @@ -2540,11 +2552,16 @@ public class TestFullResourcePath { testUri.run("ESKeyNav(1)?$format=" + HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8) .isKind(UriInfoKind.resource).goPath() .isFormatText(HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8); - testUri.runEx("ESKeyNav(1)?$format=noSlash").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESKeyNav(1)?$format=slashAtEnd/").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESKeyNav(1)?$format=/startsWithSlash").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESKeyNav(1)?$format=two/Slashes/tooMuch").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESKeyNav(1)?$format=").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("ESKeyNav(1)?$format=noSlash") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESKeyNav(1)?$format=slashAtEnd/") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESKeyNav(1)?$format=/startsWithSlash") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESKeyNav(1)?$format=two/Slashes/tooMuch") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESKeyNav(1)?$format=") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); } @Test @@ -2556,8 +2573,10 @@ public class TestFullResourcePath { testUri.run("ESAllPrim?$count=false") .isKind(UriInfoKind.resource).goPath() .isInlineCountText("false"); - testUri.runEx("ESAllPrim?$count=undefined").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim?$count=").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("ESAllPrim?$count=undefined") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESAllPrim?$count=") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); } @Test @@ -2572,8 +2591,10 @@ public class TestFullResourcePath { testUri.run("ESAllPrim?$skip=-3") .isKind(UriInfoKind.resource).goPath() .isSkipText("-3"); - testUri.runEx("ESAllPrim?$skip=F").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testUri.runEx("ESAllPrim?$skip=").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("ESAllPrim?$skip=F") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); + testUri.runEx("ESAllPrim?$skip=") + .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION); } @Test @@ -2585,7 +2606,8 @@ public class TestFullResourcePath { @Test public void notExistingSystemQueryOption() throws Exception { - testUri.runEx("ESAllPrim?$wrong=error").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + testUri.runEx("ESAllPrim?$wrong=error") + .isExSyntax(UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION); } @Test @@ -2907,19 +2929,21 @@ public class TestFullResourcePath { .root().right() .isLiteral("'SomeString'"); - testFilter.runOnETTwoKeyNavEx("invalid").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testFilter.runOnETTwoKeyNavEx("PropertyComp/invalid").isExSemantic(UriParserSemanticException.MessageKeys.TEST); - testFilter.runOnETTwoKeyNavEx("concat('a','b')/invalid").isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + testFilter.runOnETTwoKeyNavEx("invalid") + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); + testFilter.runOnETTwoKeyNavEx("PropertyComp/invalid") + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); + testFilter.runOnETTwoKeyNavEx("concat('a','b')/invalid").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); testFilter.runOnETTwoKeyNavEx("PropertyComp/concat('a','b')") - .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); testFilter.runOnETTwoKeyNavEx("PropertyCompAllPrim/PropertyInt16 eq '1'") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); testFilter.runOnETTwoKeyNavEx("PropertyCompAllPrim/PropertyDate eq 1") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); testFilter.runOnETTwoKeyNavEx("PropertyCompAllPrim/PropertyString eq 1") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); testFilter.runOnETTwoKeyNavEx("PropertyCompAllPrim/PropertyDate eq 1") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); testFilter.runOnETAllPrim("PropertySByte eq PropertySByte") .is("< eq >") @@ -4118,7 +4142,7 @@ public class TestFullResourcePath { .goParameter(1).isTypedLiteral(EntityTypeProvider.nameETKeyPrimNav); testFilter.runOnETKeyNavEx("cast(NavPropertyETKeyPrimNavOne,com.sap.odata.test1.ETKeyNav)") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE); testFilter.runOnETKeyNav("any()") .isMember().goPath().first().isUriPathInfoKind(UriResourceKind.lambdaAny); @@ -5032,13 +5056,13 @@ public class TestFullResourcePath { .goOrder(0).right().isEnum(EnumTypeProvider.nameENString, Arrays.asList("String1")); testFilter.runOrderByOnETTwoKeyNavEx("PropertyInt16 1") - .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); testFilter.runOrderByOnETTwoKeyNavEx("PropertyInt16, PropertyInt32 PropertyDuration") - .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); testFilter.runOrderByOnETTwoKeyNavEx("PropertyInt16 PropertyInt32, PropertyDuration desc") - .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); testFilter.runOrderByOnETTwoKeyNavEx("PropertyInt16 asc, PropertyInt32 PropertyDuration desc") - .isExSyntax(UriParserSyntaxException.MessageKeys.TEST); + .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX); } @Test @@ -5081,52 +5105,53 @@ public class TestFullResourcePath { @Test public void testErrors() { testUri.runEx("FICRTString(wrong1='ABC')/com.sap.odata.test1.BFCStringRTESTwoKeyNav()") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND); testUri.runEx("FICRTString(wrong1='ABC', wrong2=1)/com.sap.odata.test1.BFCStringRTESTwoKeyNav()") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND); // type filter for entity incompatible testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/com.sap.odata.test1.ETBase") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER); // type filter for entity double on entry testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')" + "/com.sap.odata.test1.ETBaseTwoKeyNav/com.sap.odata.test1.ETBaseTwoKeyNav") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); // type filter for entity double on collection testUri.runEx("ESTwoKeyNav/com.sap.odata.test1.ETBaseTwoKeyNav/com.sap.odata.test1.ETBaseTwoKeyNav") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); // type filter for entity double on non key pred testUri.runEx("SINav/com.sap.odata.test1.ETBaseTwoKeyNav/com.sap.odata.test1.ETBaseTwoKeyNav") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); // type filter for complex incompatible testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim" - + "/com.sap.odata.test1.CTCollAllPrim").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + + "/com.sap.odata.test1.CTCollAllPrim") + .isExSemantic(UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER); // type filter for complex double on entry testUri.runEx("FICRTCTTwoPrimParam(ParameterInt16=1,ParameterString='2')" + "/com.sap.odata.test1.CTBase/com.sap.odata.test1.CTBase") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); // type filter for complex double on collection testUri.runEx("FICRTCollCTTwoPrimParam(ParameterInt16=1,ParameterString='2')" + "/com.sap.odata.test1.CTBase/com.sap.odata.test1.CTBase") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); // type filter for complex double on non key pred testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim" + "/com.sap.odata.test1.CTBase/com.sap.odata.test1.CTBase") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE); testUri.runEx("ESTwoKeyNav/com.sap.odata.test1.BFCESTwoKeyNavRTESTwoKeyNav") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_PARAMETERS_EXPECTED); // $ref testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim/$ref") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_ENTITY_TYPES); testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim/$count") - .isExSemantic(UriParserSemanticException.MessageKeys.TEST); + .isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_COLLECTIONS); } @Test diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java index e4f771b66..89d3853f8 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java @@ -189,7 +189,8 @@ public class TestUriParserImpl { .isAction("UARTETParam") .isType(EntityTypeProvider.nameETTwoKeyTwoPrim, false); - testUri.runEx("AIRTPrimParam/invalidElement").isExSemantic(UriParserSemanticException.MessageKeys.TEST); + testUri.runEx("AIRTPrimParam/invalidElement") + .isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE); } @Test diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java index eff346f57..a3e0edd52 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java @@ -25,6 +25,7 @@ import org.apache.olingo.server.core.edm.provider.EdmProviderImpl; import org.apache.olingo.server.core.uri.parser.Parser; import org.apache.olingo.server.core.uri.parser.UriParserException; import org.apache.olingo.server.core.uri.parser.UriParserSemanticException; +import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; import org.junit.Before; import org.junit.Test; @@ -298,17 +299,17 @@ public class UriValidatorTest { parseAndValidate(uri, HttpMethod.GET); } - @Test(expected = UriParserSemanticException.class) + @Test(expected = UriParserSyntaxException.class) public void validateCountInvalid() throws Exception { parseAndValidate("ESAllPrim?$count=foo", HttpMethod.GET); } - @Test(expected = UriParserSemanticException.class) + @Test(expected = UriParserSyntaxException.class) public void validateTopInvalid() throws Exception { parseAndValidate("ESAllPrim?$top=foo", HttpMethod.GET); } - @Test(expected = UriParserSemanticException.class) + @Test(expected = UriParserSyntaxException.class) public void validateSkipInvalid() throws Exception { parseAndValidate("ESAllPrim?$skip=foo", HttpMethod.GET); }