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