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.reifier;
018
019import java.util.concurrent.ExecutorService;
020
021import org.apache.camel.AggregationStrategy;
022import org.apache.camel.CamelContextAware;
023import org.apache.camel.Expression;
024import org.apache.camel.Processor;
025import org.apache.camel.Route;
026import org.apache.camel.model.ProcessorDefinition;
027import org.apache.camel.model.SplitDefinition;
028import org.apache.camel.processor.Splitter;
029import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
030import org.apache.camel.processor.aggregate.ShareUnitOfWorkAggregationStrategy;
031
032public class SplitReifier extends ExpressionReifier<SplitDefinition> {
033
034    public SplitReifier(Route route, ProcessorDefinition<?> definition) {
035        super(route, (SplitDefinition)definition);
036    }
037
038    @Override
039    public Processor createProcessor() throws Exception {
040        Processor childProcessor = this.createChildProcessor(true);
041        definition.setAggregationStrategy(createAggregationStrategy());
042
043        boolean isParallelProcessing = parseBoolean(definition.getParallelProcessing(), false);
044        boolean isStreaming = parseBoolean(definition.getStreaming(), false);
045        boolean isShareUnitOfWork = parseBoolean(definition.getShareUnitOfWork(), false);
046        boolean isParallelAggregate = parseBoolean(definition.getParallelAggregate(), false);
047        boolean isStopOnAggregateException = parseBoolean(definition.getStopOnAggregateException(), false);
048        boolean isStopOnException = parseBoolean(definition.getStopOnException(), false);
049        boolean shutdownThreadPool = willCreateNewThreadPool(definition, isParallelProcessing);
050        ExecutorService threadPool = getConfiguredExecutorService("Split", definition, isParallelProcessing);
051
052        long timeout = definition.getTimeout() != null ? parseDuration(definition.getTimeout()) : 0;
053        if (timeout > 0 && !isParallelProcessing) {
054            throw new IllegalArgumentException("Timeout is used but ParallelProcessing has not been enabled.");
055        }
056        if (definition.getOnPrepareRef() != null) {
057            definition.setOnPrepare(mandatoryLookup(parseString(definition.getOnPrepareRef()), Processor.class));
058        }
059
060        Expression exp = createExpression(definition.getExpression());
061
062        Splitter answer = new Splitter(camelContext, route, exp, childProcessor, definition.getAggregationStrategy(), isParallelProcessing, threadPool,
063                                       shutdownThreadPool, isStreaming, isStopOnException, timeout, definition.getOnPrepare(), isShareUnitOfWork, isParallelAggregate,
064                                       isStopOnAggregateException);
065        return answer;
066    }
067
068    private AggregationStrategy createAggregationStrategy() {
069        AggregationStrategy strategy = definition.getAggregationStrategy();
070        if (strategy == null && definition.getStrategyRef() != null) {
071            Object aggStrategy = lookup(definition.getStrategyRef(), Object.class);
072            if (aggStrategy instanceof AggregationStrategy) {
073                strategy = (AggregationStrategy)aggStrategy;
074            } else if (aggStrategy != null) {
075                AggregationStrategyBeanAdapter adapter = new AggregationStrategyBeanAdapter(aggStrategy, definition.getStrategyMethodName());
076                if (definition.getStrategyMethodAllowNull() != null) {
077                    adapter.setAllowNullNewExchange(parseBoolean(definition.getStrategyMethodAllowNull(), false));
078                    adapter.setAllowNullOldExchange(parseBoolean(definition.getStrategyMethodAllowNull(), false));
079                }
080                strategy = adapter;
081            } else {
082                throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + definition.getStrategyRef());
083            }
084        }
085
086        if (strategy instanceof CamelContextAware) {
087            ((CamelContextAware)strategy).setCamelContext(camelContext);
088        }
089
090        if (strategy != null && parseBoolean(definition.getShareUnitOfWork(), false)) {
091            // wrap strategy in share unit of work
092            strategy = new ShareUnitOfWorkAggregationStrategy(strategy);
093        }
094
095        return strategy;
096    }
097
098}