View Javadoc

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;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.lang.SystemUtils;
24  import org.apache.commons.lang.builder.ToStringBuilder;
25  import org.apache.ojb.broker.metadata.MetadataException;
26  import org.apache.ojb.broker.util.logging.Logger;
27  import org.apache.ojb.broker.util.logging.LoggerFactory;
28  
29  /**
30   * Abstract {@link PersistentField} base implementation class.
31   *
32   * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
33   * @version $Id: PersistentFieldBase.java,v 1.1 2007-08-24 22:17:35 ewestfal Exp $
34   */
35  public abstract class PersistentFieldBase implements PersistentField
36  {
37      public static final String PATH_TOKEN = "::";
38  
39      private String fieldName;
40      protected Class rootObjectType;
41  
42      /**
43       * For internal use only!!
44       * TODO: Default constructor only needed to support
45       * PersistentFieldFactory#usesAccessorsAndMutators()
46       * method - find a better solution. Make 'public' to
47       * allow helper class to instantiate class.
48       */
49      public PersistentFieldBase()
50      {
51      }
52  
53      public PersistentFieldBase(Class clazz, String fieldname)
54      {
55          this.rootObjectType = clazz;
56          this.fieldName = fieldname;
57      }
58  
59      /**
60       * A value of true indicates that this field should
61       * suppress Java language access checking when it is used.
62       */
63      protected abstract boolean makeAccessible();
64  
65      public String getName()
66      {
67          return fieldName;
68      }
69  
70      public Class getDeclaringClass()
71      {
72          return rootObjectType;
73      }
74  
75      protected List getFieldGraph(boolean makeAccessible)
76      {
77          List result = new ArrayList();
78          String[] fields = StringUtils.split(getName(), PATH_TOKEN);
79          Field fld = null;
80          for (int i = 0; i < fields.length; i++)
81          {
82              String fieldName = fields[i];
83              try
84              {
85                  if (fld == null)
86                  {
87                      fld = getFieldRecursive(rootObjectType, fieldName);
88                  }
89                  else
90                  {
91                      fld = getFieldRecursive(fld.getType(), fieldName);
92                  }
93                  if (makeAccessible)
94                  {
95                      fld.setAccessible(true);
96                  }
97              }
98              catch (NoSuchFieldException e)
99              {
100                 throw new MetadataException("Can't find member '"
101                         + fieldName + "' in class " + (fld != null ? fld.getDeclaringClass() : rootObjectType), e);
102             }
103             result.add(fld);
104         }
105         return result;
106     }
107 
108     /**
109      * try to find a field in class c, recurse through class hierarchy if necessary
110      *
111      * @throws NoSuchFieldException if no Field was found into the class hierarchy
112      */
113     private Field getFieldRecursive(Class c, String name) throws NoSuchFieldException
114     {
115         try
116         {
117             return c.getDeclaredField(name);
118         }
119         catch (NoSuchFieldException e)
120         {
121             // if field  could not be found in the inheritance hierarchy, signal error
122             if ((c == Object.class) || (c.getSuperclass() == null) || c.isInterface())
123             {
124                 throw e;
125             }
126             // if field could not be found in class c try in superclass
127             else
128             {
129                 return getFieldRecursive(c.getSuperclass(), name);
130             }
131         }
132     }
133 
134     protected Logger getLog()
135     {
136         return LoggerFactory.getLogger("PersistentField");
137     }
138 
139     public String toString()
140     {
141         ToStringBuilder buf = new ToStringBuilder(this);
142         buf.append("rootType", rootObjectType);
143         buf.append("fieldName", fieldName);
144         return buf.toString();
145     }
146 
147     /**
148      * Build a String representation of given arguments.
149      */
150     protected String buildErrorSetMsg(Object obj, Object value, Field aField)
151     {
152         String eol = SystemUtils.LINE_SEPARATOR;
153         StringBuffer buf = new StringBuffer();
154         buf
155                 .append(eol + "[try to set 'object value' in 'target object'")
156                 .append(eol + "target obj class: " + (obj != null ? obj.getClass().getName() : null))
157                 .append(eol + "target field name: " + (aField != null ? aField.getName() : null))
158                 .append(eol + "target field type: " + (aField != null ? aField.getType() : null))
159                 .append(eol + "target field declared in: " + (aField != null ? aField.getDeclaringClass().getName() : null))
160                 .append(eol + "object value class: " + (value != null ? value.getClass().getName() : null))
161                 .append(eol + "object value: " + (value != null ? value : null))
162                 .append(eol + "]");
163         return buf.toString();
164     }
165 
166     /**
167      * Build a String representation of given arguments.
168      */
169     protected String buildErrorGetMsg(Object obj, Field aField)
170     {
171         String eol = SystemUtils.LINE_SEPARATOR;
172         StringBuffer buf = new StringBuffer();
173         buf
174                 .append(eol + "[try to read from source object")
175                 .append(eol + "source obj class: " + (obj != null ? obj.getClass().getName() : null))
176                 .append(eol + "target field name: " + (aField != null ? aField.getName() : null))
177                 .append(eol + "target field type: " + (aField != null ? aField.getType() : null))
178                 .append(eol + "target field declared in: " + (aField != null ? aField.getDeclaringClass().getName() : null))
179                 .append(eol + "]");
180         return buf.toString();
181     }
182 }