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