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
55
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
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 }