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 }