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.component.feed;
018    
019    import java.util.Date;
020    
021    import org.apache.camel.Consumer;
022    import org.apache.camel.Exchange;
023    import org.apache.camel.Processor;
024    import org.apache.camel.Producer;
025    import org.apache.camel.impl.DefaultPollingEndpoint;
026    import org.apache.camel.util.ObjectHelper;
027    
028    /**
029     * A base class for feed (atom, RSS) endpoints.
030     */
031    public abstract class FeedEndpoint extends DefaultPollingEndpoint {
032    
033        protected String feedUri;
034        protected boolean splitEntries = true;
035        protected Date lastUpdate;
036        protected boolean filter = true;
037        private boolean feedHeader = true;
038        private boolean sortEntries;
039    
040        public FeedEndpoint() {
041        }
042    
043        public FeedEndpoint(String endpointUri, FeedComponent component, String feedUri) {
044            super(endpointUri, component);
045            this.feedUri = feedUri;
046        }
047    
048        public FeedEndpoint(String endpointUri, String feedUri) {
049            this(endpointUri);
050            this.feedUri = feedUri;
051        }
052    
053        public FeedEndpoint(String endpointUri) {
054            super(endpointUri);
055        }
056    
057        public boolean isSingleton() {
058            return true;
059        }
060    
061        public Producer createProducer() throws Exception {
062            throw new UnsupportedOperationException("FeedProducer is not implemented");
063        }
064    
065        public Consumer createConsumer(Processor processor) throws Exception {
066            ObjectHelper.notNull(feedUri, "feedUri");
067    
068            FeedPollingConsumer answer;
069            if (isSplitEntries()) {
070                answer = createEntryPollingConsumer(this, processor, filter, lastUpdate);
071            } else {
072                answer = createPollingConsumer(this, processor);
073            }
074            
075            // ScheduledPollConsumer default delay is 500 millis and that is too often for polling a feed,
076            // so we override with a new default value. End user can override this value by providing a consumer.delay parameter
077            answer.setDelay(FeedPollingConsumer.DEFAULT_CONSUMER_DELAY);
078            configureConsumer(answer);
079            return answer;
080        }
081    
082        protected abstract FeedPollingConsumer createPollingConsumer(FeedEndpoint feedEndpoint, Processor processor);
083    
084        protected abstract FeedPollingConsumer createEntryPollingConsumer(FeedEndpoint feedEndpoint, Processor processor, boolean filter, Date lastUpdate);
085    
086        protected Exchange createExchangeWithFeedHeader(Object feed, String header) {
087            Exchange exchange = createExchange();
088            if (isFeedHeader()) {
089                exchange.getIn().setHeader(header, feed);
090            }
091            return exchange;
092        }    
093        
094        /**
095         * Creates an Exchange with the entries as the in body.
096         *
097         * @param feed   the atom feed
098         * @return the created exchange
099         */
100        public abstract Exchange createExchange(Object feed);
101    
102        /**
103         * Creates an Exchange with the given entry as the in body.
104         *
105         * @param feed   the feed
106         * @param entry  the entry as the in body
107         * @return the created exchange
108         */
109        public abstract Exchange createExchange(Object feed, Object entry);
110    
111        @Override
112        protected String createEndpointUri() {
113            return "atom:" + feedUri;
114        }
115    
116        @Override
117        public String getEndpointKey() {
118            // use the full endpoint uri because the lenient properties matters as they should be unique based on the feed uri
119            return getEndpointUri();
120        }
121    
122        // Properties
123        //-------------------------------------------------------------------------
124    
125        public String getFeedUri() {
126            return feedUri;
127        }
128    
129        public void setFeedUri(String feedUri) {
130            this.feedUri = feedUri;
131        }
132    
133        public boolean isSplitEntries() {
134            return splitEntries;
135        }
136    
137        /**
138         * Sets whether or not entries should be sent individually or whether the entire
139         * feed should be sent as a single message
140         */
141        public void setSplitEntries(boolean splitEntries) {
142            this.splitEntries = splitEntries;
143        }
144    
145        public Date getLastUpdate() {
146            return lastUpdate;
147        }
148    
149        /**
150         * Sets the timestamp to be used for filtering entries from the atom feeds.
151         * This options is only in conjunction with the splitEntries.
152         */
153        public void setLastUpdate(Date lastUpdate) {
154            this.lastUpdate = lastUpdate;
155        }
156    
157        public boolean isFilter() {
158            return filter;
159        }
160    
161        /**
162         * Sets whether to use filtering or not of the entries.
163         */
164        public void setFilter(boolean filter) {
165            this.filter = filter;
166        }
167    
168        /**
169         * Sets whether to add the feed object as a header
170         */
171        public void setFeedHeader(boolean feedHeader) {
172            this.feedHeader = feedHeader;
173        }
174    
175        public boolean isFeedHeader() {
176            return feedHeader;
177        }
178    
179        /**
180         * Sets whether to sort entries by published date. Only works when splitEntries = true.
181         */
182        public void setSortEntries(boolean sortEntries) {
183            this.sortEntries = sortEntries;
184        }
185    
186        public boolean isSortEntries() {
187            return sortEntries;
188        }      
189    
190        public boolean isLenientProperties() {
191            // true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
192            return true;
193        }
194    
195        // Implementation methods
196        //-------------------------------------------------------------------------
197    
198    }