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 java.util.Map;
020import java.util.function.BiPredicate;
021import java.util.function.Predicate;
022
023import org.apache.camel.Exchange;
024import org.apache.camel.Message;
025
026public class PredicateClause<T> implements org.apache.camel.Predicate {
027    private final T parent;
028    private Predicate<Exchange> predicate;
029
030    public PredicateClause(T parent) {
031        this.parent = parent;
032        this.predicate = null;
033    }
034
035    @Override
036    public boolean matches(Exchange exchange) {
037        return (predicate != null) ? predicate.test(exchange) : false;
038    }
039
040    // *******************************
041    // Exchange
042    // *******************************
043
044    /**
045     * Define a {@link org.apache.camel.Predicate} which targets the Exchange.
046     */
047    public T exchange(final Predicate<Exchange> predicate) {
048        this.predicate = predicate::test;
049        return parent;
050    }
051
052    // *******************************
053    // Message
054    // *******************************
055
056    /**
057     * Define a {@link org.apache.camel.Predicate} which targets the Exchange In
058     * Message. <blockquote>
059     * 
060     * <pre>
061     * {@code
062     * from("direct:aggregate")
063     *     .choice()
064     *         .when()
065     *            .message(m -> m.getBody() != null)
066     *            .log("Received ${body}")
067     *     .endChoice()
068     * }
069     * </pre>
070     * 
071     * </blockquote>
072     */
073    public T message(final Predicate<Message> predicate) {
074        return exchange(e -> predicate.test(e.getIn()));
075    }
076
077    // *******************************
078    // Body
079    // *******************************
080
081    /**
082     * Define a {@link org.apache.camel.Predicate} which targets the Exchange In
083     * Body. <blockquote>
084     * 
085     * <pre>
086     * {@code
087     * from("direct:aggregate")
088     *     .choice()
089     *         .when()
090     *            .body(b -> b != null)
091     *            .log("Received ${body}")
092     *     .endChoice()
093     * }
094     * </pre>
095     * 
096     * </blockquote>
097     */
098    public T body(final Predicate<Object> predicate) {
099        return exchange(e -> predicate.test(e.getIn().getBody()));
100    }
101
102    /**
103     * Define a {@link org.apache.camel.Predicate} which targets the typed
104     * Exchange In Body. <blockquote>
105     * 
106     * <pre>
107     * {@code
108     * from("direct:aggregate")
109     *     .choice()
110     *         .when()
111     *            .body(Long.class, b -> (b & 1) == 0)
112     *            .log("Received even number ${body}")
113     *     .endChoice()
114     * }
115     * </pre>
116     * 
117     * </blockquote>
118     */
119    public <B> T body(final Class<B> type, final Predicate<B> predicate) {
120        return exchange(e -> predicate.test(e.getIn().getBody(type)));
121    }
122
123    /**
124     * Define a {@link org.apache.camel.Predicate} which targets the Exchange In
125     * Body and its Headers. <blockquote>
126     * 
127     * <pre>
128     * {@code
129     * from("direct:aggregate")
130     *     .choice()
131     *         .when()
132     *            .body((b, h) -> b != null || h.containsKy("ToProcess"))
133     *            .log("Received ${body}")
134     *     .endChoice()
135     * }
136     * </pre>
137     * 
138     * </blockquote>
139     */
140    public T body(final BiPredicate<Object, Map<String, Object>> predicate) {
141        return exchange(e -> predicate.test(e.getIn().getBody(), e.getIn().getHeaders()));
142    }
143
144    /**
145     * Define a {@link org.apache.camel.Predicate} which targets the typed
146     * Exchange In Body and its Headers. <blockquote>
147     * 
148     * <pre>
149     * {@code
150     * from("direct:aggregate")
151     *     .choice()
152     *         .when()
153     *            .body(String.class, (b, h) -> b != null && !b.isEmpty() || h.containsKy("ToProcess"))
154     *            .log("Received ${body}")
155     *     .endChoice()
156     * }
157     * </pre>
158     * 
159     * </blockquote>
160     */
161    public <B> T body(final Class<B> type, final BiPredicate<B, Map<String, Object>> predicate) {
162        return exchange(e -> predicate.test(e.getIn().getBody(type), e.getIn().getHeaders()));
163    }
164}