001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.hivemind.impl;
016
017import java.net.URL;
018
019import org.apache.hivemind.ApplicationRuntimeException;
020import org.apache.hivemind.ClassResolver;
021
022/**
023 * Default implementation of {@link org.apache.hivemind.ClassResolver} based around
024 * {@link Thread#getContextClassLoader()} (which is set by the servlet container).
025 * 
026 * @author Howard Lewis Ship
027 */
028public class DefaultClassResolver implements ClassResolver
029{
030    private ClassLoader _loader;
031
032    /**
033     * Constructs a new instance using {@link Thread#getContextClassLoader()}.
034     */
035
036    public DefaultClassResolver()
037    {
038        this(Thread.currentThread().getContextClassLoader());
039    }
040
041    public DefaultClassResolver(ClassLoader loader)
042    {
043        _loader = loader;
044    }
045
046    public URL getResource(String name)
047    {
048        String stripped = removeLeadingSlash(name);
049
050        URL result = _loader.getResource(stripped);
051
052        return result;
053    }
054
055    private String removeLeadingSlash(String name)
056    {
057        if (name.startsWith("/"))
058            return name.substring(1);
059
060        return name;
061    }
062
063    /**
064     * Invokes {@link Class#forName(java.lang.String, boolean, java.lang.ClassLoader)}.
065     * 
066     * @param type
067     *            the complete class name to locate and load; alternately, may be a primitive name
068     *            or an array type (primitive or object)
069     * @return The loaded class
070     * @throws ApplicationRuntimeException
071     *             if loading the class throws an exception (typically
072     *             {@link ClassNotFoundException} or a security exception)
073     * @see JavaTypeUtils
074     */
075
076    public Class findClass(String type)
077    {
078        try
079        {
080            return lookupClass(type);
081        }
082        catch (Throwable t)
083        {
084            throw new ApplicationRuntimeException(ImplMessages.unableToLoadClass(type, _loader, t),
085                    t);
086        }
087    }
088
089    private Class lookupClass(String type) throws ClassNotFoundException
090    {
091        Class result = JavaTypeUtils.getPrimtiveClass(type);
092
093        if (result != null)
094            return result;
095
096        // This does some magic to handle arrays of primitives or objects in the
097        // format needed by Class.forName().
098
099        String jvmName = JavaTypeUtils.getJVMClassName(type);
100
101        return Class.forName(jvmName, true, _loader);
102    }
103
104    public Class checkForClass(String type)
105    {
106        try
107        {
108            return lookupClass(type);
109        }
110        catch (ClassNotFoundException ex)
111        {
112            return null;
113        }
114        catch (Throwable t)
115        {
116            throw new ApplicationRuntimeException(ImplMessages.unableToLoadClass(type, _loader, t),
117                    t);
118        }
119
120    }
121
122    public ClassLoader getClassLoader()
123    {
124        return _loader;
125    }
126
127}