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