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