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.processor.cache;
018    
019    import java.io.File;
020    import java.io.InputStream;
021    import java.io.StringReader;
022    
023    import javax.xml.transform.Source;
024    import javax.xml.transform.Transformer;
025    import javax.xml.transform.TransformerFactory;
026    import javax.xml.transform.dom.DOMResult;
027    import javax.xml.transform.dom.DOMSource;
028    
029    import org.w3c.dom.Document;
030    
031    import net.sf.ehcache.CacheManager;
032    import net.sf.ehcache.Ehcache;
033    import org.apache.camel.Exchange;
034    import org.apache.camel.Processor;
035    import org.apache.camel.component.cache.CacheManagerFactory;
036    import org.apache.camel.converter.IOConverter;
037    import org.apache.camel.converter.jaxp.XmlConverter;
038    import org.apache.camel.util.IOHelper;
039    import org.apache.commons.logging.Log;
040    import org.apache.commons.logging.LogFactory;
041    
042    
043    public class CacheBasedXPathReplacer extends CacheValidate implements Processor {
044        private static final transient Log LOG = LogFactory.getLog(CacheBasedXPathReplacer.class);
045        private String cacheName;
046        private String key;
047        private String xpath;
048        private CacheManager cacheManager;
049        private Ehcache cache;
050        private Document document;
051        private DOMSource source;
052        private DOMResult result;
053    
054        public CacheBasedXPathReplacer(String cacheName, String key, String xpath) {
055            super();
056            if (cacheName.contains("cache://")) {
057                this.setCacheName(cacheName.replace("cache://", ""));
058            } else {
059                this.setCacheName(cacheName);
060            }
061            this.key = key;
062            this.xpath = xpath;
063        }
064    
065        public void process(Exchange exchange) throws Exception {
066            // Cache the buffer to the specified Cache against the specified key
067            cacheManager = new CacheManagerFactory().instantiateCacheManager();
068    
069            if (isValid(cacheManager, cacheName, key)) {
070                cache = cacheManager.getCache(cacheName);
071    
072                if (LOG.isDebugEnabled()) {
073                    LOG.debug("Replacing XPath value " + xpath + "in Message with value stored against key " + key
074                            + " in CacheName " + cacheName);
075                }
076                exchange.getIn().setHeader("CACHE_KEY", key);
077                Object body = exchange.getIn().getBody();
078                InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, body);
079                try {
080                    document = exchange.getContext().getTypeConverter().convertTo(Document.class, exchange, is);
081                } finally {
082                    IOHelper.close(is, "is", LOG);
083                }
084    
085                InputStream cis = exchange.getContext().getTypeConverter()
086                    .convertTo(InputStream.class, cache.get(key).getObjectValue());
087    
088                try {
089                    Document cacheValueDocument = exchange.getContext().getTypeConverter()
090                        .convertTo(Document.class, exchange, cis);
091    
092                    // Create/setup the Transformer
093                    XmlConverter xmlConverter = new XmlConverter();
094                    String xslString = IOConverter.toString(new File("./src/main/resources/xpathreplacer.xsl"), exchange);
095                    xslString = xslString.replace("##match_token##", xpath);
096                    Source xslSource = xmlConverter.toStreamSource(new StringReader(xslString));
097                    TransformerFactory transformerFactory = xmlConverter.createTransformerFactory();
098                    Transformer transformer = transformerFactory.newTransformer(xslSource);
099                    source = xmlConverter.toDOMSource(document);
100                    result = new DOMResult();
101    
102                    transformer.setParameter("cacheValue", cacheValueDocument);
103                    transformer.transform(source, result);
104                } finally {
105                    IOHelper.close(cis, "cis", LOG);
106                }
107            }
108    
109            // DOMSource can be converted to byte[] by camel type converter mechanism
110            DOMSource dom = new DOMSource(result.getNode());
111            exchange.getIn().setBody(dom, byte[].class);
112        }
113    
114        public String getCacheName() {
115            return cacheName;
116        }
117    
118        public void setCacheName(String cacheName) {
119            this.cacheName = cacheName;
120        }
121    
122        public String getKey() {
123            return key;
124        }
125    
126        public void setKey(String key) {
127            this.key = key;
128        }
129    
130        public String getXpath() {
131            return xpath;
132        }
133    
134        public void setXpath(String xpath) {
135            this.xpath = xpath;
136        }
137    
138    }