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    
015    package org.apache.tapestry5.ioc.internal.services;
016    
017    import javassist.CtClass;
018    import org.apache.tapestry5.ioc.internal.util.OneShotLock;
019    import 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     */
025    public 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    }