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.builder;
018
019import org.apache.camel.CamelContext;
020import org.apache.camel.Expression;
021import org.apache.camel.Predicate;
022import org.apache.camel.model.Model;
023import org.apache.camel.model.language.ExpressionDefinition;
024import org.apache.camel.model.validator.CustomValidatorDefinition;
025import org.apache.camel.model.validator.EndpointValidatorDefinition;
026import org.apache.camel.model.validator.PredicateValidatorDefinition;
027import org.apache.camel.model.validator.ValidatorDefinition;
028import org.apache.camel.spi.AsPredicate;
029import org.apache.camel.spi.DataType;
030import org.apache.camel.spi.Validator;
031
032/**
033 * A <a href="http://camel.apache.org/dsl.html">Java DSL</a> which is used to
034 * build a {@link org.apache.camel.spi.Validator} and register into
035 * {@link org.apache.camel.CamelContext}. It requires a 'type' to be specified
036 * by type() method. And then you can choose a type of validator by withUri(),
037 * withPredicate(), withJava() or withBean() method.
038 */
039public class ValidatorBuilder {
040
041    private String type;
042    private String uri;
043    private ExpressionDefinition expression;
044    private Class<? extends Validator> clazz;
045    private String beanRef;
046
047    /**
048     * Set the data type name. If you specify 'xml:XYZ', the validator will be
049     * picked up if source type is 'xml:XYZ'. If you specify just 'xml', the
050     * validator matches with all of 'xml' source type like 'xml:ABC' or
051     * 'xml:DEF'.
052     *
053     * @param type 'from' data type name
054     */
055    public ValidatorBuilder type(String type) {
056        this.type = type;
057        return this;
058    }
059
060    /**
061     * Set the data type using Java class.
062     *
063     * @param type Java class represents data type
064     */
065    public ValidatorBuilder type(Class<?> type) {
066        this.type = new DataType(type).toString();
067        return this;
068    }
069
070    /**
071     * Set the URI to be used for the endpoint {@link Validator}.
072     * 
073     * @see EndpointValidatorDefinition, ProcessorValidator
074     * @param uri endpoint URI
075     */
076    public ValidatorBuilder withUri(String uri) {
077        resetType();
078        this.uri = uri;
079        return this;
080    }
081
082    /**
083     * Set the {@link Expression} to be used for the predicate
084     * {@link Validator}.
085     * 
086     * @see PredicateValidatorDefinition, ProcessorValidator
087     * @param expression validation expression
088     */
089    public ValidatorBuilder withExpression(@AsPredicate Expression expression) {
090        resetType();
091        this.expression = new ExpressionDefinition(expression);
092        return this;
093    }
094
095    /**
096     * Set the {@link Predicate} to be used for the predicate {@link Validator}.
097     * 
098     * @see PredicateValidatorDefinition, ProcessorValidator
099     * @param predicate validation predicate
100     */
101    public ValidatorBuilder withExpression(@AsPredicate Predicate predicate) {
102        resetType();
103        this.expression = new ExpressionDefinition(predicate);
104        return this;
105    }
106
107    /**
108     * Set the Java {@code Class} represents a custom {@code Validator}
109     * implementation class.
110     * 
111     * @see CustomValidatorDefinition
112     * @param clazz {@code Class} object represents custom validator
113     *            implementation
114     */
115    public ValidatorBuilder withJava(Class<? extends Validator> clazz) {
116        resetType();
117        this.clazz = clazz;
118        return this;
119    }
120
121    /**
122     * Set the Java Bean name to be used for custom {@code Validator}.
123     * 
124     * @see CustomValidatorDefinition
125     * @param ref bean name for the custom {@code Validator}
126     */
127    public ValidatorBuilder withBean(String ref) {
128        resetType();
129        this.beanRef = ref;
130        return this;
131    }
132
133    private void resetType() {
134        this.uri = null;
135        this.expression = null;
136        this.clazz = null;
137        this.beanRef = null;
138    }
139
140    /**
141     * Configures a new Validator according to the configurations built on this
142     * builder and register it into the given {@code CamelContext}.
143     * 
144     * @param camelContext the given CamelContext
145     */
146    public void configure(CamelContext camelContext) {
147        ValidatorDefinition validator;
148        if (uri != null) {
149            EndpointValidatorDefinition etd = new EndpointValidatorDefinition();
150            etd.setUri(uri);
151            validator = etd;
152        } else if (expression != null) {
153            PredicateValidatorDefinition dtd = new PredicateValidatorDefinition();
154            dtd.setExpression(expression);
155            validator = dtd;
156        } else if (clazz != null) {
157            CustomValidatorDefinition ctd = new CustomValidatorDefinition();
158            ctd.setClassName(clazz.getName());
159            validator = ctd;
160        } else if (beanRef != null) {
161            CustomValidatorDefinition ctd = new CustomValidatorDefinition();
162            ctd.setRef(beanRef);
163            validator = ctd;
164        } else {
165            throw new IllegalArgumentException("No Validator type was specified");
166        }
167
168        validator.setType(type);
169        camelContext.getExtension(Model.class).getValidators().add(validator);
170    }
171}