001    /*
002     * Licensed under the Apache License, Version 2.0 (the "License");
003     * you may not use this file except in compliance with the License.
004     * You may obtain a copy of the License at
005     *
006     *      http://www.apache.org/licenses/LICENSE-2.0
007     *
008     * Unless required by applicable law or agreed to in writing, software
009     * distributed under the License is distributed on an "AS IS" BASIS,
010     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011     * See the License for the specific language governing permissions and
012     * limitations under the License.
013     */
014    package org.apache.commons.classscan.util;
015    
016    import java.util.ArrayList;
017    import java.util.Collection;
018    import java.util.Collections;
019    import java.util.Iterator;
020    
021    /**
022     * A cache of service providers.
023     *
024     * @param <T> The interface of the service provider
025     */
026    public class FactoryCache<T> implements Iterable<T>  {
027    
028            final private Collection<T> readOnly;
029            
030            /**
031             * Find service providers available to the given classLoader
032             * 
033             * @param serviceProvider The interface of the service provider
034             * @param classLoader The ClassLoader to load the service provider instances
035             */
036            public FactoryCache(Class<T> serviceProvider, ClassLoader classLoader) {
037    
038                    final ArrayList<T> instances = new ArrayList<T>();
039                    
040                    new ServiceVisitor<T>() {
041                            @Override
042                            protected boolean visit(T factory) {
043                            instances.add(factory);
044                            return true;
045                            }
046                    }.visitProviders(serviceProvider, classLoader);
047    
048                    instances.trimToSize();
049            readOnly = Collections.unmodifiableCollection(instances);
050            }
051    
052            @Override
053            public Iterator<T> iterator() {
054                    return readOnly.iterator();
055            }
056    }