Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3503 Add xslt.features support #3526

Merged
merged 1 commit into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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