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.geronimo.kernel;
018    
019    import java.io.BufferedReader;
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.io.InputStreamReader;
023    
024    import org.apache.geronimo.kernel.basic.BasicKernelFactory;
025    
026    /**
027     * @version $Rev: 549825 $ $Date: 2007-06-22 10:17:31 -0400 (Fri, 22 Jun 2007) $
028     */
029    public abstract class KernelFactory {
030        public static final String KERNEL_FACTORY_KEY = KernelFactory.class.getName();
031    
032        public static KernelFactory newInstance() {
033            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
034            if (classLoader == null) {
035                classLoader = KernelFactory.class.getClassLoader();
036            }
037    
038            // System property
039            try {
040                String kernelFactoryName = System.getProperty(KERNEL_FACTORY_KEY);
041                if (kernelFactoryName != null) {
042                    return createKernelFactory(kernelFactoryName, classLoader);
043                }
044            } catch (SecurityException se) {
045            }
046    
047            // Jar Service Specification - http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html
048            String serviceId = "META-INF/services/" + KERNEL_FACTORY_KEY;
049            InputStream inputStream = null;
050            try {
051                inputStream = classLoader.getResourceAsStream(serviceId);
052                if (inputStream != null) {
053                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
054                    String kernelFactoryName = reader.readLine();
055                    reader.close();
056    
057                    if (kernelFactoryName != null && kernelFactoryName.length() > 0) {
058                        return createKernelFactory(kernelFactoryName, classLoader);
059                    }
060                }
061            } catch (Exception ignored) {
062            } finally {
063                if (inputStream != null) {
064                    try {
065                        inputStream.close();
066                    } catch (IOException ignored) {
067                    }
068                    inputStream = null;
069                }
070            }
071    
072            // Default is the basic kernel
073            return new BasicKernelFactory();
074        }
075    
076        private static KernelFactory createKernelFactory(String className, ClassLoader classLoader) {
077            try {
078                return (KernelFactory) classLoader.loadClass(className).newInstance();
079            } catch (ClassCastException e) {
080                throw new KernelFactoryError("Kernel factory class does not implement KernelFactory: " + className, e);
081            } catch (ClassNotFoundException e) {
082                throw new KernelFactoryError("Kernel factory class not found: " + className, e);
083            } catch (Exception e) {
084                throw new KernelFactoryError("Unable to instantiate kernel factory class: " + className, e);
085            }
086        }
087    
088        public abstract Kernel createKernel(String kernelName);
089    }