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.javassist;
018
019 import java.lang.reflect.Field;
020
021 import net.ep.db4o.factories.InvalidFactoryException;
022 import net.ep.db4o.factories.ObjectContainerProvider;
023
024 import com.db4o.ObjectContainer;
025 import com.db4o.reflect.generic.GenericReflector;
026 import com.db4o.reflect.jdk.JavaReflectClass;
027
028 public class Enhancer {
029
030 @SuppressWarnings("unchecked")
031 public static <T> Class<T> enhancedClass(Class<T> targetType,
032 ObjectContainerProvider _provider) {
033 ObjectContainer db = _provider.db();
034 if (db == null)
035 throw new NullPointerException(ObjectContainerProvider.class.getName() + " returned a null result");
036 GenericReflector refl = db.ext().reflector();
037 if (refl.getDelegate() instanceof JVSTReflector) {
038 JVSTReflector reflector = (JVSTReflector) _provider.db().ext().reflector()
039 .getDelegate();
040 // Class enhancedClass =
041 if (JVSTReflector.canBeEnhanced(targetType)) {
042 JVSTClass enhClazz1 = reflector.enhanceClass(targetType);
043 return enhClazz1.getEnhancedClass();
044 } else
045 throw new InvalidFactoryException(targetType + " cannot be enhanced: "
046 + JVSTReflector.explainWhyNotEnhanced(targetType));
047 }
048 return targetType;
049 }
050
051 @SuppressWarnings("unchecked")
052 public static <T> T newInstance(Class<T> clazz, ObjectContainer container) {
053 GenericReflector refl = container.ext().reflector();
054 if (refl.getDelegate() instanceof JVSTReflector) {
055 JVSTReflector reflector = (JVSTReflector) container.ext().reflector()
056 .getDelegate();
057 // Class enhancedClass =
058 JavaReflectClass enhClazz1 = (JavaReflectClass) reflector.forClass(clazz);
059 T copy = (T) enhClazz1.newInstance();
060 container.store(copy);
061 return copy;
062 }
063 try {
064 return clazz.newInstance();
065 } catch (Exception e) {
066 e.printStackTrace();
067 return null;
068 }
069 }
070
071 @SuppressWarnings("unchecked")
072 public static <T> T enhance(T input, ObjectContainer container) {
073 Class clazz = input.getClass();
074 T output = (T) newInstance(clazz, container);
075 if (output == null)
076 return null;
077 try {
078 cloneFrom(clazz, input, output);
079 } catch (Exception e) {
080 e.printStackTrace();
081 return null;
082 }
083 return output;
084 }
085
086 public static <T> void cloneFrom(T input, T output)
087 throws IllegalArgumentException, IllegalAccessException {
088 cloneFrom(input.getClass(), input, output);
089 }
090
091 @SuppressWarnings("unchecked")
092 private static <T> void cloneFrom(Class cl, T input, T output)
093 throws IllegalArgumentException, IllegalAccessException {
094 for (Field field : cl.getDeclaredFields()) {
095 boolean acc = field.isAccessible();
096 field.setAccessible(true);
097 field.set(output, field.get(input));
098 field.setAccessible(acc);
099 }
100 if (cl.getSuperclass() != null)
101 cloneFrom(cl.getSuperclass(), input, output);
102 }
103
104 }