001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.component.xslt; 018 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import javax.xml.transform.URIResolver; 024 025import org.apache.camel.Endpoint; 026import org.apache.camel.converter.jaxp.XmlConverter; 027import org.apache.camel.impl.UriEndpointComponent; 028import org.apache.camel.spi.Metadata; 029import org.apache.camel.util.EndpointHelper; 030import org.apache.camel.util.ResourceHelper; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034/** 035 * The <a href="http://camel.apache.org/xslt.html">XSLT Component</a> is for performing XSLT transformations of messages 036 */ 037public class XsltComponent extends UriEndpointComponent { 038 039 private static final Logger LOG = LoggerFactory.getLogger(XsltComponent.class); 040 041 @Metadata(label = "advanced") 042 private XmlConverter xmlConverter; 043 @Metadata(label = "advanced") 044 private URIResolver uriResolver; 045 @Metadata(label = "advanced") 046 private XsltUriResolverFactory uriResolverFactory; 047 @Metadata(label = "advanced") 048 private Object saxonConfiguration; 049 @Metadata(label = "advanced") 050 private Map<String, Object> saxonConfigurationProperties = new HashMap<>(); 051 @Metadata(label = "advanced", javaType = "java.lang.String") 052 private List<Object> saxonExtensionFunctions; 053 @Metadata(defaultValue = "true") 054 private boolean contentCache = true; 055 private boolean saxon; 056 057 public XsltComponent() { 058 super(XsltEndpoint.class); 059 } 060 061 public XmlConverter getXmlConverter() { 062 return xmlConverter; 063 } 064 065 /** 066 * To use a custom implementation of {@link org.apache.camel.converter.jaxp.XmlConverter} 067 */ 068 public void setXmlConverter(XmlConverter xmlConverter) { 069 this.xmlConverter = xmlConverter; 070 } 071 072 public XsltUriResolverFactory getUriResolverFactory() { 073 return uriResolverFactory; 074 } 075 076 /** 077 * To use a custom UriResolver which depends on a dynamic endpoint resource URI. Should not be used together with the option 'uriResolver'. 078 */ 079 public void setUriResolverFactory(XsltUriResolverFactory uriResolverFactory) { 080 this.uriResolverFactory = uriResolverFactory; 081 } 082 083 public URIResolver getUriResolver() { 084 return uriResolver; 085 } 086 087 /** 088 * To use a custom UriResolver. Should not be used together with the option 'uriResolverFactory'. 089 */ 090 public void setUriResolver(URIResolver uriResolver) { 091 this.uriResolver = uriResolver; 092 } 093 094 public boolean isContentCache() { 095 return contentCache; 096 } 097 098 /** 099 * Cache for the resource content (the stylesheet file) when it is loaded. 100 * If set to false Camel will reload the stylesheet file on each message processing. This is good for development. 101 * A cached stylesheet can be forced to reload at runtime via JMX using the clearCachedStylesheet operation. 102 */ 103 public void setContentCache(boolean contentCache) { 104 this.contentCache = contentCache; 105 } 106 107 public boolean isSaxon() { 108 return saxon; 109 } 110 111 /** 112 * Whether to use Saxon as the transformerFactoryClass. 113 * If enabled then the class net.sf.saxon.TransformerFactoryImpl. You would need to add Saxon to the classpath. 114 */ 115 public void setSaxon(boolean saxon) { 116 this.saxon = saxon; 117 } 118 119 public List<Object> getSaxonExtensionFunctions() { 120 return saxonExtensionFunctions; 121 } 122 123 /** 124 * Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition. 125 * You would need to add camel-saxon to the classpath. 126 * The function is looked up in the registry, where you can comma to separate multiple values to lookup. 127 */ 128 public void setSaxonExtensionFunctions(List<Object> extensionFunctions) { 129 this.saxonExtensionFunctions = extensionFunctions; 130 } 131 132 /** 133 * Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition. 134 * You would need to add camel-saxon to the classpath. 135 * The function is looked up in the registry, where you can comma to separate multiple values to lookup. 136 */ 137 public void setSaxonExtensionFunctions(String extensionFunctions) { 138 this.saxonExtensionFunctions = EndpointHelper.resolveReferenceListParameter( 139 getCamelContext(), 140 extensionFunctions, 141 Object.class 142 ); 143 } 144 145 public Object getSaxonConfiguration() { 146 return saxonConfiguration; 147 } 148 149 /** 150 * To use a custom Saxon configuration 151 */ 152 public void setSaxonConfiguration(Object saxonConfiguration) { 153 this.saxonConfiguration = saxonConfiguration; 154 } 155 156 public Map<String, Object> getSaxonConfigurationProperties() { 157 return saxonConfigurationProperties; 158 } 159 160 /** 161 * To set custom Saxon configuration properties 162 */ 163 public void setSaxonConfigurationProperties(Map<String, Object> configurationProperties) { 164 this.saxonConfigurationProperties = configurationProperties; 165 } 166 167 @Override 168 protected Endpoint createEndpoint(String uri, final String remaining, Map<String, Object> parameters) throws Exception { 169 XsltEndpoint endpoint = new XsltEndpoint(uri, this); 170 endpoint.setConverter(getXmlConverter()); 171 endpoint.setContentCache(isContentCache()); 172 endpoint.setSaxon(isSaxon()); 173 endpoint.setSaxonConfiguration(saxonConfiguration); 174 endpoint.setSaxonConfigurationProperties(saxonConfigurationProperties); 175 endpoint.setSaxonExtensionFunctions(saxonExtensionFunctions); 176 177 // lookup custom resolver to use 178 URIResolver resolver = resolveAndRemoveReferenceParameter(parameters, "uriResolver", URIResolver.class); 179 if (resolver == null) { 180 // not in endpoint then use component specific resolver 181 resolver = getUriResolver(); 182 } 183 if (resolver == null) { 184 // lookup custom resolver factory to use 185 XsltUriResolverFactory resolverFactory = resolveAndRemoveReferenceParameter(parameters, "uriResolverFactory", XsltUriResolverFactory.class); 186 if (resolverFactory == null) { 187 // not in endpoint then use component specific resolver factory 188 resolverFactory = getUriResolverFactory(); 189 } 190 if (resolverFactory == null) { 191 // fallback to use the Default URI resolver factory 192 resolverFactory = new DefaultXsltUriResolverFactory(); 193 } 194 195 resolver = resolverFactory.createUriResolver(getCamelContext(), remaining); 196 } 197 endpoint.setUriResolver(resolver); 198 199 setProperties(endpoint, parameters); 200 201 String resourceUri = remaining; 202 if (ResourceHelper.isHttpUri(resourceUri)) { 203 // if its a http uri, then append additional parameters as they are part of the uri 204 resourceUri = ResourceHelper.appendParameters(resourceUri, parameters); 205 } 206 LOG.debug("{} using schema resource: {}", this, resourceUri); 207 endpoint.setResourceUri(resourceUri); 208 209 if (!parameters.isEmpty()) { 210 // additional parameters need to be stored on endpoint as they can be used to configure xslt builder additionally 211 endpoint.setParameters(parameters); 212 } 213 214 return endpoint; 215 } 216 217}