View Javadoc

1   /*
2    * Copyright 2011 FatWire Corporation. All Rights Reserved.
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  
17  package com.fatwire.gst.foundation.controller.action;
18  
19  import java.lang.reflect.Field;
20  import java.lang.reflect.InvocationTargetException;
21  import java.lang.reflect.Method;
22  import java.util.Date;
23  
24  import javax.servlet.http.HttpSession;
25  
26  import org.apache.commons.lang.StringUtils;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  import COM.FutureTense.Interfaces.ICS;
31  
32  import com.fatwire.cs.core.db.Util;
33  import com.fatwire.gst.foundation.DebugHelper;
34  import com.fatwire.gst.foundation.controller.annotation.Bind;
35  import com.fatwire.gst.foundation.controller.annotation.InjectForRequest;
36  
37  /**
38   * Helper to bind variables to an Object based on annotated fields.
39   * 
40   * @author Dolf Dijkstra
41   * @since 12 mei 2012
42   */
43  public final class AnnotationBinder {
44      protected static final Log LOG = LogFactory.getLog(AnnotationBinder.class.getPackage().getName());
45      protected static final Log LOG_TIME = LogFactory.getLog(AnnotationBinder.class.getPackage().getName() + ".time");
46  
47      /**
48       * Inject ICS runtime objects into the object. Objects flagged with the
49       * {@link InjectForRequest} annotation will be populated by this method by
50       * retrieving the value from the {@link Factory#getObject(String,Class)}
51       * method.
52       * 
53       * @param object the object to inject into.
54       * @param ics the ics context.
55       */
56      public static final void bind(final Object object, ICS ics) {
57          if (object == null) {
58              throw new IllegalArgumentException("Object cannot be null.");
59          }
60          if (ics == null) {
61              throw new IllegalArgumentException("CS cannot be null.");
62          }
63          final long start = LOG_TIME.isDebugEnabled() ? System.nanoTime() : 0L;
64          try {
65              Class<?> c = object.getClass();
66              // all annotated fields.
67              while (c != Object.class && c != null) {
68                  for (final Field field : c.getDeclaredFields()) {
69                      if (field.isAnnotationPresent(Bind.class)) {
70                          bindToField(object, ics, field);
71                      }
72  
73                  }
74  
75                  c = c.getSuperclass();
76              }
77          } finally {
78              DebugHelper.printTime(LOG_TIME, "inject model for " + object.getClass().getName(), start);
79          }
80      }
81  
82      /**
83       * @param object object to bind to
84       * @param ics the ics context
85       * @param field the field to inject to
86       * @throws SecurityException
87       */
88      public static void bindToField(final Object object, final ICS ics, final Field field) throws SecurityException {
89  
90          if (!field.isAccessible()) {
91              field.setAccessible(true); // make private fields accessible
92          }
93          final Bind ifr = field.getAnnotation(Bind.class);
94  
95          String name = ifr.value();
96          if (StringUtils.isBlank(name)) {
97              name = field.getName();
98          }
99          try {
100 
101             switch (ifr.scope()) {
102                 case ics:
103                     if (field.getType().isArray()) {
104 
105                     } else {
106                         String var = ics.GetVar(name);
107                         if (StringUtils.isBlank(var)) {
108                             put(object, field, ics.GetObj(name));
109                         } else {
110                             put(object, field, var);
111                         }
112                     }
113                     break;
114                 case request:
115                     put(object, field, ics.getAttribute(name));
116 
117                     break;
118                 case session:
119                     @SuppressWarnings("deprecation")
120                     HttpSession s = ics.getIServlet().getServletRequest().getSession(false);
121                     if (s != null) {
122                         Object obj = s.getAttribute(name);
123                         if (obj == null) {
124                             try {
125                                 Method m = object.getClass().getMethod("create" + field.getType().getSimpleName(),
126                                         ICS.class);
127                                 obj = m.invoke(object, ics);
128                                 s.setAttribute(name, obj);
129                             } catch (NoSuchMethodException e) {
130                                 // ignore
131                             } catch (IllegalArgumentException e) {
132                                 LOG.debug(e);
133                             } catch (InvocationTargetException e) {
134                                 LOG.warn(e.getMessage());
135                             }
136                         }
137                         put(object, field, obj);
138                     }
139                     break;
140 
141             }
142         } catch (final IllegalAccessException e) {
143             throw new RuntimeException(e);
144         }
145 
146     }
147 
148     private static void putPrimitive(Object object, Field field, Object v) throws IllegalAccessException {
149         try {
150             if (field.getType() == Byte.TYPE) {
151                 field.setByte(object, (Byte) v);
152             } else if (field.getType() == Integer.TYPE) {
153                 field.setInt(object, (Integer) v);
154             } else if (field.getType() == Double.TYPE) {
155                 field.setDouble(object, (Double) (v));
156             } else if (field.getType() == Float.TYPE) {
157                 field.setFloat(object, (Float) (v));
158             } else if (field.getType() == Long.TYPE) {
159                 field.setLong(object, (Long) (v));
160             } else if (field.getType() == Short.TYPE) {
161                 field.setShort(object, (Short) (v));
162             } else if (field.getType() == Boolean.TYPE) {
163                 field.setBoolean(object, (Boolean) (v));
164             } else {
165                 LOG.debug("Can't set primitive field " + field.getName() + " to " + v);
166             }
167         } catch (final IllegalAccessException e) {
168             throw new IllegalAccessException("IllegalAccessException binding " + v + " to field " + field.getName());
169         }
170 
171     }
172 
173     private static void put(Object object, Field field, Object value) throws IllegalAccessException {
174         if (value == null)
175             return;
176         if (value instanceof String) {
177             put(object, field, (String) value);
178         } else if (field.getType().isPrimitive()) {
179             putPrimitive(object, field, value);
180 
181         } else {
182 
183         }
184 
185     }
186 
187     private static void put(Object object, Field field, String var) throws IllegalAccessException {
188         if (StringUtils.isBlank(var))
189             return;
190         if (field.getType().isPrimitive()) {
191             putPrimitive(object, field, var);
192         } else {
193 
194             Object value = null;
195             if (field.getType() == String.class) {
196                 value = var;
197             } else if (field.getType() == Date.class) {
198                 value = Util.parseJdbcDate(var);
199             } else if (field.getType() == Integer.class) {
200                 value = new Integer(var);
201             } else if (field.getType() == Double.class) {
202                 value = new Double(var);
203             } else if (field.getType() == Character.class) {
204                 value = new Character(var.charAt(0));
205             } else if (field.getType() == Long.class) {
206                 value = new Long(var);
207             }
208             if (LOG.isDebugEnabled()) {
209                 LOG.debug("Binding " + value + " to field " + field.getName() + " for " + object.getClass().getName());
210             }
211             try {
212                 field.set(object, value);
213             } catch (final IllegalArgumentException e) {
214                 throw new IllegalArgumentException("IllegalArgumentException binding " + value + " to field "
215                         + field.getName(), e);
216             } catch (final IllegalAccessException e) {
217                 throw new IllegalAccessException("IllegalAccessException binding " + value + " to field "
218                         + field.getName());
219             }
220         }
221 
222     }
223 
224     private static void putPrimitive(Object object, Field field, String s) throws IllegalAccessException {
225         if (StringUtils.isBlank(s))
226             return;
227         try {
228             if (field.getType() == Byte.TYPE) {
229                 field.setByte(object, Byte.parseByte(s));
230             } else if (field.getType() == Integer.TYPE) {
231                 field.setInt(object, Integer.parseInt(s));
232             } else if (field.getType() == Double.TYPE) {
233                 field.setDouble(object, Double.parseDouble(s));
234             } else if (field.getType() == Float.TYPE) {
235                 field.setFloat(object, Float.parseFloat(s));
236             } else if (field.getType() == Long.TYPE) {
237                 field.setLong(object, Long.parseLong(s));
238             } else if (field.getType() == Short.TYPE) {
239                 field.setShort(object, Short.parseShort(s));
240             } else if (field.getType() == Boolean.TYPE) {
241                 field.setBoolean(object, Boolean.parseBoolean(s));
242             } else {
243                 LOG.debug("Can't set primitive field " + field.getName() + " to " + s);
244             }
245         } catch (final IllegalAccessException e) {
246             throw new IllegalAccessException("IllegalAccessException binding " + s + " to field " + field.getName());
247         }
248 
249     }
250 }