1 package org.apache.ojb.broker.metadata.fieldaccess;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.io.Serializable;
19
20 import org.apache.ojb.broker.metadata.MetadataException;
21 import org.apache.ojb.broker.util.ClassHelper;
22
23
24
25
26
27
28
29
30
31 public class PersistentFieldAutoProxyImpl extends PersistentFieldBase
32 {
33 static final long serialVersionUID = 6286229945422476325L;
34
35
36
37
38
39
40 protected Class[] persistentFieldClasses = new Class[]{
41 PersistentFieldDirectImpl.class
42 , PersistentFieldIntrospectorImpl.class
43 , PersistentFieldPrivilegedImpl.class
44 , PersistentFieldDynaBeanImpl.class};
45
46 private PersistentField currentPF;
47 private ExceptionWrapper latestException;
48 int index = 0;
49
50 public PersistentFieldAutoProxyImpl()
51 {
52 }
53
54 public PersistentFieldAutoProxyImpl(Class clazz, String fieldname)
55 {
56 super(clazz, fieldname);
57 }
58
59 private PersistentField getCurrent()
60 {
61 if (currentPF == null)
62 {
63 if(index >= persistentFieldClasses.length)
64 {
65 index = 0;
66 currentPF = null;
67 throw new AutoDetectException("Can't autodetect valid PersistentField implementation: "
68 + latestException.message, latestException.exception);
69 }
70 try
71 {
72 currentPF = createPersistentFieldForIndex();
73 }
74 catch (Exception e)
75 {
76 throw new AutoDetectException("Can't create instance for " + persistentFieldClasses[index], e);
77 }
78 }
79 return currentPF;
80 }
81
82 private void handleException(String message, Exception e)
83 {
84 latestException = new ExceptionWrapper(message, e);
85 currentPF = null;
86 ++index;
87 }
88
89
90 public Object get(Object anObject) throws MetadataException
91 {
92 try
93 {
94 return getCurrent().get(anObject);
95 }
96 catch (Exception e)
97 {
98 if(e instanceof AutoDetectException)
99 {
100 throw (MetadataException) e;
101 }
102 else
103 {
104 handleException("Can't extract field value for field " + getName()
105 + " from object " + (anObject != null ? anObject.getClass() : null), e);
106 return get(anObject);
107 }
108 }
109 }
110
111 public void set(Object obj, Object value) throws MetadataException
112 {
113 try
114 {
115 getCurrent().set(obj, value);
116 }
117 catch (Exception e)
118 {
119 if(e instanceof AutoDetectException)
120 {
121 throw (MetadataException) e;
122 }
123 else
124 {
125 handleException("Can't set value for field " + getName()
126 + " to object " + (obj != null ? obj.getClass() : null), e);
127 set(obj, value);
128 }
129 }
130 }
131
132 public Class getType()
133 {
134 try
135 {
136 return getCurrent().getType();
137 }
138 catch (Exception e)
139 {
140 if(e instanceof AutoDetectException)
141 {
142 throw (MetadataException) e;
143 }
144 else
145 {
146 handleException("Can't identify field type for field " + getName(), null);
147 return getType();
148 }
149 }
150 }
151
152 protected boolean makeAccessible()
153 {
154 return false;
155 }
156
157 public boolean usesAccessorsAndMutators()
158 {
159 return false;
160 }
161
162 private PersistentField createPersistentFieldForIndex() throws Exception
163 {
164 return newInstance(persistentFieldClasses[index]);
165 }
166
167 private PersistentField newInstance(Class pfClass) throws Exception
168 {
169 Class[] types = new Class[]{Class.class, String.class};
170 Object[] args = new Object[]{getDeclaringClass(), getName()};
171 return (PersistentField) ClassHelper.newInstance(pfClass, types, args);
172 }
173
174 static class ExceptionWrapper implements Serializable
175 {
176 private static final long serialVersionUID = 3691042088451912249L;
177 Exception exception;
178 String message;
179
180 public ExceptionWrapper(String message, Exception exception)
181 {
182 this.message = message;
183 this.exception = exception;
184 }
185 }
186
187 static class AutoDetectException extends MetadataException
188 {
189 private static final long serialVersionUID = 3257290223049585970L;
190
191 public AutoDetectException()
192 {
193 super();
194 }
195
196 public AutoDetectException(Throwable t)
197 {
198 super(t);
199 }
200
201 public AutoDetectException(String message)
202 {
203 super(message);
204 }
205
206 public AutoDetectException(String message, Throwable t)
207 {
208 super(message, t);
209 }
210 }
211 }