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 org.apache.camel.Expression;
020import org.apache.camel.Processor;
021import org.apache.camel.Route;
022import org.apache.camel.model.ProcessorDefinition;
023import org.apache.camel.model.ResequenceDefinition;
024import org.apache.camel.model.config.BatchResequencerConfig;
025import org.apache.camel.model.config.ResequencerConfig;
026import org.apache.camel.model.config.StreamResequencerConfig;
027import org.apache.camel.processor.CamelInternalProcessor;
028import org.apache.camel.processor.Resequencer;
029import org.apache.camel.processor.StreamResequencer;
030import org.apache.camel.processor.resequencer.DefaultExchangeComparator;
031import org.apache.camel.processor.resequencer.ExpressionResultComparator;
032import org.apache.camel.util.ObjectHelper;
033
034public class ResequenceReifier extends ProcessorReifier<ResequenceDefinition> {
035
036    public ResequenceReifier(Route route, ProcessorDefinition<?> definition) {
037        super(route, (ResequenceDefinition)definition);
038    }
039
040    @Override
041    public Processor createProcessor() throws Exception {
042        // if configured from XML then streamConfig has been set with the configuration
043        ResequencerConfig resequencer = definition.getResequencerConfig();
044        StreamResequencerConfig stream = definition.getStreamConfig();
045        BatchResequencerConfig batch = definition.getBatchConfig();
046        if (resequencer instanceof StreamResequencerConfig) {
047            stream = (StreamResequencerConfig) resequencer;
048        } else if (resequencer instanceof BatchResequencerConfig) {
049            batch = (BatchResequencerConfig) resequencer;
050        }
051
052        if (stream != null) {
053            return createStreamResequencer(stream);
054        } else {
055            // default as batch mode
056            if (batch == null) {
057                batch = BatchResequencerConfig.getDefault();
058            }
059            return createBatchResequencer(batch);
060        }
061    }
062
063    /**
064     * Creates a batch {@link Resequencer} instance applying the given
065     * <code>config</code>.
066     *
067     * @param config batch resequencer configuration.
068     * @return the configured batch resequencer.
069     * @throws Exception can be thrown
070     */
071    @SuppressWarnings("deprecation")
072    protected Resequencer createBatchResequencer(BatchResequencerConfig config) throws Exception {
073        Processor processor = this.createChildProcessor(true);
074        Expression expression = createExpression(definition.getExpression());
075
076        // and wrap in unit of work
077        CamelInternalProcessor internal = new CamelInternalProcessor(camelContext, processor);
078        internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(route, camelContext));
079
080        ObjectHelper.notNull(config, "config", this);
081        ObjectHelper.notNull(expression, "expression", this);
082
083        boolean isReverse = parseBoolean(config.getReverse(), false);
084        boolean isAllowDuplicates = parseBoolean(config.getAllowDuplicates(), false);
085
086        Resequencer resequencer = new Resequencer(camelContext, internal, expression, isAllowDuplicates, isReverse);
087        resequencer.setBatchSize(parseInt(config.getBatchSize()));
088        resequencer.setBatchTimeout(parseDuration(config.getBatchTimeout()));
089        resequencer.setReverse(isReverse);
090        resequencer.setAllowDuplicates(isAllowDuplicates);
091        if (config.getIgnoreInvalidExchanges() != null) {
092            resequencer.setIgnoreInvalidExchanges(parseBoolean(config.getIgnoreInvalidExchanges(), false));
093        }
094        return resequencer;
095    }
096
097    /**
098     * Creates a {@link StreamResequencer} instance applying the given
099     * <code>config</code>.
100     *
101     * @param config stream resequencer configuration.
102     * @return the configured stream resequencer.
103     * @throws Exception can be thrwon
104     */
105    protected StreamResequencer createStreamResequencer(StreamResequencerConfig config) throws Exception {
106        Processor processor = this.createChildProcessor(true);
107        Expression expression = createExpression(definition.getExpression());
108
109        CamelInternalProcessor internal = new CamelInternalProcessor(camelContext, processor);
110        internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(route, camelContext));
111
112        ObjectHelper.notNull(config, "config", this);
113        ObjectHelper.notNull(expression, "expression", this);
114
115        ExpressionResultComparator comparator;
116        if (config.getComparatorRef() != null) {
117            comparator = mandatoryLookup(config.getComparatorRef(), ExpressionResultComparator.class);
118        } else {
119            comparator = config.getComparator();
120            if (comparator == null) {
121                comparator = new DefaultExchangeComparator();
122            }
123        }
124        comparator.setExpression(expression);
125
126        StreamResequencer resequencer = new StreamResequencer(camelContext, internal, comparator, expression);
127        resequencer.setTimeout(parseDuration(config.getTimeout()));
128        if (config.getDeliveryAttemptInterval() != null) {
129            resequencer.setDeliveryAttemptInterval(parseDuration(config.getDeliveryAttemptInterval()));
130        }
131        resequencer.setCapacity(parseInt(config.getCapacity()));
132        resequencer.setRejectOld(parseBoolean(config.getRejectOld(), false));
133        if (config.getIgnoreInvalidExchanges() != null) {
134            resequencer.setIgnoreInvalidExchanges(parseBoolean(config.getIgnoreInvalidExchanges(), false));
135        }
136        return resequencer;
137    }
138
139}