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