This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 4b327ed  CAMEL-15122: camel-jslt - providing custom object filtering 
(#3863)
4b327ed is described below

commit 4b327ed8726251bf91c8c71871ca7cdc01d33b38
Author: jflabatBCSS <65955832+jflabatb...@users.noreply.github.com>
AuthorDate: Thu May 28 06:00:35 2020 +0200

    CAMEL-15122: camel-jslt - providing custom object filtering (#3863)
---
 .../component/jslt/JsltComponentConfigurer.java    |  5 ++
 .../org/apache/camel/component/jslt/jslt.json      |  3 +-
 .../camel-jslt/src/main/docs/jslt-component.adoc   |  3 +-
 .../apache/camel/component/jslt/JsltComponent.java | 16 ++++-
 .../apache/camel/component/jslt/JsltEndpoint.java  | 42 ++++++++----
 .../camel/component/jslt/JsltObjectFilterTest.java | 76 ++++++++++++++++++++++
 .../camel/component/jslt/objectFilter/input.json   | 13 ++++
 .../camel/component/jslt/objectFilter/output.json  |  1 +
 .../jslt/objectFilter/transformation.json          |  7 ++
 9 files changed, 152 insertions(+), 14 deletions(-)

diff --git 
a/components/camel-jslt/src/generated/java/org/apache/camel/component/jslt/JsltComponentConfigurer.java
 
b/components/camel-jslt/src/generated/java/org/apache/camel/component/jslt/JsltComponentConfigurer.java
index 05cc16a..71f49a2 100644
--- 
a/components/camel-jslt/src/generated/java/org/apache/camel/component/jslt/JsltComponentConfigurer.java
+++ 
b/components/camel-jslt/src/generated/java/org/apache/camel/component/jslt/JsltComponentConfigurer.java
@@ -26,6 +26,8 @@ public class JsltComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "functions": target.setFunctions(property(camelContext, 
java.util.Collection.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "objectfilter":
+        case "objectFilter": target.setObjectFilter(property(camelContext, 
com.schibsted.spt.data.jslt.filters.JsonFilter.class, value)); return true;
         default: return false;
         }
     }
@@ -37,6 +39,7 @@ public class JsltComponentConfigurer extends 
PropertyConfigurerSupport implement
         answer.put("basicPropertyBinding", boolean.class);
         answer.put("functions", java.util.Collection.class);
         answer.put("lazyStartProducer", boolean.class);
+        answer.put("objectFilter", 
com.schibsted.spt.data.jslt.filters.JsonFilter.class);
         return answer;
     }
 
@@ -51,6 +54,8 @@ public class JsltComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "functions": return target.getFunctions();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "objectfilter":
+        case "objectFilter": return target.getObjectFilter();
         default: return null;
         }
     }
diff --git 
a/components/camel-jslt/src/generated/resources/org/apache/camel/component/jslt/jslt.json
 
b/components/camel-jslt/src/generated/resources/org/apache/camel/component/jslt/jslt.json
index 7f39648..7e90455 100644
--- 
a/components/camel-jslt/src/generated/resources/org/apache/camel/component/jslt/jslt.json
+++ 
b/components/camel-jslt/src/generated/resources/org/apache/camel/component/jslt/jslt.json
@@ -24,7 +24,8 @@
     "allowTemplateFromHeader": { "kind": "property", "displayName": "Allow 
Template From Header", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, 
"defaultValue": "false", "description": "Whether to allow to use resource 
template from header or not (default false). Enabling this allows to specify 
dynamic templates via message header. However this can be seen as a potential 
security vulnerability if the he [...]
     "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a producer may otherwise 
fail during starting and cause the r [...]
     "basicPropertyBinding": { "kind": "property", "displayName": "Basic 
Property Binding", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, 
"defaultValue": false, "description": "Whether the component should use basic 
property binding (Camel 2.x) or the newer property binding with additional 
capabilities" },
-    "functions": { "kind": "property", "displayName": "Functions", "group": 
"advanced", "label": "advanced", "required": false, "type": "array", 
"javaType": "java.util.Collection<com.schibsted.spt.data.jslt.Function>", 
"deprecated": false, "secret": false, "description": "JSLT can be extended by 
plugging in functions written in Java." }
+    "functions": { "kind": "property", "displayName": "Functions", "group": 
"advanced", "label": "advanced", "required": false, "type": "array", 
"javaType": "java.util.Collection<com.schibsted.spt.data.jslt.Function>", 
"deprecated": false, "secret": false, "description": "JSLT can be extended by 
plugging in functions written in Java." },
+    "objectFilter": { "kind": "property", "displayName": "Object Filter", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "com.schibsted.spt.data.jslt.filters.JsonFilter", "deprecated": 
false, "secret": false, "description": "JSLT can be extended by plugging in a 
custom jslt object filter" }
   },
   "properties": {
     "resourceUri": { "kind": "path", "displayName": "Resource Uri", "group": 
"producer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "secret": 
false, "description": "Path to the resource. You can prefix with: classpath, 
file, http, ref, or bean. classpath, file and http loads the resource using 
these protocols (classpath is default). ref will lookup the resource in the 
registry. bean will call a method on a  [...]
diff --git a/components/camel-jslt/src/main/docs/jslt-component.adoc 
b/components/camel-jslt/src/main/docs/jslt-component.adoc
index 85e2d8e..52a6721 100644
--- a/components/camel-jslt/src/main/docs/jslt-component.adoc
+++ b/components/camel-jslt/src/main/docs/jslt-component.adoc
@@ -50,7 +50,7 @@ format, `?option=value&option=value&...`
 
 
 // component options: START
-The JSLT component supports 4 options, which are listed below.
+The JSLT component supports 5 options, which are listed below.
 
 
 
@@ -61,6 +61,7 @@ The JSLT component supports 4 options, which are listed below.
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *basicPropertyBinding* (advanced) | Whether the component should use basic 
property binding (Camel 2.x) or the newer property binding with additional 
capabilities | false | boolean
 | *functions* (advanced) | JSLT can be extended by plugging in functions 
written in Java. |  | Collection
+| *objectFilter* (advanced) | JSLT can be extended by plugging in a custom 
jslt object filter |  | JsonFilter
 |===
 // component options: END
 
diff --git 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltComponent.java
 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltComponent.java
index d79c8a7..3a42457 100644
--- 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltComponent.java
+++ 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltComponent.java
@@ -19,18 +19,22 @@ package org.apache.camel.component.jslt;
 import java.util.Collection;
 import java.util.Map;
 
-import com.schibsted.spt.data.jslt.Function;
 import org.apache.camel.Endpoint;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 import org.apache.camel.support.ResourceHelper;
 
+import com.schibsted.spt.data.jslt.Function;
+import com.schibsted.spt.data.jslt.filters.JsonFilter;
+
 @Component("jslt")
 public class JsltComponent extends DefaultComponent {
 
     @Metadata(label = "advanced")
     private Collection<Function> functions;
+    @Metadata(label = "advanced")
+    private JsonFilter objectFilter;
     @Metadata(defaultValue = "false")
     private boolean allowTemplateFromHeader;
 
@@ -80,4 +84,14 @@ public class JsltComponent extends DefaultComponent {
         this.allowTemplateFromHeader = allowTemplateFromHeader;
     }
 
+    /**
+    * JSLT can be extended by plugging in a custom jslt object filter
+    */
+    public JsonFilter getObjectFilter() {
+        return objectFilter;
+    }
+
+    public void setObjectFilter(JsonFilter objectFilter) {
+        this.objectFilter = objectFilter;
+    }
 }
diff --git 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
index 53370ea..15cecdb 100644
--- 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
+++ 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
@@ -16,14 +16,21 @@
  */
 package org.apache.camel.component.jslt;
 
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.schibsted.spt.data.jslt.Expression;
 import com.schibsted.spt.data.jslt.Function;
+import com.schibsted.spt.data.jslt.JsltException;
 import com.schibsted.spt.data.jslt.Parser;
+import com.schibsted.spt.data.jslt.filters.JsonFilter;
 import org.apache.camel.Category;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
@@ -72,19 +79,32 @@ public class JsltEndpoint extends ResourceEndpoint {
             }
 
             String jsltStringFromHeader = allowTemplateFromHeader ? 
msg.getHeader(JsltConstants.HEADER_JSLT_STRING, String.class) : null;
-            Collection<Function> functions = 
((JsltComponent)getComponent()).getFunctions();
-
-            if (jsltStringFromHeader != null) {
-                if (functions == null) {
-                    this.transform = 
Parser.compileString(jsltStringFromHeader);
+            Collection<Function> functions = ((JsltComponent) 
getComponent()).getFunctions();
+            JsonFilter objectFilter = ((JsltComponent) 
getComponent()).getObjectFilter();
+
+            Parser parser;
+            InputStream stream = null;
+            try {
+                if (jsltStringFromHeader != null) {
+                    parser = new Parser(new 
StringReader(jsltStringFromHeader)).withSource("<inline>");
                 } else {
-                    this.transform = 
Parser.compileString(jsltStringFromHeader, functions);
+                    stream = 
JsltEndpoint.class.getClassLoader().getResourceAsStream(getResourceUri());
+                    if (stream == null) {
+                        throw new JsltException("Cannot load resource '" + 
getResourceUri() + "': not found");
+                    }
+                    Reader reader = new InputStreamReader(stream, 
StandardCharsets.UTF_8);
+                    parser = new Parser(reader).withSource(getResourceUri());
                 }
-            } else {
-                if (functions == null) {
-                    this.transform = Parser.compileResource(getResourceUri());
-                } else {
-                    this.transform = Parser.compileResource(getResourceUri(), 
functions);
+                if (functions != null) {
+                    parser = parser.withFunctions(functions);
+                }
+                if (objectFilter != null) {
+                    parser = parser.withObjectFilter(objectFilter);
+                }
+                this.transform = parser.compile();
+            } finally {
+                if(stream != null){
+                    stream.close();
                 }
             }
         }
diff --git 
a/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltObjectFilterTest.java
 
b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltObjectFilterTest.java
new file mode 100644
index 0000000..46b1275
--- /dev/null
+++ 
b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltObjectFilterTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.component.jslt;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.test.junit4.CamelTestSupport;
+
+import com.schibsted.spt.data.jslt.Expression;
+import com.schibsted.spt.data.jslt.Parser;
+import com.schibsted.spt.data.jslt.filters.JsltJsonFilter;
+import com.schibsted.spt.data.jslt.filters.JsonFilter;
+import org.apache.camel.util.IOHelper;
+import org.junit.Test;
+
+public class JsltObjectFilterTest extends CamelTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        context.getPropertiesComponent().setLocation("ref:prop");
+
+        context.getComponent("jslt", 
JsltComponent.class).setObjectFilter(createObjectFilter());
+
+        return context;
+    }
+
+    @Test
+    public void testJsltAsInputStream() throws Exception {
+        getMockEndpoint("mock:result").expectedMinimumMessageCount(1);
+        getMockEndpoint("mock:result").expectedBodiesReceived(
+                IOHelper.loadText(
+                        ResourceHelper.resolveMandatoryResourceAsInputStream(
+                                context, 
"org/apache/camel/component/jslt/objectFilter/output.json")
+                ).trim() // Remove the last newline added by 
IOHelper.loadText()
+        );
+
+        sendBody("direct://start",
+                ResourceHelper.resolveMandatoryResourceAsInputStream(
+                        context, 
"org/apache/camel/component/jslt/objectFilter/input.json"));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    private JsonFilter createObjectFilter() {
+        Expression filterExpression = Parser.compileString(". != null and . != 
{}");
+        return new JsltJsonFilter(filterExpression);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct://start")
+                        
.to("jslt:org/apache/camel/component/jslt/objectFilter/transformation.json")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/input.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/input.json
new file mode 100644
index 0000000..d6d7fe7
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/input.json
@@ -0,0 +1,13 @@
+{
+  "name": {
+    "firstname": "foo"
+  },
+  "list": [
+    {
+      "value": 1
+    },
+    {
+      "value": 2
+    }
+  ]
+}
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/output.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/output.json
new file mode 100644
index 0000000..d307513
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/output.json
@@ -0,0 +1 @@
+{"list":[]}
\ No newline at end of file
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/transformation.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/transformation.json
new file mode 100644
index 0000000..a780b7f
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/objectFilter/transformation.json
@@ -0,0 +1,7 @@
+{
+  "name": {
+    * - firstname: .
+  },
+  "list": [for(.list) . if(.value > 2)],
+  "shoudBeRemoved": .name.lastname
+}
\ No newline at end of file

Reply via email to