View Javadoc

1   package org.apache.ojb.broker.metadata.fieldaccess;
2   
3   /* Copyright 2002-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.io.Serializable;
19  
20  import org.apache.ojb.broker.metadata.MetadataException;
21  import org.apache.ojb.broker.util.ClassHelper;
22  
23  /**
24   * PeristentField implementation that attempts to detect the nature of
25   * the field it is persisting.
26   * <p>
27   * First checks to see if it is a Field, then Property, then DynaBean
28   * <p>
29   * It will match in that order.
30   */
31  public class PersistentFieldAutoProxyImpl extends PersistentFieldBase
32  {
33      static final long serialVersionUID = 6286229945422476325L;
34  
35      /**
36       * Define the number and ordering of the used {@link PersistentField}
37       * implementaions. Override this field to add new classes or to change
38       * setection order.
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 }