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