    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    }