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.velocity;
018
019 import java.io.InputStreamReader;
020 import java.io.Reader;
021 import java.io.StringWriter;
022 import java.util.Map;
023
024 import org.apache.camel.Exchange;
025 import org.apache.camel.ExchangePattern;
026 import org.apache.camel.Message;
027 import org.apache.camel.component.ResourceBasedEndpoint;
028 import org.apache.camel.util.ExchangeHelper;
029 import org.apache.velocity.VelocityContext;
030 import org.apache.velocity.app.Velocity;
031 import org.apache.velocity.app.VelocityEngine;
032 import org.apache.velocity.context.Context;
033 import org.apache.velocity.runtime.log.CommonsLogLogChute;
034 import org.springframework.core.io.Resource;
035
036 /**
037 * @version $Revision: 828294 $
038 */
039 public class VelocityEndpoint extends ResourceBasedEndpoint {
040 private final VelocityComponent component;
041 private VelocityEngine velocityEngine;
042 private boolean loaderCache = true;
043 private String encoding;
044
045 public VelocityEndpoint(String uri, VelocityComponent component, String resourceUri, Map parameters) {
046 super(uri, component, resourceUri, null);
047 this.component = component;
048 }
049
050 @Override
051 public boolean isSingleton() {
052 return true;
053 }
054
055 @Override
056 public ExchangePattern getExchangePattern() {
057 return ExchangePattern.InOut;
058 }
059
060 private synchronized VelocityEngine getVelocityEngine() throws Exception {
061 if (velocityEngine == null) {
062 velocityEngine = component.getVelocityEngine();
063 velocityEngine.setProperty(Velocity.FILE_RESOURCE_LOADER_CACHE, isLoaderCache() ? Boolean.TRUE : Boolean.FALSE);
064 velocityEngine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, CommonsLogLogChute.class.getName());
065 velocityEngine.setProperty(CommonsLogLogChute.LOGCHUTE_COMMONS_LOG_NAME, VelocityEndpoint.class.getName());
066 velocityEngine.init();
067 }
068 return velocityEngine;
069 }
070
071 public void setVelocityEngine(VelocityEngine velocityEngine) {
072 this.velocityEngine = velocityEngine;
073 }
074
075 public boolean isLoaderCache() {
076 return loaderCache;
077 }
078
079 /**
080 * Enables / disables the velocity resource loader cache which is enabled by default
081 *
082 * @param loaderCache a flag to enable/disable the cache
083 */
084 public void setLoaderCache(boolean loaderCache) {
085 this.loaderCache = loaderCache;
086 }
087
088 public void setEncoding(String encoding) {
089 this.encoding = encoding;
090 }
091
092 public String getEncoding() {
093 return encoding;
094 }
095
096 @SuppressWarnings("unchecked")
097 @Override
098 protected void onExchange(Exchange exchange) throws Exception {
099 Resource resource = getResource();
100
101 // getResourceAsInputStream also considers the content cache
102 Reader reader = encoding != null ? new InputStreamReader(getResourceAsInputStream(), encoding) : new InputStreamReader(getResourceAsInputStream());
103 StringWriter buffer = new StringWriter();
104 String logTag = getClass().getName();
105 Map variableMap = ExchangeHelper.createVariableMap(exchange);
106 Context velocityContext = new VelocityContext(variableMap);
107
108 // let velocity parse and generate the result in buffer
109 VelocityEngine engine = getVelocityEngine();
110 if (log.isDebugEnabled()) {
111 log.debug("Velocity is evaluating using velocity context: " + variableMap);
112 }
113 engine.evaluate(velocityContext, buffer, logTag, reader);
114
115 // now lets output the results to the exchange
116 Message out = exchange.getOut(true);
117 out.setBody(buffer.toString());
118 Map<String, Object> headers = (Map<String, Object>) velocityContext.get("headers");
119 for (String key : headers.keySet()) {
120 out.setHeader(key, headers.get(key));
121 }
122 }
123
124 }