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;
018    
019    import java.lang.reflect.Method;
020    
021    import org.apache.camel.CamelContext;
022    import org.apache.camel.CamelContextAware;
023    import org.apache.camel.util.ObjectHelper;
024    import static org.apache.camel.util.CollectionHelper.collectionAsCommaDelimitedString;
025    
026    /**
027     * File filter using Spring's AntPathMatcher.
028     * <p/>
029     * Exclude take precedence over includes. If a file match both exclude and include it will be regarded as excluded.
030     * @param <T>
031     */
032    public class AntPathMatcherGenericFileFilter<T> implements GenericFileFilter<T>, CamelContextAware {
033        private static final String ANTPATHMATCHER_CLASSNAME = "org.apache.camel.spring.util.SpringAntPathMatcherFileFilter";
034    
035        private CamelContext context;
036    
037        private String[] excludes;
038        private String[] includes;
039    
040        private Object filter;
041        private Method includesMethod;
042        private Method excludesMethod;
043        private Method acceptsMethod;
044    
045        public boolean accept(GenericFile<T> file) {
046            try {
047                synchronized (this) {
048                    if (filter == null) {
049                        init();
050                    }
051                }
052    
053                // invoke setIncludes(String), must using string type as invoking with string[] does not work
054                ObjectHelper.invokeMethod(includesMethod, filter, collectionAsCommaDelimitedString(includes));
055    
056                // invoke setExcludes(String), must using string type as invoking with string[] does not work
057                ObjectHelper.invokeMethod(excludesMethod, filter, collectionAsCommaDelimitedString(excludes));
058    
059                // invoke acceptPathName(String)
060                String path = file.getRelativeFilePath();
061                return (Boolean) ObjectHelper.invokeMethod(acceptsMethod, filter, path);
062    
063            } catch (NoSuchMethodException e) {
064                throw new TypeNotPresentException(ANTPATHMATCHER_CLASSNAME, e);
065            }
066        }
067    
068        @SuppressWarnings("unchecked")
069        private void init() throws NoSuchMethodException {
070            // we must use reflection to invoke the AntPathMatcherFileFilter that reside in camel-spring.jar
071            // and we don't want camel-core to have runtime dependency on camel-spring.jar
072            // use class resolver from CamelContext to ensure it works with OSGi as well
073            Class clazz = context.getClassResolver().resolveClass(ANTPATHMATCHER_CLASSNAME);
074            ObjectHelper.notNull(clazz, ANTPATHMATCHER_CLASSNAME + " not found in classpath. camel-spring.jar is required in the classpath.");
075    
076            filter = ObjectHelper.newInstance(clazz);
077    
078            includesMethod = filter.getClass().getMethod("setIncludes", String.class);
079            excludesMethod = filter.getClass().getMethod("setExcludes", String.class);
080            acceptsMethod = filter.getClass().getMethod("acceptPathName", String.class);
081        }
082    
083        public String[] getExcludes() {
084            return excludes;
085        }
086    
087        public void setExcludes(String[] excludes) {
088            this.excludes = excludes;
089        }
090    
091        public String[] getIncludes() {
092            return includes;
093        }
094    
095        public void setIncludes(String[] includes) {
096            this.includes = includes;
097        }
098    
099        /**
100         * Sets excludes using a single string where each element can be separated with comma
101         */
102        public void setExcludes(String excludes) {
103            setExcludes(excludes.split(","));
104        }
105    
106        /**
107         * Sets includes using a single string where each element can be separated with comma
108         */
109        public void setIncludes(String includes) {
110            setIncludes(includes.split(","));
111        }
112    
113        public void setCamelContext(CamelContext camelContext) {
114            this.context = camelContext;
115        }
116    
117        public CamelContext getCamelContext() {
118            return context;
119        }
120    }