View Javadoc

1   /*
2    * Copyright 2004 Charles Blaxland
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  package mnemosyne.core;
17  
18  import mnemosyne.aop.AopSystem;
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  import java.lang.reflect.Field;
23  import java.util.HashSet;
24  import java.util.Set;
25  
26  /***
27   * @version $Id: EnhancerImpl.java,v 1.2 2004/08/12 14:01:05 charlesblaxland Exp $
28   */
29  public class EnhancerImpl implements Enhancer
30  {
31      private static final Log log = LogFactory.getLog(EnhancerImpl.class);
32  
33      private AopSystem aopSystem;
34      private PersistentObjectFactory persistentObjectFactory;
35  
36      public EnhancerImpl(PersistentObjectFactory persistentObjectFactory, AopSystem aopSystem)
37      {
38          this.aopSystem = aopSystem;
39          this.persistentObjectFactory = persistentObjectFactory;
40      }
41  
42      public Set enhance(Object obj)
43      {
44          log.debug("Enhancing object of type " + obj.getClass().getName());
45          Set addedObjects = new HashSet();
46          Persistable persistable = (Persistable) obj;
47          if (!persistable.isPersistent())
48          {
49              makePersistent(persistable);
50              addedObjects.add(persistable.getPersistentObject());
51          }
52  
53          enhance(obj, addedObjects);
54          return addedObjects;
55      }
56  
57      private void enhance(Object obj, Set addedObjects)
58      {
59          enhance(obj, obj.getClass(), addedObjects);
60      }
61  
62      private void enhance(Object obj, Class clazz, Set addedObjects)
63      {
64          Field[] fields = clazz.getDeclaredFields();
65          enhance(fields, obj, addedObjects);
66  
67          Class superClass = clazz.getSuperclass();
68          if (superClass != null && superClass != Object.class && superClass != NonAopPersistable.class)
69          {
70              enhance(obj, superClass, addedObjects);
71          }
72  
73          Class[] interfaces = clazz.getInterfaces();
74          for (int i = 0; i < interfaces.length; i++)
75          {
76              enhance(obj, interfaces[i], addedObjects);
77          }
78      }
79  
80      private void enhance(Field[] fields, Object obj, Set addedObjects)
81      {
82          for (int i = 0; i < fields.length; i++)
83          {
84              Field field = fields[i];
85              if (!field.getType().isPrimitive() && !aopSystem.isAopIntroducedField(field))
86              {
87                  enhance(field, obj, addedObjects);
88              }
89          }
90      }
91  
92      private void enhance(Field field, Object targetObject, Set addedObjects)
93      {
94          try
95          {
96              field.setAccessible(true);
97              Object obj = field.get(targetObject);
98              if (obj != null)
99              {
100                 if (!(obj instanceof Persistable))
101                 {
102                     throw new NotPersistableException("Object of type " + obj.getClass().getName() + " is not persistable");
103                 }
104 
105                 Persistable persistable = (Persistable) obj;
106                 PersistentObject persistentObject = persistable.getPersistentObject();
107                 if (persistentObject == null)
108                 {
109                     if (log.isTraceEnabled())
110                     {
111                         log.trace("Making field " + targetObject.getClass().getName() + "." + field.getName() + " persistent");
112                     }
113 
114                     persistentObject = makePersistent(persistable);
115                     addedObjects.add(persistentObject);
116                     enhance(obj, addedObjects);
117                 }
118             }
119         }
120         catch (IllegalAccessException e)
121         {
122             throw new NotPersistableException("Security permissions do not permit objects of this type (" + field.getType().getName() + ") to be persisted (must have ReflectPermission(\"suppressAccessChecks\") permission)", e);
123         }
124     }
125 
126     private PersistentObject makePersistent(Persistable obj)
127     {
128         PersistentObject persistentObject;
129         persistentObject = persistentObjectFactory.createPersistentObject();
130         persistentObject.initializeAsNewObject(obj);
131         obj.setPersistentObject(persistentObject);
132         return persistentObject;
133     }
134 }