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 015package org.apache.tapestry5.ioc.internal; 016 017import org.apache.tapestry5.ioc.ObjectCreator; 018import org.apache.tapestry5.ioc.ServiceBuilderResources; 019import org.apache.tapestry5.ioc.services.PlasticProxyFactory; 020import org.apache.tapestry5.services.UpdateListenerHub; 021 022import java.lang.reflect.Method; 023 024/** 025 * Responsible for creating a {@link ReloadableServiceImplementationObjectCreator} for a service implementation. 026 */ 027@SuppressWarnings("unchecked") 028public 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 @Override 052 public ObjectCreator constructCreator(final ServiceBuilderResources resources) 053 { 054 return new ObjectCreator() 055 { 056 @Override 057 public Object createObject() 058 { 059 return createReloadableProxy(resources); 060 } 061 062 @Override 063 public String toString() 064 { 065 return proxyFactory.getMethodLocation(bindMethod).toString(); 066 } 067 }; 068 } 069 070 @Override 071 public String getDescription() 072 { 073 return String.format("Reloadable %s via %s", serviceImplementationClass.getName(), 074 proxyFactory.getMethodLocation(bindMethod)); 075 } 076 077 private Object createReloadableProxy(ServiceBuilderResources resources) 078 { 079 ReloadableServiceImplementationObjectCreator reloadableCreator = new ReloadableServiceImplementationObjectCreator(proxyFactory, 080 resources, proxyFactory.getClassLoader(), serviceImplementationClass.getName()); 081 082 resources.getService(UpdateListenerHub.class).addUpdateListener(reloadableCreator); 083 084 if (eagerLoad) 085 { 086 reloadableCreator.createObject(); 087 } 088 089 return proxyFactory.createProxy(serviceInterfaceClass, resources.getServiceImplementation(), reloadableCreator, getDescription()); 090 } 091}