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