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 */ 017package org.apache.camel.component.language; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.io.UnsupportedEncodingException; 022import java.net.URLEncoder; 023 024import org.apache.camel.Component; 025import org.apache.camel.Consumer; 026import org.apache.camel.Expression; 027import org.apache.camel.Processor; 028import org.apache.camel.Producer; 029import org.apache.camel.RuntimeCamelException; 030import org.apache.camel.component.ResourceEndpoint; 031import org.apache.camel.spi.Language; 032import org.apache.camel.spi.Metadata; 033import org.apache.camel.spi.UriEndpoint; 034import org.apache.camel.spi.UriParam; 035import org.apache.camel.spi.UriPath; 036import org.apache.camel.util.IOHelper; 037import org.apache.camel.util.ObjectHelper; 038import org.apache.camel.util.ResourceHelper; 039 040/** 041 * Language endpoint. 042 * 043 * @version 044 */ 045@UriEndpoint(scheme = "language", title = "Language", syntax = "language:languageName", producerOnly = true, label = "core,script") 046public class LanguageEndpoint extends ResourceEndpoint { 047 private Language language; 048 private Expression expression; 049 private boolean contentResolvedFromResource; 050 @UriPath(enums = "bean,constant,el,exchangeProperty,file,groovy,header,jsonpath,jxpath,mvel,ognl,ref,simple,spel,sql,terser,tokenize,xpath,xquery,xtokenize") @Metadata(required = "true") 051 private String languageName; 052 @UriParam 053 private String script; 054 @UriParam(defaultValue = "true") 055 private boolean transform = true; 056 @UriParam 057 private boolean binary; 058 @UriParam 059 private boolean cacheScript; 060 061 public LanguageEndpoint() { 062 // enable cache by default 063 setContentCache(true); 064 } 065 066 public LanguageEndpoint(String endpointUri, Component component, Language language, Expression expression, String resourceUri) { 067 super(endpointUri, component, resourceUri); 068 this.language = language; 069 this.expression = expression; 070 // enable cache by default 071 setContentCache(true); 072 } 073 074 public Producer createProducer() throws Exception { 075 ObjectHelper.notNull(getCamelContext(), "CamelContext", this); 076 077 if (language == null && languageName != null) { 078 language = getCamelContext().resolveLanguage(languageName); 079 } 080 081 ObjectHelper.notNull(language, "language", this); 082 if (cacheScript && expression == null && script != null) { 083 script = resolveScript(script); 084 expression = language.createExpression(script); 085 } 086 087 return new LanguageProducer(this); 088 } 089 090 public Consumer createConsumer(Processor processor) throws Exception { 091 throw new RuntimeCamelException("Cannot consume to a LanguageEndpoint: " + getEndpointUri()); 092 } 093 094 /** 095 * Resolves the script. 096 * 097 * @param script script or uri for a script to load 098 * @return the script 099 * @throws IOException is thrown if error loading the script 100 */ 101 protected String resolveScript(String script) throws IOException { 102 String answer; 103 if (ResourceHelper.hasScheme(script)) { 104 InputStream is = loadResource(script); 105 answer = getCamelContext().getTypeConverter().convertTo(String.class, is); 106 IOHelper.close(is); 107 } else { 108 answer = script; 109 } 110 111 return answer; 112 } 113 114 public boolean isSingleton() { 115 return true; 116 } 117 118 @Override 119 protected String createEndpointUri() { 120 String s = script; 121 try { 122 s = URLEncoder.encode(s, "UTF-8"); 123 } catch (UnsupportedEncodingException e) { 124 // ignore 125 } 126 return languageName + ":" + s; 127 } 128 129 public Language getLanguage() { 130 return language; 131 } 132 133 public Expression getExpression() { 134 if (isContentResolvedFromResource() && isContentCacheCleared()) { 135 return null; 136 } 137 return expression; 138 } 139 140 public void setExpression(Expression expression) { 141 this.expression = expression; 142 } 143 144 public boolean isTransform() { 145 return transform; 146 } 147 148 /** 149 * Whether or not the result of the script should be used as message body. 150 * <p/> 151 * This options is default <tt>true</tt>. 152 * 153 * @param transform <tt>true</tt> to use result as new message body, <tt>false</tt> to keep the existing message body 154 */ 155 public void setTransform(boolean transform) { 156 this.transform = transform; 157 } 158 159 public boolean isBinary() { 160 return binary; 161 } 162 163 /** 164 * Whether the script is binary content or text content. 165 * <p/> 166 * By default the script is read as text content (eg <tt>java.lang.String</tt>) 167 * 168 * @param binary <tt>true</tt> to read the script as binary, instead of text based. 169 */ 170 public void setBinary(boolean binary) { 171 this.binary = binary; 172 } 173 174 /** 175 * Sets the name of the language to use 176 * 177 * @param languageName the name of the language 178 */ 179 public void setLanguageName(String languageName) { 180 this.languageName = languageName; 181 } 182 183 /** 184 * Sets the script to execute 185 * 186 * @param script the script 187 */ 188 public void setScript(String script) { 189 this.script = script; 190 } 191 192 public String getScript() { 193 return script; 194 } 195 196 public boolean isContentResolvedFromResource() { 197 return contentResolvedFromResource; 198 } 199 200 public void setContentResolvedFromResource(boolean contentResolvedFromResource) { 201 this.contentResolvedFromResource = contentResolvedFromResource; 202 } 203 204 public boolean isCacheScript() { 205 return cacheScript; 206 } 207 208 /** 209 * Whether to cache the compiled script and reuse 210 * <p/> 211 * Notice reusing the script can cause side effects from processing one Camel 212 * {@link org.apache.camel.Exchange} to the next {@link org.apache.camel.Exchange}. 213 */ 214 public void setCacheScript(boolean cacheScript) { 215 this.cacheScript = cacheScript; 216 } 217 218 public void clearContentCache() { 219 super.clearContentCache(); 220 // must also clear expression and script 221 expression = null; 222 script = null; 223 } 224 225}