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.model;
018
019import javax.xml.bind.annotation.XmlAccessType;
020import javax.xml.bind.annotation.XmlAccessorType;
021import javax.xml.bind.annotation.XmlAttribute;
022import javax.xml.bind.annotation.XmlRootElement;
023import javax.xml.bind.annotation.XmlTransient;
024
025import org.apache.camel.CamelContextAware;
026import org.apache.camel.Endpoint;
027import org.apache.camel.Processor;
028import org.apache.camel.processor.PollEnricher;
029import org.apache.camel.processor.aggregate.AggregationStrategy;
030import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
031import org.apache.camel.spi.RouteContext;
032import org.apache.camel.util.ObjectHelper;
033
034/**
035 * Represents an XML <pollEnrich/> element
036 *
037 * @see org.apache.camel.processor.Enricher
038 */
039@XmlRootElement(name = "pollEnrich")
040@XmlAccessorType(XmlAccessType.FIELD)
041public class PollEnrichDefinition extends NoOutputDefinition<PollEnrichDefinition> 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
048    private Long timeout;
049    @XmlAttribute(name = "strategyRef")
050    private String aggregationStrategyRef;
051    @XmlAttribute(name = "strategyMethodName")
052    private String aggregationStrategyMethodName;
053    @XmlAttribute(name = "strategyMethodAllowNull")
054    private Boolean aggregationStrategyMethodAllowNull;
055    @XmlAttribute
056    private Boolean aggregateOnException;
057    @XmlTransient
058    private AggregationStrategy aggregationStrategy;
059
060    public PollEnrichDefinition() {
061    }
062
063    public PollEnrichDefinition(AggregationStrategy aggregationStrategy, String resourceUri, long timeout) {
064        this.aggregationStrategy = aggregationStrategy;
065        this.resourceUri = resourceUri;
066        this.timeout = timeout;
067    }
068
069    @Override
070    public String toString() {
071        return "PollEnrich[" + description() + " " + aggregationStrategy + "]";
072    }
073    
074    protected String description() {
075        return FromDefinition.description(getResourceUri(), getResourceRef(), (Endpoint) null);
076    }
077
078    @Override
079    public String getShortName() {
080        return "pollEnrich";
081    }
082    
083    @Override
084    public String getLabel() {
085        return "pollEnrich[" + description() + "]";
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        PollEnricher enricher;
112        if (timeout != null) {
113            enricher = new PollEnricher(null, endpoint.createPollingConsumer(), timeout);
114        } else {
115            // if no timeout then we should block, and there use a negative timeout
116            enricher = new PollEnricher(null, endpoint.createPollingConsumer(), -1);
117        }
118
119        AggregationStrategy strategy = createAggregationStrategy(routeContext);
120        if (strategy == null) {
121            enricher.setDefaultAggregationStrategy();
122        } else {
123            enricher.setAggregationStrategy(strategy);
124        }
125        if (getAggregateOnException() != null) {
126            enricher.setAggregateOnException(getAggregateOnException());
127        }
128
129        return enricher;
130    }
131
132    private AggregationStrategy createAggregationStrategy(RouteContext routeContext) {
133        AggregationStrategy strategy = getAggregationStrategy();
134        if (strategy == null && aggregationStrategyRef != null) {
135            Object aggStrategy = routeContext.lookup(aggregationStrategyRef, Object.class);
136            if (aggStrategy instanceof AggregationStrategy) {
137                strategy = (AggregationStrategy) aggStrategy;
138            } else if (aggStrategy != null) {
139                AggregationStrategyBeanAdapter adapter = new AggregationStrategyBeanAdapter(aggStrategy, getAggregationStrategyMethodName());
140                if (getAggregationStrategyMethodAllowNull() != null) {
141                    adapter.setAllowNullNewExchange(getAggregationStrategyMethodAllowNull());
142                    adapter.setAllowNullOldExchange(getAggregationStrategyMethodAllowNull());
143                }
144                strategy = adapter;
145            } else {
146                throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + aggregationStrategyRef);
147            }
148        }
149
150        if (strategy != null && strategy instanceof CamelContextAware) {
151            ((CamelContextAware) strategy).setCamelContext(routeContext.getCamelContext());
152        }
153
154        return strategy;
155    }
156
157    public String getResourceUri() {
158        return resourceUri;
159    }
160
161    public void setResourceUri(String resourceUri) {
162        this.resourceUri = resourceUri;
163    }
164
165    public String getResourceRef() {
166        return resourceRef;
167    }
168
169    public void setResourceRef(String resourceRef) {
170        this.resourceRef = resourceRef;
171    }
172
173    public Long getTimeout() {
174        return timeout;
175    }
176
177    public void setTimeout(Long timeout) {
178        this.timeout = timeout;
179    }
180
181    public String getAggregationStrategyRef() {
182        return aggregationStrategyRef;
183    }
184
185    public void setAggregationStrategyRef(String aggregationStrategyRef) {
186        this.aggregationStrategyRef = aggregationStrategyRef;
187    }
188
189    public String getAggregationStrategyMethodName() {
190        return aggregationStrategyMethodName;
191    }
192
193    public void setAggregationStrategyMethodName(String aggregationStrategyMethodName) {
194        this.aggregationStrategyMethodName = aggregationStrategyMethodName;
195    }
196
197    public Boolean getAggregationStrategyMethodAllowNull() {
198        return aggregationStrategyMethodAllowNull;
199    }
200
201    public void setAggregationStrategyMethodAllowNull(Boolean aggregationStrategyMethodAllowNull) {
202        this.aggregationStrategyMethodAllowNull = aggregationStrategyMethodAllowNull;
203    }
204
205    public AggregationStrategy getAggregationStrategy() {
206        return aggregationStrategy;
207    }
208
209    public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
210        this.aggregationStrategy = aggregationStrategy;
211    }
212
213    public Boolean getAggregateOnException() {
214        return aggregateOnException;
215    }
216
217    public void setAggregateOnException(Boolean aggregateOnException) {
218        this.aggregateOnException = aggregateOnException;
219    }
220}