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 java.util.List;
020
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlAttribute;
024import javax.xml.bind.annotation.XmlID;
025import javax.xml.bind.annotation.XmlRootElement;
026import javax.xml.bind.annotation.XmlTransient;
027import javax.xml.bind.annotation.XmlType;
028import javax.xml.bind.annotation.XmlValue;
029
030import org.apache.camel.CamelContext;
031import org.apache.camel.Exchange;
032import org.apache.camel.Expression;
033import org.apache.camel.ExpressionFactory;
034import org.apache.camel.Predicate;
035import org.apache.camel.reifier.language.ExpressionReifier;
036import org.apache.camel.spi.Metadata;
037import org.apache.camel.util.CollectionStringBuffer;
038import org.apache.camel.util.ObjectHelper;
039
040/**
041 * A useful base class for an expression
042 */
043@Metadata(label = "language", title = "Expression")
044@XmlRootElement
045@XmlType(name = "expression") // must be named expression
046@XmlAccessorType(XmlAccessType.FIELD)
047@SuppressWarnings("rawtypes")
048public class ExpressionDefinition implements Expression, Predicate, ExpressionFactory {
049    @XmlAttribute
050    @XmlID
051    private String id;
052    @XmlValue
053    @Metadata(required = true)
054    private String expression;
055    @XmlAttribute
056    @Metadata(defaultValue = "true", javaType = "java.lang.Boolean")
057    private String trim;
058    @XmlTransient
059    private Predicate predicate;
060    @XmlTransient
061    private Expression expressionValue;
062    @XmlTransient
063    private ExpressionDefinition expressionType;
064
065    public ExpressionDefinition() {
066    }
067
068    public ExpressionDefinition(String expression) {
069        this.expression = expression;
070    }
071
072    public ExpressionDefinition(Predicate predicate) {
073        this.predicate = predicate;
074    }
075
076    public ExpressionDefinition(Expression expression) {
077        this.expressionValue = expression;
078    }
079
080    public static String getLabel(List<ExpressionDefinition> expressions) {
081        CollectionStringBuffer buffer = new CollectionStringBuffer();
082        for (ExpressionDefinition expression : expressions) {
083            buffer.append(expression.getLabel());
084        }
085        return buffer.toString();
086    }
087
088    @Override
089    public String toString() {
090        // favour using the output from expression value
091        if (getExpressionValue() != null) {
092            return getExpressionValue().toString();
093        }
094
095        StringBuilder sb = new StringBuilder();
096        if (getLanguage() != null) {
097            sb.append(getLanguage()).append("{");
098        }
099        if (getPredicate() != null) {
100            sb.append(getPredicate().toString());
101        } else if (getExpression() != null) {
102            sb.append(getExpression());
103        }
104        if (getLanguage() != null) {
105            sb.append("}");
106        }
107        return sb.toString();
108    }
109
110    public String getLanguage() {
111        return "";
112    }
113
114    public String getExpression() {
115        return expression;
116    }
117
118    /**
119     * The expression value in your chosen language syntax
120     */
121    public void setExpression(String expression) {
122        this.expression = expression;
123    }
124
125    public String getId() {
126        return id;
127    }
128
129    /**
130     * Sets the id of this node
131     */
132    public void setId(String value) {
133        this.id = value;
134    }
135
136    public Predicate getPredicate() {
137        return predicate;
138    }
139
140    public Expression getExpressionValue() {
141        return expressionValue;
142    }
143
144    protected void setExpressionValue(Expression expressionValue) {
145        this.expressionValue = expressionValue;
146    }
147
148    public ExpressionDefinition getExpressionType() {
149        return expressionType;
150    }
151
152    public String getTrim() {
153        return trim;
154    }
155
156    /**
157     * Whether to trim the value to remove leading and trailing whitespaces and
158     * line breaks
159     */
160    public void setTrim(String trim) {
161        this.trim = trim;
162    }
163
164    /**
165     * Returns some descriptive text to describe this node
166     */
167    public String getLabel() {
168        Predicate predicate = getPredicate();
169        if (predicate != null) {
170            return predicate.toString();
171        }
172        Expression expressionValue = getExpressionValue();
173        if (expressionValue != null) {
174            return expressionValue.toString();
175        }
176
177        String exp = getExpression();
178        return exp != null ? exp : "";
179    }
180
181    /**
182     * Allows derived classes to set a lazily created expressionType instance
183     * such as if using the {@link org.apache.camel.builder.ExpressionClause}
184     */
185    protected void setExpressionType(ExpressionDefinition expressionType) {
186        this.expressionType = expressionType;
187    }
188
189    //
190    // ExpressionFactory
191    //
192
193    @Override
194    public Expression createExpression(CamelContext camelContext) {
195        return ExpressionReifier.reifier(camelContext, this).createExpression();
196    }
197
198    //
199    // Expression
200    //
201
202    @Override
203    public <T> T evaluate(Exchange exchange, Class<T> type) {
204        if (expressionValue == null) {
205            expressionValue = createExpression(exchange.getContext());
206        }
207        ObjectHelper.notNull(expressionValue, "expressionValue");
208        return expressionValue.evaluate(exchange, type);
209    }
210
211    //
212    // Predicate
213    //
214
215    @Override
216    public boolean matches(Exchange exchange) {
217        if (predicate == null) {
218            predicate = ExpressionReifier.reifier(exchange.getContext(), this).createPredicate();
219        }
220        ObjectHelper.notNull(predicate, "predicate");
221        return predicate.matches(exchange);
222    }
223
224}