001 // Copyright 2009, 2010, 2011 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 java.util.concurrent.Callable; 018 import java.util.concurrent.ExecutorService; 019 import java.util.concurrent.Future; 020 021 import org.apache.tapestry5.ioc.Invokable; 022 import org.apache.tapestry5.ioc.ObjectCreator; 023 import org.apache.tapestry5.ioc.services.ParallelExecutor; 024 import org.apache.tapestry5.ioc.services.PerthreadManager; 025 import org.apache.tapestry5.ioc.services.ThunkCreator; 026 027 public class ParallelExecutorImpl implements ParallelExecutor 028 { 029 private final ThunkCreator thunkCreator; 030 031 private final ExecutorService executorService; 032 033 private final PerthreadManager perthreadManager; 034 035 public ParallelExecutorImpl(ExecutorService executorService, ThunkCreator thunkCreator, 036 PerthreadManager perthreadManager) 037 { 038 this.executorService = executorService; 039 this.thunkCreator = thunkCreator; 040 this.perthreadManager = perthreadManager; 041 } 042 043 public <T> Future<T> invoke(Invokable<T> invocable) 044 { 045 assert invocable != null; 046 047 return executorService.submit(toCallable(invocable)); 048 } 049 050 private <T> Callable<T> toCallable(final Invokable<T> invocable) 051 { 052 return new Callable<T>() 053 { 054 public T call() throws Exception 055 { 056 try 057 { 058 return invocable.invoke(); 059 } 060 finally 061 { 062 perthreadManager.cleanup(); 063 } 064 } 065 }; 066 } 067 068 public <T> T invoke(Class<T> proxyType, Invokable<T> invocable) 069 { 070 final Future<T> future = invoke(invocable); 071 072 ObjectCreator<T> creator = new ObjectCreator<T>() 073 { 074 public T createObject() 075 { 076 try 077 { 078 return future.get(); 079 } 080 catch (Exception ex) 081 { 082 throw new RuntimeException(ex); 083 } 084 } 085 }; 086 087 String description = String.format("FutureThunk[%s]", proxyType.getName()); 088 089 return thunkCreator.createThunk(proxyType, new CachingObjectCreator(creator), description); 090 } 091 }