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.model.language;
018
019import javax.xml.bind.annotation.XmlAccessType;
020import javax.xml.bind.annotation.XmlAccessorType;
021import javax.xml.bind.annotation.XmlAttribute;
022import javax.xml.bind.annotation.XmlRootElement;
023
024import org.apache.camel.CamelContext;
025import org.apache.camel.Expression;
026import org.apache.camel.Predicate;
027import org.apache.camel.language.tokenizer.TokenizeLanguage;
028import org.apache.camel.spi.Metadata;
029import org.apache.camel.util.ExpressionToPredicateAdapter;
030
031/**
032 * For expressions and predicates using a body or header tokenizer.
033 *
034 * @see TokenizeLanguage
035 */
036@Metadata(label = "language,core", title = "Tokenize")
037@XmlRootElement(name = "tokenize")
038@XmlAccessorType(XmlAccessType.FIELD)
039public class TokenizerExpression extends ExpressionDefinition {
040    @XmlAttribute(required = true)
041    private String token;
042    @XmlAttribute
043    private String endToken;
044    @XmlAttribute
045    private String inheritNamespaceTagName;
046    @XmlAttribute
047    private String headerName;
048    @XmlAttribute
049    private Boolean regex;
050    @XmlAttribute
051    private Boolean xml;
052    @XmlAttribute
053    private Boolean includeTokens;
054    @XmlAttribute
055    private Integer group;
056    @XmlAttribute
057    private Boolean skipFirst;
058
059    public TokenizerExpression() {
060    }
061
062    @Override
063    public String getLanguage() {
064        return "tokenize";
065    }
066
067    public String getToken() {
068        return token;
069    }
070
071    /**
072     * The (start) token to use as tokenizer, for example \n for a new line token
073     */
074    public void setToken(String token) {
075        this.token = token;
076    }
077
078    public String getEndToken() {
079        return endToken;
080    }
081
082    /**
083     * The end token to use as tokenizer if using start/end token pairs.
084     */
085    public void setEndToken(String endToken) {
086        this.endToken = endToken;
087    }
088
089    public String getHeaderName() {
090        return headerName;
091    }
092
093    /**
094     * Name of header to tokenize instead of using the message body.
095     */
096    public void setHeaderName(String headerName) {
097        this.headerName = headerName;
098    }
099
100    /**
101     * If the token is a regular expression pattern.
102     * <p/>
103     * The default value is false
104     */
105    public void setRegex(boolean regex) {
106        this.regex = regex;
107    }
108
109    public Boolean getRegex() {
110        return regex;
111    }
112
113    public String getInheritNamespaceTagName() {
114        return inheritNamespaceTagName;
115    }
116
117    /**
118     * To inherit namepaces from a root/parent tag name when using XML
119     */
120    public void setInheritNamespaceTagName(String inheritNamespaceTagName) {
121        this.inheritNamespaceTagName = inheritNamespaceTagName;
122    }
123
124    public Boolean getXml() {
125        return xml;
126    }
127
128    /**
129     * Whether the input is XML messages.
130     * This option must be set to true if working with XML payloads.
131     */
132    public void setXml(Boolean xml) {
133        this.xml = xml;
134    }
135
136    public Boolean getIncludeTokens() {
137        return includeTokens;
138    }
139
140    /**
141     * Whether to include the tokens in the parts when using pairs
142     * <p/>
143     * The default value is false
144     */
145    public void setIncludeTokens(Boolean includeTokens) {
146        this.includeTokens = includeTokens;
147    }
148
149    public Integer getGroup() {
150        return group;
151    }
152
153    /**
154     * To group N parts together, for example to split big files into chunks of 1000 lines.
155     */
156    public void setGroup(Integer group) {
157        this.group = group;
158    }
159
160    public Boolean getSkipFirst() {
161        return skipFirst;
162    }
163
164    /**
165     * To skip the very first element
166     */
167    public void setSkipFirst(Boolean skipFirst) {
168        this.skipFirst = skipFirst;
169    }
170
171    @Override
172    public Expression createExpression(CamelContext camelContext) {
173        // special for new line tokens, if defined from XML then its 2 characters, so we replace that back to a single char
174        if (token.startsWith("\\n")) {
175            token = '\n' + token.substring(2);
176        }
177
178        TokenizeLanguage language = new TokenizeLanguage();
179        language.setToken(token);
180        language.setEndToken(endToken);
181        language.setInheritNamespaceTagName(inheritNamespaceTagName);
182        language.setHeaderName(headerName);
183        if (regex != null) {
184            language.setRegex(regex);
185        }
186        if (xml != null) {
187            language.setXml(xml);
188        }
189        if (includeTokens != null) {
190            language.setIncludeTokens(includeTokens);
191        }
192        if (group != null) {
193            if (group <= 0) {
194                throw new IllegalArgumentException("Group must be a positive number, was: " + group);
195            }
196            language.setGroup(group);
197        }
198        if (skipFirst != null) {
199            language.setSkipFirst(skipFirst);
200        }
201        return language.createExpression();
202    }
203
204    @Override
205    public Predicate createPredicate(CamelContext camelContext) {
206        Expression exp = createExpression(camelContext);
207        return ExpressionToPredicateAdapter.toPredicate(exp);
208    }
209
210    @Override
211    public String toString() {
212        if (endToken != null) {
213            return "tokenize{body() using tokens: " + token + "..." + endToken + "}";
214        } else {
215            return "tokenize{" + (headerName != null ? "header: " + headerName : "body()") + " using token: " + token + "}";
216        }
217    }
218}