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.commons.discovery.tools;
018    
019    import org.apache.commons.discovery.ResourceClass;
020    import org.apache.commons.discovery.ResourceClassIterator;
021    import org.apache.commons.discovery.resource.classes.DiscoverClasses;
022    import org.apache.commons.discovery.resource.ClassLoaders;
023    
024    
025    /**
026     * Holder for a default class.
027     * 
028     * Class may be specified by name (String) or class (Class).
029     * Using the holder complicates the users job, but minimized # of API's.
030     * 
031     * @author Richard A. Sitze
032     */
033    public class DefaultClassHolder {
034        private Class        defaultClass;
035        private final String defaultName;
036        
037        public DefaultClassHolder(Class defaultClass) {
038            this.defaultClass = defaultClass;
039            this.defaultName = defaultClass.getName();
040        }
041        
042        public DefaultClassHolder(String defaultName) {
043            this.defaultClass = null;
044            this.defaultName = defaultName;
045        }
046    
047        /**
048         * @param spi non-null SPI
049         * @param loaders Used only if class needs to be loaded.
050         * 
051         * @return Default Class.  Load the class if necessary,
052         *         and verify that it implements the SPI.
053         *         (this forces the check, no way out..).
054         */
055        public Class getDefaultClass(SPInterface spi, ClassLoaders loaders) {
056            if (defaultClass == null) {
057                DiscoverClasses classDiscovery = new DiscoverClasses(loaders);
058                ResourceClassIterator classes = classDiscovery.findResourceClasses(getDefaultName());
059                if (classes.hasNext()) {
060                    ResourceClass info = classes.nextResourceClass();
061                    try {
062                        defaultClass = info.loadClass();
063                    } catch (Exception e) {
064                        // ignore
065                    }
066                }
067            }
068            
069            if (defaultClass != null) {
070                spi.verifyAncestory(defaultClass);
071            }
072    
073            return defaultClass;
074        }
075    
076        public String getDefaultName() {
077            return defaultName;
078        }
079    }