//  Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.tapestry.enhance.javassist;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.LoaderClassPath;
import javassist.NotFoundException;
import org.apache.tapestry.IResourceResolver;
import org.apache.tapestry.enhance.CodeGenerationException;
import org.apache.tapestry.enhance.EnhancedClassLoader;
import org.apache.tapestry.enhance.IEnhancedClass;
import org.apache.tapestry.enhance.IEnhancedClassFactory;

/**
 *  This class defines the factory for creation of new Javassist enhanced classes. 
 *  There is typically only one object of this class in the system. 
 *  Common functionality objects for Javassist enhancement are stored here.
 *
 *  @author Mindbridge
 *  @version $Id$
 *  @since 3.0
 */
public class EnhancedClassFactory implements IEnhancedClassFactory
{
    private IResourceResolver _resourceResolver;
    private EnhancedClassLoader _enhancedClassLoader;
    private ClassPool _classPool;

    private ClassMapping _typeMap = null;

    public EnhancedClassFactory(IResourceResolver resourceResolver)
    {
        _resourceResolver = resourceResolver;

        reset();
    }

    protected ClassPool createClassPool()
    {
        ClassLoader loader = _resourceResolver.getClassLoader();

        // create a new ClassPool and make sure it uses the application resource resolver 
        ClassPool classPool = new ClassPool(null);
        classPool.insertClassPath(new LoaderClassPath(loader));

        return classPool;
    }

    /**
     * @see org.apache.tapestry.enhance.IEnhancedClassFactory#reset()
     */
    public synchronized void reset()
    {
        // create a new class pool and discard the previous one
        _classPool = createClassPool();
        _typeMap = new ClassMapping(_classPool);

        ClassLoader loader = _resourceResolver.getClassLoader();
        _enhancedClassLoader = new EnhancedClassLoader(loader);
    }


    /**
     * @see org.apache.tapestry.enhance.IEnhancedClassFactory#createEnhancedClass(java.lang.String, java.lang.Class)
     */
    public IEnhancedClass createEnhancedClass(String className, Class parentClass)
    {
        return new EnhancedClass(className, parentClass, this);
    }

    public ClassPool getClassPool()
    {
        return _classPool;
    }

    public ClassMapping getClassMapping()
    {
        return _typeMap;
    }

    /**
     *  Given the java class, returns the equivalent {@link CtClass type}.  In addition,
     *  knows about scalar types, arrays of scalar types, java.lang.Object[] and
     *  java.lang.String[].
     *
     **/

    public CtClass getObjectType(String type)
    {

        synchronized (this) {
            CtClass result = getClassMapping().getType(type);

            if (result == null)
            {
                try
                {
                    result = _classPool.get(type);
                    getClassMapping().recordType(type, result);
                }
                catch (NotFoundException e)
                {
                    throw new CodeGenerationException(e);
                }
            }
            return result;
        }

    }


    /**
     * @return The class loader to be used to create the enhanced class
     */
    public EnhancedClassLoader getEnhancedClassLoader()
    {
        return _enhancedClassLoader;
    }

}
