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 */ 017 package org.apache.camel.component.xslt; 018 019 import java.io.IOException; 020 import javax.xml.transform.Source; 021 import javax.xml.transform.TransformerException; 022 023 import org.apache.camel.Component; 024 import org.apache.camel.Exchange; 025 import org.apache.camel.api.management.ManagedAttribute; 026 import org.apache.camel.api.management.ManagedOperation; 027 import org.apache.camel.api.management.ManagedResource; 028 import org.apache.camel.builder.xml.XsltBuilder; 029 import org.apache.camel.impl.ProcessorEndpoint; 030 import org.slf4j.Logger; 031 import org.slf4j.LoggerFactory; 032 033 @ManagedResource(description = "Managed XsltEndpoint") 034 public class XsltEndpoint extends ProcessorEndpoint { 035 036 private static final transient Logger LOG = LoggerFactory.getLogger(XsltEndpoint.class); 037 038 private XsltBuilder xslt; 039 private String resourceUri; 040 private boolean cacheStylesheet; 041 private volatile boolean cacheCleared; 042 043 public XsltEndpoint(String endpointUri, Component component, XsltBuilder xslt, String resourceUri, 044 boolean cacheStylesheet) throws Exception { 045 super(endpointUri, component, xslt); 046 this.xslt = xslt; 047 this.resourceUri = resourceUri; 048 this.cacheStylesheet = cacheStylesheet; 049 } 050 051 @ManagedOperation(description = "Clears the cached XSLT stylesheet, forcing to re-load the stylesheet on next request") 052 public void clearCachedStylesheet() { 053 this.cacheCleared = true; 054 } 055 056 @ManagedAttribute(description = "Whether the XSLT stylesheet is cached") 057 public boolean isCacheStylesheet() { 058 return cacheStylesheet; 059 } 060 061 public XsltEndpoint findOrCreateEndpoint(String uri, String newResourceUri) { 062 String newUri = uri.replace(resourceUri, newResourceUri); 063 LOG.trace("Getting endpoint with URI: {}", newUri); 064 return getCamelContext().getEndpoint(newUri, XsltEndpoint.class); 065 } 066 067 @Override 068 protected void onExchange(Exchange exchange) throws Exception { 069 String newResourceUri = exchange.getIn().getHeader(XsltConstants.XSLT_RESOURCE_URI, String.class); 070 if (newResourceUri != null) { 071 exchange.getIn().removeHeader(XsltConstants.XSLT_RESOURCE_URI); 072 073 LOG.trace("{} set to {} creating new endpoint to handle exchange", XsltConstants.XSLT_RESOURCE_URI, newResourceUri); 074 XsltEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri); 075 newEndpoint.onExchange(exchange); 076 return; 077 } else { 078 if (!cacheStylesheet || cacheCleared) { 079 loadResource(resourceUri); 080 } 081 super.onExchange(exchange); 082 } 083 } 084 085 /** 086 * Loads the resource. 087 * 088 * @param resourceUri the resource to load 089 * 090 * @throws TransformerException is thrown if error loading resource 091 * @throws IOException is thrown if error loading resource 092 */ 093 protected void loadResource(String resourceUri) throws TransformerException, IOException { 094 LOG.trace("{} loading schema resource: {}", this, resourceUri); 095 Source source = xslt.getUriResolver().resolve(resourceUri, null); 096 if (source == null) { 097 throw new IOException("Cannot load schema resource " + resourceUri); 098 } else { 099 xslt.setTransformerSource(source); 100 } 101 // now loaded so clear flag 102 cacheCleared = false; 103 } 104 105 @Override 106 protected void doStart() throws Exception { 107 super.doStart(); 108 loadResource(resourceUri); 109 } 110 111 @Override 112 protected void doStop() throws Exception { 113 super.doStop(); 114 } 115 }