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.file.remote;
018    
019    import org.apache.camel.Processor;
020    import org.apache.camel.component.file.GenericFile;
021    import org.apache.camel.component.file.GenericFileEndpoint;
022    import org.apache.camel.component.file.GenericFileExchange;
023    import org.apache.camel.component.file.GenericFileProducer;
024    import org.apache.camel.processor.idempotent.MemoryIdempotentRepository;
025    import org.apache.camel.util.ObjectHelper;
026    
027    /**
028     * Remote file endpoint.
029     */
030    public abstract class RemoteFileEndpoint<T> extends GenericFileEndpoint<T> {
031    
032        public RemoteFileEndpoint() {
033            // no args constructor for spring bean endpoint configuration
034        }
035    
036        public RemoteFileEndpoint(String uri, RemoteFileComponent<T> component, RemoteFileConfiguration configuration) {
037            super(uri, component);
038            this.configuration = configuration;
039        }
040    
041        @Override
042        public GenericFileExchange createExchange() {
043            return new RemoteFileExchange(this);
044        }
045    
046        @Override
047        @SuppressWarnings("unchecked")
048        public GenericFileExchange<T> createExchange(GenericFile<T> file) {
049            RemoteFileExchange answer = new RemoteFileExchange<T>(this);
050            answer.setGenericFile(file);
051            return answer;
052        }
053    
054        @Override
055        public GenericFileProducer<T> createProducer() throws Exception {
056            afterPropertiesSet();
057            return buildProducer();
058        }
059    
060        @Override
061        public RemoteFileConsumer<T> createConsumer(Processor processor) throws Exception {
062            afterPropertiesSet();
063            RemoteFileConsumer<T> consumer = buildConsumer(processor);
064    
065            // we assume its a file if the name has a dot in it (eg foo.txt)
066            if (configuration.getDirectory().contains(".")) {
067                throw new IllegalArgumentException("Only directory is supported. Endpoint must be configured with a valid directory: "
068                        + configuration.getDirectory());
069            }
070    
071            if (isDelete() && getMove() != null) {
072                throw new IllegalArgumentException("You cannot both set delete=true and move options");
073            }
074            // if noop=true then idempotent should also be configured
075            if (isNoop() && !isIdempotent()) {
076                log.info("Endpoint is configured with noop=true so forcing endpoint to be idempotent as well");
077                setIdempotent(true);
078            }
079    
080            // if idempotent and no repository set then create a default one
081            if (isIdempotent() && idempotentRepository == null) {
082                log.info("Using default memory based idempotent repository with cache max size: " + DEFAULT_IDEMPOTENT_CACHE_SIZE);
083                idempotentRepository = MemoryIdempotentRepository.memoryIdempotentRepository(DEFAULT_IDEMPOTENT_CACHE_SIZE);
084            }
085    
086            // set max messages per poll
087            consumer.setMaxMessagesPerPoll(getMaxMessagesPerPoll());
088    
089            configureConsumer(consumer);
090            return consumer;
091        }
092    
093        /**
094         * Validates this endpoint if its configured properly.
095         *
096         * @throws Exception is thrown if endpoint is invalid configured for its mandatory options
097         */
098        protected void afterPropertiesSet() throws Exception {
099            RemoteFileConfiguration config = (RemoteFileConfiguration) getConfiguration();
100            ObjectHelper.notEmpty(config.getHost(), "host");
101            ObjectHelper.notEmpty(config.getProtocol(), "protocol");
102            if (config.getPort() <= 0) {
103                throw new IllegalArgumentException("port is not assigned to a positive value");
104            }
105        }
106    
107        /**
108         * Remote File Endpoints, impl this method to create a custom consumer specific to their "protocol" etc.
109         *
110         * @param processor  the processor
111         * @return the created consumer
112         */
113        protected abstract RemoteFileConsumer<T> buildConsumer(Processor processor);
114    
115        /**
116         * Remote File Endpoints, impl this method to create a custom producer specific to their "protocol" etc.
117         *
118         * @return the created producer
119         */
120        protected abstract GenericFileProducer<T> buildProducer();
121    
122        /**
123         * Returns human readable server information for logging purpose
124         */
125        public String remoteServerInformation() {
126            return ((RemoteFileConfiguration) configuration).remoteServerInformation();
127        }
128        
129        @Override
130        public char getFileSeparator() {       
131            return '/';
132        }
133        
134        @Override
135        public boolean isAbsolute(String name) {        
136            return name.startsWith("/");
137        }
138    
139    }