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.AggregationStrategy;
020import org.apache.camel.CamelContextAware;
021import org.apache.camel.Processor;
022import org.apache.camel.model.ClaimCheckDefinition;
023import org.apache.camel.model.ProcessorDefinition;
024import org.apache.camel.processor.ClaimCheckProcessor;
025import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
026import org.apache.camel.spi.RouteContext;
027import org.apache.camel.support.ObjectHelper;
028
029import static org.apache.camel.util.ObjectHelper.notNull;
030
031public class ClaimCheckReifier extends ProcessorReifier<ClaimCheckDefinition> {
032
033    public ClaimCheckReifier(ProcessorDefinition<?> definition) {
034        super(ClaimCheckDefinition.class.cast(definition));
035    }
036
037    @Override
038    public Processor createProcessor(RouteContext routeContext) throws Exception {
039        notNull(definition.getOperation(), "operation", this);
040
041        ClaimCheckProcessor claim = new ClaimCheckProcessor();
042        claim.setOperation(definition.getOperation().name());
043        claim.setKey(definition.getKey());
044        claim.setFilter(definition.getFilter());
045
046        AggregationStrategy strategy = createAggregationStrategy(routeContext);
047        if (strategy != null) {
048            claim.setAggregationStrategy(strategy);
049        }
050
051        // only filter or aggregation strategy can be configured not both
052        if (definition.getFilter() != null && strategy != null) {
053            throw new IllegalArgumentException("Cannot use both filter and custom aggregation strategy on ClaimCheck EIP");
054        }
055
056        // validate filter, we cannot have both +/- at the same time
057        if (definition.getFilter() != null) {
058            Iterable it = ObjectHelper.createIterable(definition.getFilter(), ",");
059            boolean includeBody = false;
060            boolean excludeBody = false;
061            for (Object o : it) {
062                String pattern = o.toString();
063                if ("body".equals(pattern) || "+body".equals(pattern)) {
064                    includeBody = true;
065                } else if ("-body".equals(pattern)) {
066                    excludeBody = true;
067                }
068            }
069            if (includeBody && excludeBody) {
070                throw new IllegalArgumentException("Cannot have both include and exclude body at the same time in the filter: " + definition.getFilter());
071            }
072            boolean includeHeaders = false;
073            boolean excludeHeaders = false;
074            for (Object o : it) {
075                String pattern = o.toString();
076                if ("headers".equals(pattern) || "+headers".equals(pattern)) {
077                    includeHeaders = true;
078                } else if ("-headers".equals(pattern)) {
079                    excludeHeaders = true;
080                }
081            }
082            if (includeHeaders && excludeHeaders) {
083                throw new IllegalArgumentException("Cannot have both include and exclude headers at the same time in the filter: " + definition.getFilter());
084            }
085            boolean includeHeader = false;
086            boolean excludeHeader = false;
087            for (Object o : it) {
088                String pattern = o.toString();
089                if (pattern.startsWith("header:") || pattern.startsWith("+header:")) {
090                    includeHeader = true;
091                } else if (pattern.startsWith("-header:")) {
092                    excludeHeader = true;
093                }
094            }
095            if (includeHeader && excludeHeader) {
096                throw new IllegalArgumentException("Cannot have both include and exclude header at the same time in the filter: " + definition.getFilter());
097            }
098        }
099
100        return claim;
101    }
102
103    private AggregationStrategy createAggregationStrategy(RouteContext routeContext) {
104        AggregationStrategy strategy = definition.getAggregationStrategy();
105        if (strategy == null && definition.getAggregationStrategyRef() != null) {
106            Object aggStrategy = routeContext.lookup(definition.getAggregationStrategyRef(), Object.class);
107            if (aggStrategy instanceof AggregationStrategy) {
108                strategy = (AggregationStrategy)aggStrategy;
109            } else if (aggStrategy != null) {
110                strategy = new AggregationStrategyBeanAdapter(aggStrategy, definition.getAggregationStrategyMethodName());
111            } else {
112                throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + definition.getAggregationStrategyRef());
113            }
114        }
115
116        if (strategy instanceof CamelContextAware) {
117            ((CamelContextAware)strategy).setCamelContext(routeContext.getCamelContext());
118        }
119
120        return strategy;
121    }
122
123}