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.language.tokenizer;
018
019import org.apache.camel.Expression;
020import org.apache.camel.IsSingleton;
021import org.apache.camel.Predicate;
022import org.apache.camel.builder.ExpressionBuilder;
023import org.apache.camel.spi.Language;
024import org.apache.camel.util.ExpressionToPredicateAdapter;
025import org.apache.camel.util.ObjectHelper;
026
027/**
028 * A language for tokenizer expressions.
029 * <p/>
030 * This tokenizer language can operator in the following modes:
031 * <ul>
032 *     <li>default - using a single tokenizer</li>
033 *     <li>pair - using both start and end tokens</li>
034 *     <li>xml - using both start and end tokens in XML mode, support inheriting namespaces</li>
035 * </ul>
036 * The default mode supports the <tt>headerName</tt> and <tt>regex</tt> options.
037 * Where as the pair mode only supports <tt>token</tt> and <tt>endToken</tt>.
038 * And the <tt>xml</tt> mode supports the <tt>inheritNamespaceTagName</tt> option.
039 */
040public class TokenizeLanguage implements Language, IsSingleton {
041
042    private String token;
043    private String endToken;
044    private String inheritNamespaceTagName;
045    private String headerName;
046    private boolean regex;
047    private boolean xml;
048    private boolean includeTokens;
049    private int group;
050
051    public static Expression tokenize(String token) {
052        return tokenize(token, false);
053    }
054
055    public static Expression tokenize(String token, boolean regex) {
056        TokenizeLanguage language = new TokenizeLanguage();
057        language.setToken(token);
058        language.setRegex(regex);
059        return language.createExpression(null);
060    }
061
062    public static Expression tokenize(String headerName, String token) {
063        return tokenize(headerName, token, false);
064    }
065
066    public static Expression tokenize(String headerName, String token, boolean regex) {
067        TokenizeLanguage language = new TokenizeLanguage();
068        language.setHeaderName(headerName);
069        language.setToken(token);
070        language.setRegex(regex);
071        return language.createExpression(null);
072    }
073
074    public static Expression tokenizePair(String startToken, String endToken, boolean includeTokens) {
075        TokenizeLanguage language = new TokenizeLanguage();
076        language.setToken(startToken);
077        language.setEndToken(endToken);
078        language.setIncludeTokens(includeTokens);
079        return language.createExpression(null);
080    }
081
082    public static Expression tokenizeXML(String tagName, String inheritNamespaceTagName) {
083        TokenizeLanguage language = new TokenizeLanguage();
084        language.setToken(tagName);
085        language.setInheritNamespaceTagName(inheritNamespaceTagName);
086        language.setXml(true);
087        language.setIncludeTokens(true);
088        return language.createExpression(null);
089    }
090
091    public Predicate createPredicate(String expression) {
092        return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
093    }
094
095    /**
096     * Creates a tokenize expression.
097     */
098    public Expression createExpression() {
099        ObjectHelper.notNull(token, "token");
100
101        Expression answer = null;
102        if (isXml()) {
103            answer = ExpressionBuilder.tokenizeXMLExpression(token, inheritNamespaceTagName);
104        } else if (endToken != null) {
105            answer = ExpressionBuilder.tokenizePairExpression(token, endToken, includeTokens);
106        }
107
108        if (answer == null) {
109            // use the regular tokenizer
110            Expression exp = headerName == null ? ExpressionBuilder.bodyExpression() : ExpressionBuilder.headerExpression(headerName);
111            if (regex) {
112                answer = ExpressionBuilder.regexTokenizeExpression(exp, token);
113            } else {
114                answer = ExpressionBuilder.tokenizeExpression(exp, token);
115            }
116        }
117
118        // if group then wrap answer in group expression
119        if (group > 0) {
120            // only include group token if not xml
121            String groupToken = isXml() ? null : token;
122            answer = ExpressionBuilder.groupIteratorExpression(answer, groupToken, group);
123        }
124
125        return answer;
126    }
127
128    public Expression createExpression(String expression) {
129        if (ObjectHelper.isNotEmpty(expression)) {
130            this.token = expression;
131        }
132        return createExpression();
133    }
134
135    public String getToken() {
136        return token;
137    }
138
139    public void setToken(String token) {
140        this.token = token;
141    }
142
143    public String getEndToken() {
144        return endToken;
145    }
146
147    public void setEndToken(String endToken) {
148        this.endToken = endToken;
149    }
150
151    public String getHeaderName() {
152        return headerName;
153    }
154
155    public void setHeaderName(String headerName) {
156        this.headerName = headerName;
157    }
158
159    public boolean isRegex() {
160        return regex;
161    }
162
163    public void setRegex(boolean regex) {
164        this.regex = regex;
165    }
166
167    public String getInheritNamespaceTagName() {
168        return inheritNamespaceTagName;
169    }
170
171    public void setInheritNamespaceTagName(String inheritNamespaceTagName) {
172        this.inheritNamespaceTagName = inheritNamespaceTagName;
173    }
174
175    public boolean isXml() {
176        return xml;
177    }
178
179    public void setXml(boolean xml) {
180        this.xml = xml;
181    }
182
183    public boolean isIncludeTokens() {
184        return includeTokens;
185    }
186
187    public void setIncludeTokens(boolean includeTokens) {
188        this.includeTokens = includeTokens;
189    }
190
191    public int getGroup() {
192        return group;
193    }
194
195    public void setGroup(int group) {
196        this.group = group;
197    }
198
199    public boolean isSingleton() {
200        return false;
201    }
202}