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.freemarker;
018
019 import java.io.Reader;
020 import java.io.StringReader;
021 import java.io.StringWriter;
022 import java.util.Map;
023 import java.util.Map.Entry;
024
025 import freemarker.template.Configuration;
026 import freemarker.template.Template;
027 import org.apache.camel.Component;
028 import org.apache.camel.Exchange;
029 import org.apache.camel.ExchangePattern;
030 import org.apache.camel.Message;
031 import org.apache.camel.component.ResourceBasedEndpoint;
032 import org.apache.camel.util.ExchangeHelper;
033 import org.apache.camel.util.ObjectHelper;
034
035 /**
036 * Freemarker endpoint
037 */
038 public class FreemarkerEndpoint extends ResourceBasedEndpoint {
039
040 private String encoding;
041 private Configuration configuration;
042
043 public FreemarkerEndpoint() {
044 }
045
046 public FreemarkerEndpoint(String uri, Component component, String resourceUri) {
047 super(uri, component, resourceUri, null);
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 @Override
061 protected String createEndpointUri() {
062 return "freemarker:" + getResourceUri();
063 }
064
065 /**
066 * Sets the encoding to be used for loading the template file.
067 */
068 public void setEncoding(String encoding) {
069 this.encoding = encoding;
070 }
071
072 public String getEncoding() {
073 return encoding;
074 }
075
076 public Configuration getConfiguration() {
077 return configuration;
078 }
079
080 /**
081 * Sets the Freemarker configuration to use
082 */
083 public void setConfiguration(Configuration configuration) {
084 this.configuration = configuration;
085 }
086
087 public FreemarkerEndpoint findOrCreateEndpoint(String uri, String newResourceUri) {
088 String newUri = uri.replace(getResourceUri(), newResourceUri);
089 if (log.isDebugEnabled()) {
090 log.debug("Getting endpoint with URI: " + newUri);
091 }
092 return (FreemarkerEndpoint) getCamelContext().getEndpoint(newUri);
093 }
094
095 @Override
096 @SuppressWarnings("unchecked")
097 protected void onExchange(Exchange exchange) throws Exception {
098 String path = getResourceUri();
099 ObjectHelper.notNull(configuration, "configuration");
100 ObjectHelper.notNull(path, "resourceUri");
101
102 String newResourceUri = exchange.getIn().getHeader(FreemarkerConstants.FREEMARKER_RESOURCE_URI, String.class);
103 if (newResourceUri != null) {
104 exchange.getIn().removeHeader(FreemarkerConstants.FREEMARKER_RESOURCE_URI);
105
106 if (log.isDebugEnabled()) {
107 log.debug(FreemarkerConstants.FREEMARKER_RESOURCE_URI + " set to " + newResourceUri + " creating new endpoint to handle exchange");
108 }
109 FreemarkerEndpoint newEndpoint = findOrCreateEndpoint(getEndpointUri(), newResourceUri);
110 newEndpoint.onExchange(exchange);
111 return;
112 }
113
114 Reader reader = null;
115 String content = exchange.getIn().getHeader(FreemarkerConstants.FREEMARKER_TEMPLATE, String.class);
116 if (content != null) {
117 // use content from header
118 reader = new StringReader(content);
119 // remove the header to avoid it being propagated in the routing
120 exchange.getIn().removeHeader(FreemarkerConstants.FREEMARKER_TEMPLATE);
121 }
122
123 Map variableMap = ExchangeHelper.createVariableMap(exchange);
124 // let freemarker parse and generate the result in buffer
125 Template template;
126
127 if (reader != null) {
128 if (log.isDebugEnabled()) {
129 log.debug("Freemarker is evaluating template read from header " + FreemarkerConstants.FREEMARKER_TEMPLATE + " using context: " + variableMap);
130 }
131 template = new Template("temp", reader, new Configuration());
132 } else {
133 if (log.isDebugEnabled()) {
134 log.debug("Freemarker is evaluating " + path + " using context: " + variableMap);
135 }
136 if (getEncoding() != null) {
137 template = configuration.getTemplate(path, getEncoding());
138 } else {
139 template = configuration.getTemplate(path);
140 }
141 }
142 StringWriter buffer = new StringWriter();
143 template.process(variableMap, buffer);
144 buffer.flush();
145
146 // now lets output the results to the exchange
147 Message out = exchange.getOut();
148 out.setBody(buffer.toString());
149 Map<String, Object> headers = (Map<String, Object>) variableMap.get("headers");
150 for (Entry<String, Object> entry : headers.entrySet()) {
151 out.setHeader(entry.getKey(), entry.getValue());
152 }
153 }
154 }