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 */ 017 018package org.apache.camel.builder; 019 020import java.util.function.BiFunction; 021 022import org.apache.camel.Exchange; 023import org.apache.camel.Message; 024import org.apache.camel.processor.aggregate.AggregationStrategy; 025import org.apache.camel.util.ObjectHelper; 026 027public class AggregationStrategyClause<T> implements AggregationStrategy { 028 private final T parent; 029 private AggregationStrategy strategy; 030 031 public AggregationStrategyClause(T parent) { 032 this.parent = parent; 033 this.strategy = null; 034 } 035 036 @Override 037 public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { 038 return ObjectHelper.notNull(strategy, "AggregationStrategy").aggregate(oldExchange, newExchange); 039 } 040 041 // ******************************* 042 // Exchange 043 // ******************************* 044 045 /** 046 * Define an aggregation strategy which targets the exchnage. 047 */ 048 public T exchange(final BiFunction<Exchange, Exchange, Exchange> function) { 049 strategy = function::apply; 050 return parent; 051 } 052 053 // ******************************* 054 // Message 055 // ******************************* 056 057 /** 058 * Define an aggregation strategy which targets Exchanges In Message. 059 * 060 * <blockquote><pre>{@code 061 * from("direct:aggregate") 062 * .aggregate() 063 * .message((old, new) -> { 064 * if (old == null) { 065 * return new; 066 * } 067 * 068 * String oldBody = old.getBody(String.class); 069 * String newBody = new.getBody(String.class); 070 * 071 * old.setBody(oldBody + "+" + newBody); 072 * 073 * return old; 074 * }); 075 * }</pre></blockquote> 076 */ 077 public T message(final BiFunction<Message, Message, Message> function) { 078 return exchange((Exchange oldExchange, Exchange newExchange) -> { 079 Message oldMessage = oldExchange != null ? oldExchange.getIn() : null; 080 Message newMessage = ObjectHelper.notNull(newExchange, "NewExchange").getIn(); 081 Message result = function.apply(oldMessage, newMessage); 082 083 if (oldExchange != null) { 084 oldExchange.setIn(result); 085 return oldExchange; 086 } else { 087 newExchange.setIn(result); 088 return newExchange; 089 } 090 }); 091 } 092 093 // ******************************* 094 // Body 095 // ******************************* 096 097 /** 098 * Define an aggregation strategy which targets Exchanges In Body. 099 * 100 * <blockquote><pre>{@code 101 * from("direct:aggregate") 102 * .aggregate() 103 * .body((old, new) -> { 104 * if (old == null) { 105 * return new; 106 * } 107 * 108 * return old.toString() + new.toString(); 109 * }); 110 * }</pre></blockquote> 111 */ 112 public T body(final BiFunction<Object, Object, Object> function) { 113 return body(Object.class, function); 114 } 115 116 /** 117 * Define an aggregation strategy which targets Exchanges In Body. 118 * 119 * <blockquote><pre>{@code 120 * from("direct:aggregate") 121 * .aggregate() 122 * .body(String.class, (old, new) -> { 123 * if (old == null) { 124 * return new; 125 * } 126 * 127 * return old + new; 128 * }); 129 * }</pre></blockquote> 130 */ 131 public <B> T body(final Class<B> type, final BiFunction<B, B, Object> function) { 132 return body(type, type, function); 133 } 134 135 /** 136 * Define an aggregation strategy which targets Exchanges In Body. 137 */ 138 public <O, N> T body(final Class<O> oldType, final Class<N> newType, final BiFunction<O, N, Object> function) { 139 return exchange((Exchange oldExchange, Exchange newExchange) -> { 140 Message oldMessage = oldExchange != null ? oldExchange.getIn() : null; 141 Message newMessage = ObjectHelper.notNull(newExchange, "NewExchange").getIn(); 142 143 Object result = function.apply( 144 oldMessage != null ? oldMessage.getBody(oldType) : null, 145 newMessage != null ? newMessage.getBody(newType) : null); 146 147 if (oldExchange != null) { 148 oldExchange.getIn().setBody(result); 149 return oldExchange; 150 } else { 151 newExchange.getIn().setBody(result); 152 return newExchange; 153 } 154 }); 155 } 156}