Skip to content

Commit

Permalink
#3503 Add xslt.features support
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Istomin authored and Istomin committed Feb 8, 2022
1 parent c8c39c0 commit 5927609
Show file tree
Hide file tree
Showing 15 changed files with 221 additions and 4 deletions.
26 changes: 26 additions & 0 deletions docs/modules/ROOT/pages/reference/extensions/xslt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ Scheme-less URIs are interpreted as `classpath:` URIs.

Only `classpath:` URIs are supported on Quarkus. `file:`, `http:` and other kinds of URIs do not work by design.

=== Configuration
TransformerFactory features can be configured using following property:
[source,properties]
----
quarkus.camel.xslt.features."http\://javax.xml.XMLConstants/feature/secure-processing"=false
----
=== Extension functions support
https://xml.apache.org/xalan-j/extensions.html[Xalan's extension functions]
do work properly only when:

1. Secure-processing is disabled
2. Functions are defined in a separate jar
3. Functions are augmented during native build phase. For example, they can be registered for reflection:
[source,java]
----
@RegisterForReflection(targets = { my.Functions.class })
public class FunctionsConfiguration {
}
----

[NOTE]
====
The content of the XSLT source URIs is parsed and compiled into Java classes at build time. These Java classes are the
Expand Down Expand Up @@ -82,6 +102,12 @@ A comma separated list of templates to compile.
The package name for the generated classes.
| `string`
| `org.apache.camel.quarkus.component.xslt.generated`

|icon:lock[title=Fixed at build time] [[quarkus.camel.xslt.features]]`link:#quarkus.camel.xslt.features[quarkus.camel.xslt.features]`

TransformerFactory features.
| ``Map<String,Boolean>``
|
|===

[.configuration-legend]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.transform.TransformerException;
Expand Down Expand Up @@ -102,6 +103,11 @@ void xsltResources(

try {
TransformerFactory tf = new XalanTransformerFactory();

for (Map.Entry<String, Boolean> entry : config.features.entrySet()) {
tf.setFeature(entry.getKey(), entry.getValue());
}

tf.setAttribute("generate-translet", true);
tf.setAttribute("translet-name", resolvedUri.transletClassName);
tf.setAttribute("package-name", config.packageName);
Expand Down
20 changes: 20 additions & 0 deletions extensions/xslt/runtime/src/main/doc/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ Scheme-less URIs are interpreted as `classpath:` URIs.

Only `classpath:` URIs are supported on Quarkus. `file:`, `http:` and other kinds of URIs do not work by design.

=== Configuration
TransformerFactory features can be configured using following property:
[source,properties]
----
quarkus.camel.xslt.features."http\://javax.xml.XMLConstants/feature/secure-processing"=false
----
=== Extension functions support
https://xml.apache.org/xalan-j/extensions.html[Xalan's extension functions]
do work properly only when:

1. Secure-processing is disabled
2. Functions are defined in a separate jar
3. Functions are augmented during native build phase. For example, they can be registered for reflection:
[source,java]
----
@RegisterForReflection(targets = { my.Functions.class })
public class FunctionsConfiguration {
}
----

[NOTE]
====
The content of the XSLT source URIs is parsed and compiled into Java classes at build time. These Java classes are the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.camel.quarkus.component.xslt;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigItem;
Expand All @@ -36,4 +37,10 @@ public class CamelXsltConfig {
*/
@ConfigItem(defaultValue = "org.apache.camel.quarkus.component.xslt.generated")
public String packageName;

/**
* TransformerFactory features.
*/
@ConfigItem
public Map<String, Boolean> features;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
*/
package org.apache.camel.quarkus.component.xslt;

import java.util.Map;

import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;

import io.quarkus.runtime.RuntimeValue;
Expand All @@ -27,11 +30,12 @@

@Recorder
public class CamelXsltRecorder {

public RuntimeValue<XsltComponent> createXsltComponent(CamelXsltConfig config,
RuntimeValue<RuntimeUriResolver.Builder> uriResolverBuilder) {
final RuntimeUriResolver uriResolver = uriResolverBuilder.getValue().build();
final QuarkusTransformerFactoryConfigurationStrategy strategy = new QuarkusTransformerFactoryConfigurationStrategy(
config.packageName, uriResolver);
config.packageName, config.features, uriResolver);
final XsltComponent component = new XsltComponent();
component.setUriResolver(uriResolver);
component.setTransformerFactoryConfigurationStrategy(strategy);
Expand All @@ -52,16 +56,28 @@ static class QuarkusTransformerFactoryConfigurationStrategy implements Transform

private final String packageName;
private final RuntimeUriResolver uriResolver;
private final Map<String, Boolean> features;

public QuarkusTransformerFactoryConfigurationStrategy(String packageName, RuntimeUriResolver uriResolver) {
public QuarkusTransformerFactoryConfigurationStrategy(String packageName, Map<String, Boolean> features,
RuntimeUriResolver uriResolver) {
this.uriResolver = uriResolver;
this.packageName = packageName;
this.features = features;
}

@Override
public void configure(TransformerFactory tf, XsltEndpoint endpoint) {
final String className = uriResolver.getTransletClassName(endpoint.getResourceUri());

for (Map.Entry<String, Boolean> entry : features.entrySet()) {
try {
tf.setFeature(entry.getKey(), entry.getValue());
} catch (TransformerException e) {
throw new RuntimeException("Could not set TransformerFactory feature '"
+ entry.getKey() + "' = " + entry.getValue(), e);
}
}

tf.setAttribute("use-classpath", true);
tf.setAttribute("translet-name", className);
tf.setAttribute("package-name", packageName);
Expand Down
1 change: 1 addition & 0 deletions integration-tests-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<module>test-support</module>
<module>mock-backend</module>
<module>wiremock</module>
<module>xslt-support</module>
</modules>

<dependencyManagement>
Expand Down
31 changes: 31 additions & 0 deletions integration-tests-support/xslt-support/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-tests-support</artifactId>
<version>2.8.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>camel-quarkus-integration-tests-support-xslt</artifactId>
<name>Camel Quarkus :: Integration Tests :: Support :: XSLT</name>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.test.support.xslt;

public class Functions {
public static String concatDash(String val1, String val2) {
return val1 + "-" + val2;
}
}
4 changes: 4 additions & 0 deletions integration-tests/xml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-support-stax</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-tests-support-xslt</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.quarkus.component.xml.it;

import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection(targets = { org.apache.camel.quarkus.test.support.xslt.Functions.class })
public class FunctionsConfiguration {
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,17 @@ public String htmlParse(String html) {
@Path("/xslt")
@POST
@Produces(MediaType.TEXT_PLAIN)
public String classpath(String body) throws Exception {
public String classpath(String body) {
return producerTemplate.requestBody("xslt:xslt/classpath-transform.xsl", body, String.class);
}

@Path("/xslt-extension-function")
@POST
@Produces(MediaType.TEXT_PLAIN)
public String extensionFunction(String body) {
return producerTemplate.requestBody("xslt:xslt/extension-function.xsl", body, String.class);
}

@Path("/html-transform")
@POST
@Consumes(MediaType.TEXT_HTML)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ quarkus.log.category."org.apache.camel.quarkus.core.deployment".level = INFO
#
# Quarkus - Camel
#
quarkus.camel.xslt.sources = xslt/classpath-transform.xsl,xslt/html-transform.xsl,xslt/html-to-text.xsl
quarkus.camel.xslt.sources = xslt/classpath-transform.xsl,xslt/html-transform.xsl,xslt/html-to-text.xsl,xslt/extension-function.xsl
quarkus.camel.xslt.features."http\://javax.xml.XMLConstants/feature/secure-processing" = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
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.
-->
<xsl:stylesheet
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:func='xalan://org.apache.camel.quarkus.test.support.xslt.Functions'
extension-element-prefixes='func'
version='1.0'>

<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>

<xsl:template match="/">
<extension-function-xsl>
<xsl:value-of select="func:concatDash(/mail/subject, /mail/body)" />
</extension-function-xsl>
</xsl:template>
</xsl:stylesheet>
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ public void xslt() {
actual);
}

@Test
public void xsltExtensionFunction() {
final String actual = RestAssured.given()
.body(BODY)
.post("/xml/xslt-extension-function")
.then()
.statusCode(200)
.extract().body().asString().trim().replaceAll(">\\s+<", "><");

Assertions.assertEquals(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><extension-function-xsl>Hey-Hello world!</extension-function-xsl>",
actual);
}

@Test
public void htmlTransform() throws Exception {
String html = IOUtils.toString(getClass().getResourceAsStream("/test.html"), Charset.forName("UTF-8"));
Expand Down
5 changes: 5 additions & 0 deletions poms/bom-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@
<artifactId>camel-quarkus-integration-wiremock-support</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-tests-support-xslt</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel.quarkus</groupId>
Expand Down

0 comments on commit 5927609

Please sign in to comment.