View Javadoc

1   /**
2    * Copyright (C) 2009 Erik Putrycz <erik.putrycz@gmail.com>
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.ep.db4o.factories;
18  
19  import java.lang.reflect.InvocationHandler;
20  import java.lang.reflect.Method;
21  import java.lang.reflect.Proxy;
22  
23  public class BasicFactories implements Factories {
24  	
25  	/* (non-Javadoc)
26  	 * @see net.ep.db4o.factories.Factories#createFactory(java.lang.Class)
27  	 */
28  	@SuppressWarnings("unchecked")
29  	public <T> T createFactory(Class<T> factory) {
30  		Method[] faMethods =factory.getDeclaredMethods();
31  		if (faMethods.length == 0)
32  			throw new InvalidFactoryException("No method found in factory");
33  		Method main = faMethods[0];
34  		Class<?> targetType = main.getReturnType();
35  		if (faMethods.length > targetType.getDeclaredConstructors().length)
36  			throw new InvalidFactoryException(faMethods.length + " found in factory but " + targetType.getDeclaredConstructors().length + " should be declared");
37  		if (targetType == null)
38  			throw new InvalidFactoryException("The return type of '" + main.getName() + "' cannot be void");
39  		Class<?> realType = getRealClass(targetType);
40  		InvocationHandler invHandler = new FactoryInvocationHandler(factory,targetType,realType, this);
41  		return (T) Proxy.newProxyInstance(factory.getClassLoader(), new Class[]{factory},invHandler);
42  	}
43  
44  	protected Class<?> getRealClass(Class<?> targetType) {
45  		return targetType;
46  	}
47  
48  	public void onNewInstance(Object inst) {
49  		// do nothing
50  		
51  	}
52  
53  	@SuppressWarnings("unchecked")
54  	public <T> T createInstance(Class<T> clazz) {
55  		T instance;
56  		try {
57  			instance = (T) getRealClass(clazz).newInstance();
58  		} catch (InstantiationException e) {
59  			throw new InvalidFactoryException("No empty constructor found in " + clazz.getName(),e);						
60  		} catch (IllegalAccessException e) {
61  			throw new InvalidFactoryException(e);						
62  		}
63  		onNewInstance(instance);
64  		return instance;
65  	}
66  
67  }