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        return language.createExpression(null);
088    }
089
090    public Predicate createPredicate(String expression) {
091        return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
092    }
093
094    /**
095     * Creates a tokenize expression.
096     */
097    public Expression createExpression() {
098        ObjectHelper.notNull(token, "token");
099
100        // validate some invalid combinations
101        if (endToken != null && inheritNamespaceTagName != null) {
102            throw new IllegalArgumentException("Cannot have both xml and pair tokenizer enabled.");
103        }
104        if (isXml() && (endToken != null || includeTokens)) {
105            throw new IllegalArgumentException("Cannot have both xml and pair tokenizer enabled.");
106        }
107
108        Expression answer = null;
109        if (isXml()) {
110            answer = ExpressionBuilder.tokenizeXMLExpression(token, inheritNamespaceTagName);
111        } else if (endToken != null) {
112            answer = ExpressionBuilder.tokenizePairExpression(token, endToken, includeTokens);
113        }
114
115        if (answer == null) {
116            // use the regular tokenizer
117            Expression exp = headerName == null ? ExpressionBuilder.bodyExpression() : ExpressionBuilder.headerExpression(headerName);
118            if (regex) {
119                answer = ExpressionBuilder.regexTokenizeExpression(exp, token);
120            } else {
121                answer = ExpressionBuilder.tokenizeExpression(exp, token);
122            }
123        }
124
125        // if group then wrap answer in group expression
126        if (group > 0) {
127            // only include group token if not xml
128            String groupToken = isXml() ? null : token;
129            answer = ExpressionBuilder.groupIteratorExpression(answer, groupToken, group);
130        }
131
132        return answer;
133    }
134
135    public Expression createExpression(String expression) {
136        if (ObjectHelper.isNotEmpty(expression)) {
137            this.token = expression;
138        }
139        return createExpression();
140    }
141
142    public String getToken() {
143        return token;
144    }
145
146    public void setToken(String token) {
147        this.token = token;
148    }
149
150    public String getEndToken() {
151        return endToken;
152    }
153
154    public void setEndToken(String endToken) {
155        this.endToken = endToken;
156    }
157
158    public String getHeaderName() {
159        return headerName;
160    }
161
162    public void setHeaderName(String headerName) {
163        this.headerName = headerName;
164    }
165
166    public boolean isRegex() {
167        return regex;
168    }
169
170    public void setRegex(boolean regex) {
171        this.regex = regex;
172    }
173
174    public String getInheritNamespaceTagName() {
175        return inheritNamespaceTagName;
176    }
177
178    public void setInheritNamespaceTagName(String inheritNamespaceTagName) {
179        this.inheritNamespaceTagName = inheritNamespaceTagName;
180    }
181
182    public boolean isXml() {
183        return xml;
184    }
185
186    public void setXml(boolean xml) {
187        this.xml = xml;
188    }
189
190    public boolean isIncludeTokens() {
191        return includeTokens;
192    }
193
194    public void setIncludeTokens(boolean includeTokens) {
195        this.includeTokens = includeTokens;
196    }
197
198    public int getGroup() {
199        return group;
200    }
201
202    public void setGroup(int group) {
203        this.group = group;
204    }
205
206    public boolean isSingleton() {
207        return false;
208    }
209}