All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.util.toolbox.XsltAggregationStrategy Maven / Gradle / Ivy

There is a newer version: 4.7.0
Show newest version
/**
 * 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.util.toolbox;

import java.io.IOException;
import java.util.concurrent.RejectedExecutionException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;

import org.w3c.dom.Document;

import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Exchange;
import org.apache.camel.builder.xml.XsltBuilder;
import org.apache.camel.builder.xml.XsltUriResolver;
import org.apache.camel.component.xslt.XsltEndpoint;
import org.apache.camel.component.xslt.XsltOutput;
import org.apache.camel.processor.aggregate.AggregationStrategy;
import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages.
 * 

* Since XSLT does not directly support providing multiple XML payloads as an input, this aggregator injects * the new incoming XML document (newExchange) into the oldExchange as an exchange property of * type {@link Document}. The old exchange therefore remains accessible as the root context. * This exchange property can then be accessed from your XSLT by declaring an {@code } at the top * of your stylesheet: * * * * * * * * * * * * * The exchange property name defaults to new-exchange but can be * changed through {@link #setPropertyName(String)}. *

* Some code bits have been copied from the {@link org.apache.camel.component.xslt.XsltEndpoint}. */ public class XsltAggregationStrategy extends ServiceSupport implements AggregationStrategy, CamelContextAware { private static final Logger LOG = LoggerFactory.getLogger(XsltAggregationStrategy.class); private static final String DEFAULT_PROPERTY_NAME = "new-exchange"; private volatile XsltBuilder xslt; private volatile URIResolver uriResolver; private CamelContext camelContext; private String propertyName; private String xslFile; private String transformerFactoryClass; private XsltOutput output = XsltOutput.string; /** * Constructor. * * @param xslFileLocation location of the XSL transformation */ public XsltAggregationStrategy(String xslFileLocation) { this.xslFile = xslFileLocation; } @Override public CamelContext getCamelContext() { return camelContext; } @Override public void setCamelContext(CamelContext camelContext) { this.camelContext = camelContext; } @Override public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { // guard against unlikely NPE if (newExchange == null) { return oldExchange; } // in the first call to this aggregation, do not call the XSLT but instead store the // incoming exchange if (oldExchange == null) { return newExchange; } if (!isRunAllowed()) { throw new RejectedExecutionException(); } try { oldExchange.setProperty(propertyName, newExchange.getIn().getBody(Document.class)); xslt.process(oldExchange); return oldExchange; } catch (Throwable e) { oldExchange.setException(e); } return oldExchange; } public void setOutput(XsltOutput output) { this.output = output; } public void setXslt(XsltBuilder xslt) { this.xslt = xslt; } public void setUriResolver(URIResolver uriResolver) { this.uriResolver = uriResolver; } public void setTransformerFactoryClass(String transformerFactoryClass) { this.transformerFactoryClass = transformerFactoryClass; } public String getPropertyName() { return propertyName; } public void setPropertyName(String propertyName) { this.propertyName = propertyName; } @Deprecated protected void initialize(CamelContext context) throws Exception { this.camelContext = context; } protected void configureOutput(XsltBuilder xslt, String output) throws Exception { if (ObjectHelper.isEmpty(output)) { return; } if ("string".equalsIgnoreCase(output)) { xslt.outputString(); } else if ("bytes".equalsIgnoreCase(output)) { xslt.outputBytes(); } else if ("DOM".equalsIgnoreCase(output)) { xslt.outputDOM(); } else if ("file".equalsIgnoreCase(output)) { xslt.outputFile(); } else { throw new IllegalArgumentException("Unknown output type: " + output); } } /** * Loads the resource. * * @param resourceUri the resource to load * @throws TransformerException is thrown if error loading resource * @throws IOException is thrown if error loading resource */ protected void loadResource(String resourceUri) throws TransformerException, IOException { LOG.trace("{} loading schema resource: {}", this, resourceUri); Source source = xslt.getUriResolver().resolve(resourceUri, null); if (source == null) { throw new IOException("Cannot load schema resource " + resourceUri); } else { xslt.setTransformerSource(source); } } // --- fluent builders --- public static XsltAggregationStrategy create(String xslFile) { return new XsltAggregationStrategy(xslFile); } public XsltAggregationStrategy withPropertyName(String propertyName) { setPropertyName(propertyName); return this; } public XsltAggregationStrategy withOutput(XsltOutput output) { setOutput(output); return this; } public XsltAggregationStrategy withUriResolver(URIResolver resolver) { setUriResolver(resolver); return this; } public XsltAggregationStrategy withTransformerFactoryClass(String clazz) { setTransformerFactoryClass(clazz); return this; } public XsltAggregationStrategy withSaxon() { setTransformerFactoryClass(XsltEndpoint.SAXON_TRANSFORMER_FACTORY_CLASS_NAME); return this; } @Override protected void doStart() throws Exception { ObjectHelper.notNull(camelContext, "CamelContext", this); // set the default property name if not set this.propertyName = ObjectHelper.isNotEmpty(propertyName) ? propertyName : DEFAULT_PROPERTY_NAME; // initialize the XsltBuilder this.xslt = camelContext.getInjector().newInstance(XsltBuilder.class); if (transformerFactoryClass != null) { Class factoryClass = camelContext.getClassResolver().resolveMandatoryClass(transformerFactoryClass, XsltAggregationStrategy.class.getClassLoader()); TransformerFactory factory = (TransformerFactory) camelContext.getInjector().newInstance(factoryClass); xslt.getConverter().setTransformerFactory(factory); } if (uriResolver == null) { uriResolver = new XsltUriResolver(camelContext, xslFile); } xslt.setUriResolver(uriResolver); xslt.setFailOnNullBody(true); xslt.transformerCacheSize(0); xslt.setAllowStAX(true); configureOutput(xslt, output.name()); loadResource(xslFile); } @Override protected void doStop() throws Exception { // noop } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy