KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > metadata > fieldaccess > PersistentFieldDirectImpl


1 package org.apache.ojb.broker.metadata.fieldaccess;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.lang.reflect.Field JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.apache.ojb.broker.metadata.MetadataException;
22 import org.apache.ojb.broker.util.ClassHelper;
23 import org.apache.ojb.broker.core.proxy.ProxyHelper;
24
25 /**
26  * This {@link org.apache.ojb.broker.metadata.fieldaccess.PersistentField} implementation
27  * is the high-speed version of the access strategies.
28  * <br/>
29  * It does not cooperate with an AccessController,
30  * but accesses the fields directly. This implementation persistent
31  * attributes don't need getters and setters
32  * and don't have to be declared public or protected. Only the the
33  * metadata field names have to match the class fields.
34  *
35  * @version $Id: PersistentFieldDirectImpl.java,v 1.2.2.2 2005/12/21 22:26:41 tomdz Exp $
36  */

37 public class PersistentFieldDirectImpl extends PersistentFieldBase
38 {
39     private static final long serialVersionUID = -5458024240998909205L;
40
41     private transient boolean isInitialized;
42     private transient List JavaDoc fieldsList;
43     private transient Field JavaDoc field;
44     private transient boolean nonNested;
45
46     public PersistentFieldDirectImpl()
47     {
48     }
49
50     public PersistentFieldDirectImpl(Class JavaDoc type, String JavaDoc fieldname)
51     {
52         super(type, fieldname);
53     }
54
55     public Class JavaDoc getType()
56     {
57         return getField().getType();
58     }
59
60     /**
61      * Returns the underlying field object.
62      * If parameter <tt>setAccessible</tt> is true the
63      * field access checking was suppressed.
64      */

65     protected Field JavaDoc getField()
66     {
67         // make sure class was initialized
68
if (!isInitialized)
69         {
70             /*
71             first we build a graph of fields for nested fields support,
72             but for best performance on non-nested fields we also keep
73             the latest field separate and set a 'is nested' flag.
74             */

75             fieldsList = getFieldGraph(makeAccessible());
76             field = (Field JavaDoc) fieldsList.get(fieldsList.size() - 1);
77             nonNested = fieldsList.size() == 1;
78             isInitialized = true;
79         }
80         return field;
81     }
82
83     private List JavaDoc getFieldsList()
84     {
85         // make sure class was initialized
86
if (!isInitialized) getField();
87         return fieldsList;
88     }
89
90     protected boolean isNestedField()
91     {
92         return !nonNested;
93     }
94
95     /**
96      * do not override this method, have a look at {@link #setValueFor(java.lang.reflect.Field, Object, Object)}
97      */

98     public void set(Object JavaDoc target, Object JavaDoc value) throws MetadataException
99     {
100         // if target null, we have nothing to do
101
if(target == null) return;
102         Object JavaDoc current = target;
103         if (isNestedField())
104         {
105             List JavaDoc fields = getFieldsList();
106             int size = fields.size() - 1;
107             Field JavaDoc field;
108             for (int i = 0; i < size; i++)
109             {
110                 field = (Field JavaDoc) fields.get(i);
111                 Object JavaDoc attribute;
112                 try
113                 {
114                     attribute = getValueFrom(field, current);
115                 }
116                 catch (Exception JavaDoc e)
117                 {
118                     throw new MetadataException("Can't read field '" + field.getName() + "' of type " + field.getType().getName(), e);
119                 }
120                 if (attribute != null || value != null)
121                 {
122                     // if the intermediary nested object is null, we have to create
123
// a new instance to set the value
124
if (attribute == null)
125                     {
126                         try
127                         {
128                             attribute = ClassHelper.newInstance(field.getType());
129                         }
130                         catch (Exception JavaDoc e)
131                         {
132                             throw new MetadataException("Can't create nested object of type '"
133                                     + field.getType() + "' for field '"
134                                     + field.getName() + "'", e);
135                         }
136                     }
137                     try
138                     {
139                         //field.set(current, attribute);
140
setValueFor(field, current, attribute);
141                     }
142                     //catch (IllegalAccessException e)
143
catch (Exception JavaDoc e)
144                     {
145                         throw new MetadataException("Can't set nested object of type '"
146                                     + field.getType() + "' for field '"
147                                     + field.getName() + "'", e);
148                     }
149                 }
150                 else
151                 {
152                     return;
153                 }
154                 current = attribute;
155             }
156         }
157         setValueFor(getField(), current, value);
158     }
159
160     /**
161      * do not override this method, have a look at {@link #getValueFrom(java.lang.reflect.Field, Object)}
162      */

163     public Object JavaDoc get(Object JavaDoc target) throws MetadataException
164     {
165         Object JavaDoc result = target;
166         if (isNestedField())
167         {
168             List JavaDoc fields = getFieldsList();
169             for (int i = 0; i < fields.size(); i++)
170             {
171                 if (result == null) break;
172                 result = getValueFrom((Field JavaDoc) fields.get(i), result);
173             }
174         }
175         else
176         {
177             result = result != null ? getValueFrom(getField(), result) : null;
178         }
179         return result;
180     }
181
182
183
184     protected Object JavaDoc getValueFrom(Field JavaDoc field, Object JavaDoc target)
185     {
186         try
187         {
188             return field.get(ProxyHelper.getRealObject(target));
189             // TODO: don't make costly proxy test on field level use
190
// return field.get(target);
191
}
192         catch (IllegalAccessException JavaDoc e)
193         {
194             throw new MetadataException(
195                     "IllegalAccess error reading field: " +
196                     (field != null ? field.getName() : null) + " from object: "
197                     + (target != null ? target.getClass().getName() : null), e);
198         }
199         catch (IllegalArgumentException JavaDoc e)
200         {
201             throw new MetadataException(
202                     "IllegalArgument error reading field: " +
203                     buildErrorGetMsg(target, field), e);
204         }
205     }
206
207     protected void setValueFor(Field JavaDoc field, Object JavaDoc target, final Object JavaDoc value)
208     {
209         try
210         {
211             /**
212              * MBAIRD
213              * we need to be able to set values to null. We can only set something to null if
214              * the type is not a primitive (assignable from Object).
215              */

216             // thanks to Tomasz Wysocki for this trick
217
if ((value != null) || !field.getType().isPrimitive())
218             {
219                 field.set(ProxyHelper.getRealObject(target), value);
220                 // TODO: don't make costly proxy test on field level use
221
// field.set(target, value);
222
}
223         }
224         catch (NullPointerException JavaDoc ignored)
225         {
226             getLog().info("Target object '" + (target != null ? target.getClass().getName() : null)
227                     + "' for field '" + (field != null ? field.getName() : null)
228                     + "' of type '" + (field != null ? field.getType().getName() : null)
229                     + "' seems to be null. Can't write into null.", ignored);
230         }
231         catch (Exception JavaDoc e)
232         {
233             getLog().error("while set field: " + buildErrorSetMsg(target, value, field));
234             throw new MetadataException("IllegalAccess error setting field:" +
235                     (field != null ? field.getName() : null) + " in object:" + target.getClass().getName(), e);
236         }
237     }
238
239     /**
240      * This implementation returns always 'true'.
241      */

242     protected boolean makeAccessible()
243     {
244         return true;
245     }
246
247     /**
248      * Always returns 'false'.
249      * @see org.apache.ojb.broker.metadata.fieldaccess.PersistentField#usesAccessorsAndMutators
250      */

251     public boolean usesAccessorsAndMutators()
252     {
253         return false;
254     }
255 }
256
Popular Tags