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