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     */
017    package org.apache.camel.model;
018    
019    import javax.xml.bind.annotation.XmlAccessType;
020    import javax.xml.bind.annotation.XmlAccessorType;
021    import javax.xml.bind.annotation.XmlAttribute;
022    import javax.xml.bind.annotation.XmlRootElement;
023    import javax.xml.bind.annotation.XmlTransient;
024    
025    import org.apache.camel.CamelContextAware;
026    import org.apache.camel.Endpoint;
027    import org.apache.camel.Processor;
028    import org.apache.camel.processor.Enricher;
029    import org.apache.camel.processor.aggregate.AggregationStrategy;
030    import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
031    import org.apache.camel.spi.RouteContext;
032    import org.apache.camel.util.ObjectHelper;
033    
034    /**
035     * Represents an XML <enrich/> element
036     *
037     * @see Enricher
038     */
039    @XmlRootElement(name = "enrich")
040    @XmlAccessorType(XmlAccessType.FIELD)
041    public class EnrichDefinition extends NoOutputDefinition<EnrichDefinition> implements EndpointRequiredDefinition {
042        @XmlAttribute(name = "uri")
043        private String resourceUri;
044        // TODO: For Camel 3.0 we should remove this ref attribute as you can do that in the uri, by prefixing with ref:
045        @XmlAttribute(name = "ref")
046        private String resourceRef;
047        @XmlAttribute(name = "strategyRef")
048        private String aggregationStrategyRef;
049        @XmlAttribute(name = "strategyMethodName")
050        private String aggregationStrategyMethodName;
051        @XmlAttribute(name = "strategyMethodAllowNull")
052        private Boolean aggregationStrategyMethodAllowNull;
053        @XmlTransient
054        private AggregationStrategy aggregationStrategy;
055        
056        public EnrichDefinition() {
057            this(null, null);
058        }
059    
060        public EnrichDefinition(String resourceUri) {
061            this(null, resourceUri);
062        }
063        
064        public EnrichDefinition(AggregationStrategy aggregationStrategy, String resourceUri) {
065            this.aggregationStrategy = aggregationStrategy;
066            this.resourceUri = resourceUri;
067        }
068        
069        @Override
070        public String toString() {
071            return "Enrich[" + description() + " " + aggregationStrategy + "]";
072        }
073        
074        protected String description() {
075            return FromDefinition.description(resourceUri, resourceRef, (Endpoint) null);
076        }
077        
078        @Override
079        public String getLabel() {
080            return "enrich[" + description() + "]";
081        }
082    
083        @Override
084        public String getShortName() {
085            return "enrich";
086        }
087    
088        @Override
089        public String getEndpointUri() {
090            if (resourceUri != null) {
091                return resourceUri;
092            } else {
093                return null;
094            }
095        }
096    
097        @Override
098        public Processor createProcessor(RouteContext routeContext) throws Exception {
099            if (ObjectHelper.isEmpty(resourceUri) && ObjectHelper.isEmpty(resourceRef)) {
100                throw new IllegalArgumentException("Either uri or ref must be provided for resource endpoint");
101            }
102    
103            // lookup endpoint
104            Endpoint endpoint;
105            if (resourceUri != null) {
106                endpoint = routeContext.resolveEndpoint(resourceUri);
107            } else {
108                endpoint = routeContext.resolveEndpoint(null, resourceRef);
109            }
110    
111            Enricher enricher = new Enricher(null, endpoint.createProducer());
112            AggregationStrategy strategy = createAggregationStrategy(routeContext);
113            if (strategy == null) {
114                enricher.setDefaultAggregationStrategy();
115            } else {
116                enricher.setAggregationStrategy(strategy);
117            }
118            return enricher;
119        }
120    
121        private AggregationStrategy createAggregationStrategy(RouteContext routeContext) {
122            AggregationStrategy strategy = getAggregationStrategy();
123            if (strategy == null && aggregationStrategyRef != null) {
124                Object aggStrategy = routeContext.lookup(aggregationStrategyRef, Object.class);
125                if (aggStrategy instanceof AggregationStrategy) {
126                    strategy = (AggregationStrategy) aggStrategy;
127                } else if (aggStrategy != null) {
128                    AggregationStrategyBeanAdapter adapter = new AggregationStrategyBeanAdapter(aggStrategy, getAggregationStrategyMethodName());
129                    if (getAggregationStrategyMethodAllowNull() != null) {
130                        adapter.setAllowNullNewExchange(getAggregationStrategyMethodAllowNull());
131                        adapter.setAllowNullOldExchange(getAggregationStrategyMethodAllowNull());
132                    }
133                    strategy = adapter;
134                } else {
135                    throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + aggregationStrategyRef);
136                }
137            }
138    
139            if (strategy != null && strategy instanceof CamelContextAware) {
140                ((CamelContextAware) strategy).setCamelContext(routeContext.getCamelContext());
141            }
142    
143            return strategy;
144        }
145    
146        public String getResourceUri() {
147            return resourceUri;
148        }
149    
150        public void setResourceUri(String resourceUri) {
151            this.resourceUri = resourceUri;
152        }
153    
154        public String getResourceRef() {
155            return resourceRef;
156        }
157    
158        public void setResourceRef(String resourceRef) {
159            this.resourceRef = resourceRef;
160        }
161    
162        public String getAggregationStrategyRef() {
163            return aggregationStrategyRef;
164        }
165    
166        public void setAggregationStrategyRef(String aggregationStrategyRef) {
167            this.aggregationStrategyRef = aggregationStrategyRef;
168        }
169    
170        public String getAggregationStrategyMethodName() {
171            return aggregationStrategyMethodName;
172        }
173    
174        public void setAggregationStrategyMethodName(String aggregationStrategyMethodName) {
175            this.aggregationStrategyMethodName = aggregationStrategyMethodName;
176        }
177    
178        public Boolean getAggregationStrategyMethodAllowNull() {
179            return aggregationStrategyMethodAllowNull;
180        }
181    
182        public void setAggregationStrategyMethodAllowNull(Boolean aggregationStrategyMethodAllowNull) {
183            this.aggregationStrategyMethodAllowNull = aggregationStrategyMethodAllowNull;
184        }
185    
186        public AggregationStrategy getAggregationStrategy() {
187            return aggregationStrategy;
188        }
189    
190        public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
191            this.aggregationStrategy = aggregationStrategy;
192        }
193    }