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    // *******************************
056    // Message
057    // *******************************
058    
059    /**
060     * Define a {@link Processor} which targets the Exchange In Message.
061     *     
062     * <blockquote><pre>{@code
063     * from("direct:aggregate")
064     *     .process()
065     *         .message(m -> m.setHeader("HasBody", m.getBody() != null));
066     * }</pre></blockquote>
067     */
068    public T message(final Consumer<Message> consumer) {
069        processor = e -> consumer.accept(e.getIn());
070        return parent;
071    }
072
073    // *******************************
074    // Body
075    // *******************************
076
077    /**
078     * Define a {@link Processor} which targets the Exchange In Body.
079     *     
080     * <blockquote><pre>{@code
081     * from("direct:aggregate")
082     *     .process()
083     *         .body(System.out::println);
084     * }</pre></blockquote>
085     */
086    public T body(final Consumer<Object> consumer) {
087        processor = e -> consumer.accept(e.getIn().getBody());
088        return parent;
089    }
090
091    /**
092     * Define a {@link Processor} which targets the typed Exchange In Body.
093     *     
094     * <blockquote><pre>{@code
095     * from("direct:aggregate")
096     *     .process()
097     *         .body(MyObject.class, MyObject::dumpToStdOut);
098     * }</pre></blockquote>
099     */
100    public <B> T body(Class<B> type, final Consumer<B> consumer) {
101        processor = e -> consumer.accept(e.getIn().getBody(type));
102        return parent;
103    }
104    
105    /**
106     * Define a {@link Processor} which targets the Exchange In Body and its Headers.
107     *     
108     * <blockquote><pre>{@code
109     * from("direct:aggregate")
110     *     .process()
111     *         .body((b, h) -> h.put("ClassName", b.getClass().getName()));
112     * }</pre></blockquote>
113     */
114    public T body(final BiConsumer<Object, Map<String, Object>> consumer) {
115        processor = e -> consumer.accept(
116            e.getIn().getBody(),
117            e.getIn().getHeaders()
118        );
119        return parent;
120    }
121    
122    /**
123     * Define a {@link Processor} which targets the typed Exchange In Body and its Headers.
124     *     
125     * <blockquote><pre>{@code
126     * from("direct:aggregate")
127     *     .process()
128     *         .body(MyObject.class, (b, h) -> { 
129     *             if (h.containsKey("dump")) {
130     *                  b.dumpToStdOut();
131     *             }
132     *         });
133     * }</pre></blockquote>
134     */
135    public <B> T body(Class<B> type, final BiConsumer<B, Map<String, Object>> consumer) {
136        processor = e -> consumer.accept(
137            e.getIn().getBody(type),
138            e.getIn().getHeaders()
139        );
140        return parent;
141    }
142}