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}