001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020package org.apache.felix.ipojo;
021
022import java.net.URL;
023import java.security.ProtectionDomain;
024import java.util.HashMap;
025import java.util.Map;
026
027/**
028 * This class defines the classloader attached to a factory.
029 * This class loader is used to load the implementation (e.g. manipulated)
030 * class.
031 *
032 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
033 * @see ClassLoader
034 */
035class FactoryClassloader extends ClassLoader {
036
037    /**
038     * The map of defined classes [Name, Class Object].
039     */
040    private final Map<String, Class<?>> m_definedClasses = new HashMap<String, Class<?>>();
041    private ComponentFactory factory;
042
043    public FactoryClassloader(ComponentFactory factory) {
044        this.factory = factory;
045    }
046
047    /**
048     * The defineClass method.
049     *
050     * @param name   name of the class
051     * @param clazz  the byte array of the class
052     * @param domain the protection domain
053     * @return the defined class.
054     */
055    public Class<?> defineClass(String name, byte[] clazz, ProtectionDomain domain) {
056        if (m_definedClasses.containsKey(name)) {
057            return m_definedClasses.get(name);
058        }
059        Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
060        m_definedClasses.put(name, clas);
061        return clas;
062    }
063
064    /**
065     * Returns the URL of the required resource.
066     *
067     * @param arg the name of the resource to find.
068     * @return the URL of the resource.
069     * @see ClassLoader#getResource(String)
070     */
071    public URL getResource(String arg) {
072        return factory.m_context.getBundle().getResource(arg);
073    }
074
075    /**
076     * Loads the given class.
077     *
078     * @param name    the name of the class
079     * @param resolve should be the class resolve now ?
080     * @return the loaded class object
081     * @throws ClassNotFoundException if the class to load is not found
082     * @see ClassLoader#loadClass(String, boolean)
083     * @see ClassLoader#loadClass(String, boolean)
084     */
085    protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
086        return factory.m_context.getBundle().loadClass(name);
087    }
088}