CAMEL-8799: Make it possible for JsonPath to suppress PathNotFoundException
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/97329383 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/97329383 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/97329383 Branch: refs/heads/master Commit: 9732938301d96bc4e06101a7b95860d9446e03cc Parents: 0654622 Author: Claus Ibsen <davscl...@apache.org> Authored: Sat May 30 10:39:33 2015 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Sat May 30 10:39:33 2015 +0200 ---------------------------------------------------------------------- .../camel/builder/ExpressionClauseSupport.java | 33 +++++++++- .../model/language/JsonPathExpression.java | 19 ++++++ .../org/apache/camel/jsonpath/JsonPath.java | 5 ++ .../JsonPathAnnotationExpressionFactory.java | 3 + .../apache/camel/jsonpath/JsonPathEngine.java | 16 +++-- .../camel/jsonpath/JsonPathExpression.java | 20 ++++++- .../camel/jsonpath/JsonPathBeanOptionTest.java | 63 -------------------- .../JsonPathBeanSuppressExceptionsTest.java | 62 +++++++++++++++++++ 8 files changed, 152 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java index d0fa176..a40b932 100644 --- a/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java +++ b/camel-core/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java @@ -333,7 +333,21 @@ public class ExpressionClauseSupport<T> { * @return the builder to continue processing the DSL */ public T jsonpath(String text) { - return expression(new JsonPathExpression(text)); + return jsonpath(text, false); + } + + /** + * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path + * expression</a> + * + * @param text the expression to be evaluated + * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException + * @return the builder to continue processing the DSL + */ + public T jsonpath(String text, boolean suppressExceptions) { + JsonPathExpression expression = new JsonPathExpression(text); + expression.setSuppressExceptions(suppressExceptions); + return expression(expression); } /** @@ -352,6 +366,23 @@ public class ExpressionClauseSupport<T> { } /** + * Evaluates a <a href="http://camel.apache.org/jsonpath.html">Json Path + * expression</a> + * + * @param text the expression to be evaluated + * @param suppressExceptions whether to suppress exceptions such as PathNotFoundException + * @param resultType the return type expected by the expression + * @return the builder to continue processing the DSL + */ + public T jsonpath(String text, boolean suppressExceptions, Class<?> resultType) { + JsonPathExpression expression = new JsonPathExpression(text); + expression.setSuppressExceptions(suppressExceptions); + expression.setResultType(resultType); + setExpressionType(expression); + return result; + } + + /** * Evaluates a <a href="http://commons.apache.org/jxpath/">JXPath expression</a> * * @param text the expression to be evaluated http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java b/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java index 3d37b92..f5a7dd7 100644 --- a/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java +++ b/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java @@ -42,6 +42,8 @@ public class JsonPathExpression extends ExpressionDefinition { private String resultTypeName; @XmlTransient private Class<?> resultType; + @XmlAttribute @Metadata(defaultValue = "false") + private Boolean suppressExceptions; public JsonPathExpression() { } @@ -72,6 +74,17 @@ public class JsonPathExpression extends ExpressionDefinition { this.resultType = resultType; } + public Boolean getSuppressExceptions() { + return suppressExceptions; + } + + /** + * Whether to suppress exceptions such as PathNotFoundException. + */ + public void setSuppressExceptions(Boolean suppressExceptions) { + this.suppressExceptions = suppressExceptions; + } + public String getLanguage() { return "jsonpath"; } @@ -93,6 +106,9 @@ public class JsonPathExpression extends ExpressionDefinition { if (resultType != null) { setProperty(expression, "resultType", resultType); } + if (suppressExceptions != null) { + setProperty(expression, "suppressExceptions", suppressExceptions); + } super.configureExpression(camelContext, expression); } @@ -101,6 +117,9 @@ public class JsonPathExpression extends ExpressionDefinition { if (resultType != null) { setProperty(predicate, "resultType", resultType); } + if (suppressExceptions != null) { + setProperty(predicate, "suppressExceptions", suppressExceptions); + } super.configurePredicate(camelContext, predicate); } http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java index eae308d..0bca294 100644 --- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java +++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java @@ -41,6 +41,11 @@ public @interface JsonPath { String value(); /** + * Whether to suppress exceptions such as PathNotFoundException + */ + boolean suppressExceptions() default false; + + /** * To configure the json path options to use */ Option[] options() default {}; http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java index b56257a..8c314c5 100644 --- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java +++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java @@ -39,6 +39,9 @@ public class JsonPathAnnotationExpressionFactory extends DefaultAnnotationExpres if (annotation instanceof JsonPath) { JsonPath jsonPathAnnotation = (JsonPath) annotation; + + answer.setSuppressExceptions(jsonPathAnnotation.suppressExceptions()); + Option[] options = jsonPathAnnotation.options(); answer.setOptions(options); } http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java index f73315e..363492d 100644 --- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java +++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java @@ -40,15 +40,23 @@ public class JsonPathEngine { private final Configuration configuration; public JsonPathEngine(String expression) { - this(expression, null); + this(expression, false, null); } - public JsonPathEngine(String expression, Option[] options) { + public JsonPathEngine(String expression, boolean suppressExceptions, Option[] options) { Defaults defaults = DefaultsImpl.INSTANCE; if (options != null) { - this.configuration = Configuration.builder().jsonProvider(defaults.jsonProvider()).options(options).build(); + Configuration.ConfigurationBuilder builder = Configuration.builder().jsonProvider(defaults.jsonProvider()).options(options); + if (suppressExceptions) { + builder.options(Option.SUPPRESS_EXCEPTIONS); + } + this.configuration = builder.build(); } else { - this.configuration = Configuration.builder().jsonProvider(defaults.jsonProvider()).build(); + Configuration.ConfigurationBuilder builder = Configuration.builder().jsonProvider(defaults.jsonProvider()); + if (suppressExceptions) { + builder.options(Option.SUPPRESS_EXCEPTIONS); + } + this.configuration = builder.build(); } this.path = JsonPath.compile(expression); } http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java index d4fa8b3..3f84938 100644 --- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java +++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java @@ -28,6 +28,7 @@ public class JsonPathExpression extends ExpressionAdapter { private JsonPathEngine engine; private Class<?> resultType; + private boolean suppressExceptions; private Option[] options; public JsonPathExpression(String expression) { @@ -36,7 +37,7 @@ public class JsonPathExpression extends ExpressionAdapter { public void init() { try { - engine = new JsonPathEngine(expression, options); + engine = new JsonPathEngine(expression, suppressExceptions, options); } catch (Exception e) { throw new ExpressionIllegalSyntaxException(expression, e); } @@ -46,14 +47,31 @@ public class JsonPathExpression extends ExpressionAdapter { return resultType; } + /** + * To configure the result type to use + */ public void setResultType(Class<?> resultType) { this.resultType = resultType; } + public boolean isSuppressExceptions() { + return suppressExceptions; + } + + /** + * Whether to suppress exceptions such as PathNotFoundException + */ + public void setSuppressExceptions(boolean suppressExceptions) { + this.suppressExceptions = suppressExceptions; + } + public Option[] getOptions() { return options; } + /** + * To configure the json path options to use + */ public void setOptions(Option[] options) { this.options = options; } http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanOptionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanOptionTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanOptionTest.java deleted file mode 100644 index b8e761a..0000000 --- a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanOptionTest.java +++ /dev/null @@ -1,63 +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.camel.jsonpath; - -import com.jayway.jsonpath.Option; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.Test; - -public class JsonPathBeanOptionTest extends CamelTestSupport { - - @Test - public void testFullName() throws Exception { - String json = "{\"person\" : {\"firstname\" : \"foo\", \"middlename\" : \"foo2\", \"lastname\" : \"bar\"}}"; - getMockEndpoint("mock:result").expectedBodiesReceived("foo foo2 bar"); - template.sendBody("direct:start", json); - assertMockEndpointsSatisfied(); - } - - @Test - public void testFirstAndLastName() throws Exception { - String json = "{\"person\" : {\"firstname\" : \"foo\", \"lastname\" : \"bar\"}}"; - getMockEndpoint("mock:result").expectedBodiesReceived("foo bar"); - template.sendBody("direct:start", json); - assertMockEndpointsSatisfied(); - } - - @Override - protected RouteBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - from("direct:start").bean(FullNameBean.class).to("mock:result"); - } - }; - } - - protected static class FullNameBean { - // middle name is optional - public static String getName(@JsonPath("person.firstname") String first, - @JsonPath(value = "person.middlename", options = Option.SUPPRESS_EXCEPTIONS) String middle, - @JsonPath("person.lastname") String last) { - if (middle != null) { - return first + " " + middle + " " + last; - } - return first + " " + last; - } - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/97329383/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanSuppressExceptionsTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanSuppressExceptionsTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanSuppressExceptionsTest.java new file mode 100644 index 0000000..20541a2 --- /dev/null +++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathBeanSuppressExceptionsTest.java @@ -0,0 +1,62 @@ +/** + * 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.camel.jsonpath; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class JsonPathBeanSuppressExceptionsTest extends CamelTestSupport { + + @Test + public void testFullName() throws Exception { + String json = "{\"person\" : {\"firstname\" : \"foo\", \"middlename\" : \"foo2\", \"lastname\" : \"bar\"}}"; + getMockEndpoint("mock:result").expectedBodiesReceived("foo foo2 bar"); + template.sendBody("direct:start", json); + assertMockEndpointsSatisfied(); + } + + @Test + public void testFirstAndLastName() throws Exception { + String json = "{\"person\" : {\"firstname\" : \"foo\", \"lastname\" : \"bar\"}}"; + getMockEndpoint("mock:result").expectedBodiesReceived("foo bar"); + template.sendBody("direct:start", json); + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").bean(FullNameBean.class).to("mock:result"); + } + }; + } + + protected static class FullNameBean { + // middle name is optional + public static String getName(@JsonPath("person.firstname") String first, + @JsonPath(value = "person.middlename", suppressExceptions = true) String middle, + @JsonPath("person.lastname") String last) { + if (middle != null) { + return first + " " + middle + " " + last; + } + return first + " " + last; + } + } +}