001// Copyright 2005, 2006, 2007, 2008 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.tapestry5.ioc.internal.services;
016
017import javassist.CtClass;
018import org.apache.tapestry5.ioc.internal.util.OneShotLock;
019import org.slf4j.Logger;
020
021/**
022 * Base class for {@link org.apache.tapestry5.ioc.internal.services.ClassFabImpl}. This code is a fork from HiveMind; it
023 * is kept seperate from ClassFabImpl in case we want to re-introduce the idea of an InterfaceFab.
024 */
025public class AbstractFab
026{
027    protected final OneShotLock lock = new OneShotLock();
028
029    private final CtClass ctClass;
030
031    private final CtClassSource source;
032
033    private final Logger logger;
034
035    public AbstractFab(CtClassSource source, CtClass ctClass, Logger logger)
036    {
037        this.ctClass = ctClass;
038        this.source = source;
039        this.logger = logger;
040    }
041
042    public void addInterface(Class interfaceClass)
043    {
044        lock.check();
045
046        CtClass ctInterfaceClass = source.toCtClass(interfaceClass);
047
048        try
049        {
050            for (CtClass existing : ctClass.getInterfaces())
051                if (existing == ctInterfaceClass) return;
052        }
053        catch (Exception ex)
054        {
055            // Don't think this code is actually reachable.
056        }
057
058        ctClass.addInterface(ctInterfaceClass);
059    }
060
061    protected CtClass[] toCtClasses(Class[] inputClasses)
062    {
063        if (inputClasses == null || inputClasses.length == 0) return null;
064
065        int count = inputClasses.length;
066        CtClass[] result = new CtClass[count];
067
068        for (int i = 0; i < count; i++)
069        {
070            CtClass ctClass = toCtClass(inputClasses[i]);
071
072            result[i] = ctClass;
073        }
074
075        return result;
076    }
077
078    protected CtClass toCtClass(Class inputClass)
079    {
080        return source.toCtClass(inputClass);
081    }
082
083    public Class createClass()
084    {
085        lock.lock();
086
087        if (logger.isDebugEnabled()) logger.debug(String.format("Creating class from %s", this));
088
089        return source.createClass(ctClass);
090    }
091
092    protected CtClass getCtClass()
093    {
094        return ctClass;
095    }
096
097    protected CtClassSource getSource()
098    {
099        return source;
100    }
101    
102    protected Logger getLogger()
103    {
104        return logger;
105    }
106
107}