View Javadoc

1   package net.sf.mmapps.commons.beans;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   import org.apache.commons.beanutils.PropertyUtils;
8   import org.apache.commons.logging.Log;
9   import org.apache.commons.logging.LogFactory;
10  import org.mmbase.bridge.*;
11  import org.mmbase.bridge.Field;
12  import org.mmbase.bridge.FieldIterator;
13  import org.mmbase.bridge.FieldList;
14  import org.mmbase.bridge.Node;
15  import org.mmbase.bridge.NodeManager;
16  
17  /***
18   * Utilities to map Node fields to POJO's by using Apache Commons BeanUtils
19   * 
20   * @author Wouter Heijke
21   * @version $Revision: 1.1 $
22   */
23  public class MMBaseNodeMapper {
24  	private static Log log = LogFactory.getLog(MMBaseNodeMapper.class);
25  
26  	/***
27  	 * Maps fields from a MMBase node to a Java Object
28  	 * 
29  	 * @param node MMBase Node to use
30  	 * @param nodeClass Java object to place values from source Node fields into
31  	 * @return The initialized Java object
32  	 */
33  	public static Object copyNode(Node node, Object nodeClass) {
34  
35  		if (node != null && nodeClass != null) {
36  			NodeManager nodeManager = node.getNodeManager();
37  
38  			FieldList fl = nodeManager.getFields();
39  			FieldIterator fli = fl.fieldIterator();
40  			while (fli.hasNext()) {
41  				Field f = fli.nextField();
42  				String fname = f.getName();
43  				Object v = null; 
44                  if (!fname.equalsIgnoreCase("number") && f.getType() == Field.TYPE_NODE) {
45                      v = node.getNodeValue(fname);
46                  }
47                  else {
48                      v = node.getObjectValue(fname);
49                  }
50  
51  				if (fname.equalsIgnoreCase("number")) {
52  					fname = "id";
53  				} else if (fname.equalsIgnoreCase("otype")) {
54  					// fname = "type";
55  					// v = getOType(v);
56  				}
57  
58  				if (v != null && fname != null) {
59  					if (PropertyUtils.isWriteable(nodeClass, fname)) {
60  						try {
61  							PropertyUtils.setProperty(nodeClass, fname, v);
62                          } catch (IllegalArgumentException e) {
63                              log.error("IllegalArgumentException for Node '" + node.getNumber()
64                                      + "' on Class '" + nodeClass.getClass().getName()
65                                      + "' on fieldname '" + fname + "'"); 
66                              throw e;
67  						} catch (IllegalAccessException e) {
68  							log.error("IllegalAccessException for Node '" + node.getNumber()
69                                      + "' on Class '" + nodeClass.getClass().getName()
70                                      + "' on fieldname '" + fname + "'");
71  						} catch (InvocationTargetException e) {
72  							log.error("InvocationTargetException for Node '" + node.getNumber()
73                                      + "' on fieldname '" + fname + "'");
74  						} catch (NoSuchMethodException e) {
75  							log.error("NoSuchMethodException for Node '" + node.getNumber()
76                                      + "' on fieldname '" + fname + "'");
77  						}
78  					} else {
79  						//log.warn("Property '" + fname + "' doesn't exist or not writable");
80  					}
81  				}
82  			}
83  		}
84  
85  		return nodeClass;
86  	}
87  
88  	/***
89  	 * Maps fields from a MMBase node to a Java Class
90  	 * 
91  	 * @param node MMBase Node to use
92  	 * @param clazz Java class to place values from source Node fields into
93  	 * @return Instance of the Java Class initialized with the fields from the
94  	 *         Node
95  	 */
96  	public static Object copyNode(Node node, Class clazz) {
97  		Object nodeClass = null;
98  
99  		if (node != null && clazz != null) {
100 			try {
101 				nodeClass = clazz.newInstance();
102 				nodeClass = copyNode(node, nodeClass);
103 			} catch (InstantiationException e) {
104 				log.error("InstantiationException for Node '" + node.getNumber() + "' on Class '"
105 						+ nodeClass.getClass().getName() + "'");
106 			} catch (IllegalAccessException e) {
107 				log.error("IllegalAccessException for Node '" + node.getNumber() + "' on Class '"
108 						+ nodeClass.getClass().getName() + "'");
109 			}
110 		}
111 		return nodeClass;
112 	}
113     
114     public static List convertList(NodeList l, Class clazz) {
115         List result = new ArrayList();
116         for (int i = 0; i < l.size(); i++) {
117             Object object = copyNode(l.getNode(i), clazz);
118             result.add(object);
119         }
120         return result;
121     }
122 
123 	public static void copyBean(Object bean, Node node) {
124 		if (node != null && bean != null) {
125 			NodeManager nodeManager = node.getNodeManager();
126 
127 			FieldList fl = nodeManager.getFields();
128 			FieldIterator fli = fl.fieldIterator();
129 			while (fli.hasNext()) {
130 				Field f = fli.nextField();
131 				String fname = f.getName();
132 
133 				if (fname != null) {
134 					log.debug("field='" + fname + "'");
135 
136 					if (fname.equalsIgnoreCase("number") || fname.equalsIgnoreCase("otype") || fname.equalsIgnoreCase("owner")) {
137 						log.debug("ignore:" + fname);
138 					} else {
139 						if (PropertyUtils.isReadable(bean, fname)) {
140 							try {
141 								Object value = PropertyUtils.getProperty(bean, fname);
142 
143 								int fieldType = f.getType();
144 								switch (fieldType) {
145 								case Field.TYPE_DOUBLE:
146 									node.setDoubleValue(fname, ((Double) (value)).doubleValue());
147 									break;
148 								case Field.TYPE_FLOAT:
149 									node.setFloatValue(fname, ((Float) (value)).floatValue());
150 									break;
151 								case Field.TYPE_INTEGER:
152 									node.setIntValue(fname, ((Integer) (value)).intValue());
153 									break;
154 								case Field.TYPE_LONG:
155 									node.setLongValue(fname, ((Long) (value)).longValue());
156 									break;
157 								case Field.TYPE_NODE:
158 									break;
159 								case Field.TYPE_STRING:
160 									node.setStringValue(fname, (String) value);
161 									break;
162 								default:
163 									node.setObjectValue(fname, value);
164 								}
165 
166 							} catch (IllegalArgumentException e) {
167 								log.error("IllegalArgumentException for Node '" + node.getNumber() + "' on Class '"
168 										+ bean.getClass().getName() + "' on fieldname '" + fname + "'");
169 								throw e;
170 							} catch (IllegalAccessException e) {
171 								log.error("IllegalAccessException for Node '" + node.getNumber() + "' on Class '"
172 										+ bean.getClass().getName() + "' on fieldname '" + fname + "'");
173 							} catch (InvocationTargetException e) {
174 								log.error("InvocationTargetException for Node '" + node.getNumber() + "' on fieldname '" + fname
175 										+ "'");
176 							} catch (NoSuchMethodException e) {
177 								log.error("NoSuchMethodException for Node '" + node.getNumber() + "' on fieldname '" + fname
178 										+ "'");
179 							}
180 						} else {
181 							log.warn("Property '" + fname + "' doesn't exist or not readable");
182 						}
183 
184 					}
185 				}
186 			}
187 		}
188 	}
189 
190 }