Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mentawai/filter/InjectionFilter.java


1   /*
2    * Mentawai Web Framework http://mentawai.lohis.com.br/
3    * Copyright (C) 2005  Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com)
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18   */
19  package org.mentawai.filter;
20  
21  import java.lang.reflect.*;
22  import java.util.*;
23  
24  import org.mentawai.core.*;
25  import org.mentawai.util.*;
26  
27  /**
28   * A filter that tries to inject the input values in the action through setters. (Ex. <i>setUsername()</i>, <i>setPassword()</i>, etc.)
29   * It can also inject the input value directly in the attribute, even if it is a private field.
30   * Use this filter if you don't want to deal with the action input object and instaed you want to inject its values in the action.
31   * This filter tries to inject all the input values in the action.
32   *
33   * @author Sergio Oliveira
34   */
35  public class InjectionFilter implements Filter {
36      
37      private Map methods = new HashMap();
38      private boolean tryField = false;
39      
40      /**
41       * Creates an InjectionFilter that can be used by any action class.
42       * You may use this filter per action or as a global filter.
43       */
44      public InjectionFilter() { }
45      
46      /**
47       * Creates an InjectionFilter that can be used by any action class.
48       * You may use this filter per action or as a global filter.
49       * If tryField is true and it cannot find a setter for the input value,
50       * it will try to directly access the attribute, even if it is a private field.
51       *
52       * @param tryField A flag indicating whether this filter should try to access private attributes.
53       */    
54      public InjectionFilter(boolean tryField) {
55          this.tryField = tryField;
56      }
57      
58      /*
59       * Find a field, even if it is private...
60       */
61      static Field getField(Object target, String name) {
62          Field fields[] = target.getClass().getDeclaredFields();
63          for(int i=0;i<fields.length;i++) {
64              if (name.equals(fields[i].getName())) {
65                  return fields[i];
66              }
67          }
68          return null;
69      }
70      
71    /*
72     * Use reflection to inject the value in the action.
73     */
74    private void setValue(Object target, String name, Object value) {
75      try {
76        StringBuffer sb = new StringBuffer(30);
77        sb.append("set");
78        sb.append(name.substring(0,1).toUpperCase());
79        if (name.length() > 1) sb.append(name.substring(1));
80              
81              String methodName = sb.toString();
82              
83              Class actionClass = target.getClass();
84              
85              Map map = (Map) methods.get(actionClass);
86              if (map == null) {
87                  map = new HashMap();
88                  methods.put(actionClass, map);
89              }
90              
91              if (!map.containsKey(name)) {
92                  Method m = null;
93                  Field f = null;
94                  try {
95                //m = actionClass.getMethod(methodName, new Class[] { value.getClass() });
96                      m = FindMethod.getMethod(actionClass, methodName, new Class[] { value.getClass() });
97                  } catch(Exception e) {
98                      //e.printStackTrace();
99                      
100                     // try primitive...
101                     Class primitive = getPrimitiveFrom(value);
102                     if (primitive != null) {
103                         try {
104                             m = actionClass.getMethod(methodName, new Class[] { primitive });
105                         } catch(Exception ex) {
106                             //ex.printStackTrace();
107                         }
108                     }
109                     
110                     if (m == null && tryField) {
111                         // try field...
112                         f = getField(target, name);
113                         if (f != null) {
114                             f.setAccessible(true);
115                         }
116                     }
117                     
118                 }
119                 if (m != null) {
120                     map.put(name, m);
121                     m.setAccessible(true);
122                 } else {
123                     map.put(name, f);
124                 }
125             }
126             
127             Object obj = map.get(name);
128             if (obj instanceof Method) {
129                 Method m = (Method) obj;
130                 m.invoke(target, new Object[] { value });
131             } else if (obj instanceof Field) {
132                 Field f = (Field) obj;
133                 f.set(target, value);
134             }
135     } catch(Exception e) {
136       //e.printStackTrace();
137     }
138   }
139     
140     static Class getPrimitiveFrom(Object w) { 
141         if (w instanceof Boolean) { return Boolean.TYPE; } 
142         else if (w instanceof Byte) { return Byte.TYPE; } 
143         else if (w instanceof Short) { return Short.TYPE; } 
144         else if (w instanceof Character) { return Character.TYPE; } 
145         else if (w instanceof Integer) { return Integer.TYPE; } 
146         else if (w instanceof Long) { return Long.TYPE; } 
147         else if (w instanceof Float) { return Float.TYPE; } 
148         else if (w instanceof Double) { return Double.TYPE; } 
149         return null;
150     }
151   
152   public String filter(InvocationChain chain) throws Exception {
153     Action action = chain.getAction();
154         
155         Object model = null;
156         // model-driven...
157         if (action instanceof ModelDriven) {
158             ModelDriven md = (ModelDriven) action;
159             model = md.getModel();
160             if (model == null) throw new FilterException("ModelDriven action cannot return a null model!");
161         }
162         
163     Input input = action.getInput();
164         Iterator iter = input.keys();
165         while(iter.hasNext()) {
166             String name = (String) iter.next();
167             Object value = input.getValue(name);
168             if (value == null) continue;
169             if (model != null) {
170                 setValue(model, name, value);
171             } else {
172                 setValue(action, name, value);
173             }
174         }
175     return chain.invoke();
176   }
177     
178     public void destroy() { }
179 }
180