001 /** 002 * Copyright (C) 2009 Erik Putrycz <erik.putrycz@gmail.com> 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package net.ep.db4o.factories; 018 019 import java.lang.reflect.InvocationHandler; 020 import java.lang.reflect.Method; 021 import java.lang.reflect.Proxy; 022 023 public class BasicFactories implements Factories { 024 025 /* (non-Javadoc) 026 * @see net.ep.db4o.factories.Factories#createFactory(java.lang.Class) 027 */ 028 @SuppressWarnings("unchecked") 029 public <T> T createFactory(Class<T> factory) { 030 Method[] faMethods =factory.getDeclaredMethods(); 031 if (faMethods.length == 0) 032 throw new InvalidFactoryException("No method found in factory"); 033 Method main = faMethods[0]; 034 Class<?> targetType = main.getReturnType(); 035 if (faMethods.length > targetType.getDeclaredConstructors().length) 036 throw new InvalidFactoryException(faMethods.length + " found in factory but " + targetType.getDeclaredConstructors().length + " should be declared"); 037 if (targetType == null) 038 throw new InvalidFactoryException("The return type of '" + main.getName() + "' cannot be void"); 039 Class<?> realType = getRealClass(targetType); 040 InvocationHandler invHandler = new FactoryInvocationHandler(factory,targetType,realType, this); 041 return (T) Proxy.newProxyInstance(factory.getClassLoader(), new Class[]{factory},invHandler); 042 } 043 044 protected Class<?> getRealClass(Class<?> targetType) { 045 return targetType; 046 } 047 048 public void onNewInstance(Object inst) { 049 // do nothing 050 051 } 052 053 @SuppressWarnings("unchecked") 054 public <T> T createInstance(Class<T> clazz) { 055 T instance; 056 try { 057 instance = (T) getRealClass(clazz).newInstance(); 058 } catch (InstantiationException e) { 059 throw new InvalidFactoryException("No empty constructor found in " + clazz.getName(),e); 060 } catch (IllegalAccessException e) { 061 throw new InvalidFactoryException(e); 062 } 063 onNewInstance(instance); 064 return instance; 065 } 066 067 }