    001    // Copyright 2010, 2011, 2012 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;
    016
    017    import org.apache.tapestry5.ioc.ObjectCreator;
    018    import org.apache.tapestry5.ioc.ServiceBuilderResources;
    019    import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
    020    import org.apache.tapestry5.services.UpdateListenerHub;
    021
    022    import java.lang.reflect.Method;
    023
    024    /**
    025     * Responsible for creating a {@link ReloadableServiceImplementationObjectCreator} for a service implementation.
    026     */
    027    @SuppressWarnings("unchecked")
    028    public class ReloadableObjectCreatorSource implements ObjectCreatorSource
    029    {
    030        private final PlasticProxyFactory proxyFactory;
    031
    032        private final Method bindMethod;
    033
    034        private final Class serviceInterfaceClass;
    035
    036        private final Class serviceImplementationClass;
    037
    038        private final boolean eagerLoad;
    039
    040        public ReloadableObjectCreatorSource(PlasticProxyFactory proxyFactory, Method bindMethod,
    041                                             Class serviceInterfaceClass, Class serviceImplementationClass, boolean eagerLoad)
    042        {
    043            this.proxyFactory = proxyFactory;
    044            this.bindMethod = bindMethod;
    045            this.serviceInterfaceClass = serviceInterfaceClass;
    046            this.serviceImplementationClass = serviceImplementationClass;
    047            this.eagerLoad = eagerLoad;
    048        }
    049
    050
    051        public ObjectCreator constructCreator(final ServiceBuilderResources resources)
    052        {
    053            return new ObjectCreator()
    054            {
    055                public Object createObject()
    056                {
    057                    return createReloadableProxy(resources);
    058                }
    059
    060                @Override
    061                public String toString()
    062                {
    063                    return proxyFactory.getMethodLocation(bindMethod).toString();
    064                }
    065            };
    066        }
    067
    068        public String getDescription()
    069        {
    070            return String.format("Reloadable %s via %s", serviceImplementationClass.getName(),
    071                    proxyFactory.getMethodLocation(bindMethod));
    072        }
    073
    074        private Object createReloadableProxy(ServiceBuilderResources resources)
    075        {
    076            ReloadableServiceImplementationObjectCreator reloadableCreator = new ReloadableServiceImplementationObjectCreator(proxyFactory,
    077                    resources, proxyFactory.getClassLoader(), serviceImplementationClass.getName());
    078
    079            resources.getService(UpdateListenerHub.class).addUpdateListener(reloadableCreator);
    080
    081            if (eagerLoad)
    082            {
    083                reloadableCreator.createObject();
    084            }
    085
    086            return proxyFactory.createProxy(serviceInterfaceClass, reloadableCreator, getDescription());
    087        }
    088    }