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 }