BeanDomSerializer.java

biz/hammurapi/xml/dom/BeanDomSerializer.java

Violations

Inspector Message Severity Location
Java Inspector 048 Copyrights information should be present in each file. 1
Java Inspector 086 Use equals() instead of == or != to compare objects. 1 58:67
Java Inspector 086 Use equals() instead of == or != to compare objects. 1 151:90
Java Inspector 049 Use a Collection instead of arrays Object[] 2 136:57
Java Inspector 049 Use a Collection instead of arrays Object[] 2 137:59
Java Inspector 049 Use a Collection instead of arrays Object[] 2 168:58
Java Inspector 070-A Cyclomatic complexity is too high: 13, maximum allowed is 12 2 106:33
Java Inspector 082 Parenthesis are redundant. 2 141:70
Java Inspector 082 Parenthesis are redundant. 2 144:77
Java Inspector 089 Type is not documented 2 42:1
Java Inspector 089 Undocumented constructor 2 49:17
Java Inspector 089 Undocumented method 2 53:17
Java Inspector 089 Undocumented method 2 57:17
Java Inspector 089 Undocumented method 2 102:9
Java Inspector 089 Undocumented method 2 106:33
Java Inspector 025 Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] 3 154:167
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 123:69
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 129:69
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 131:65
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 146:104
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 205:68
Java Inspector 026 Avoid hardwired string literals. Allowed literals: [] 3 207:33
Java Inspector 051 It is good practice to call in any case super() in a constructor. 3 49:17
Java Inspector 054 Discourage usage of instance variables like a, j by enforcing minimal variable name length (3). 3 47:17

Source code

1/*
2 * hgcommons 9
3 * Hammurapi Group Common Library
4 * Copyright (C) 2003 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
21 * e-Mail: support@hammurapi.biz
22 */
23package biz.hammurapi.xml.dom;
24
25import java.lang.reflect.Field;
26import java.lang.reflect.Method;
27import java.lang.reflect.Modifier;
28import java.util.HashMap;
29import java.util.HashSet;
30import java.util.Map;
31import java.util.Set;
32
33import org.w3c.dom.Element;
34
35import biz.hammurapi.convert.Converter;
36
37/**
38 * @author Pavel Vlasov
39 *
40 * @version $Revision: 1.4 $
41 */
42public class BeanDomSerializer {
43 private class StackEntry {
44 long counter;
45
46 private class IdentityWrapper {
47 Object o;
48
49 public IdentityWrapper(Object o) {
50 this.o=o;
51 }
52
53 public int hashCode() {
54 return o.hashCode();
55 }
56
57 public boolean equals(Object obj) {
58 return obj instanceof IdentityWrapper && o==((IdentityWrapper) obj).o;
59 }
60 }
61
62 Map identityMap=new HashMap();
63 Map referenceMap=new HashMap();
64
65 Long getReference(Object o) {
66 if (o instanceof Number || o instanceof String) {
67 return (Long) referenceMap.get(o);
68 }
69
70 return (Long) identityMap.get(new IdentityWrapper(o));
71 }
72
73 long addReference(Object o) {
74 if (o instanceof Number || o instanceof String) {
75 Long ref=(Long) referenceMap.get(o);
76 if (ref==null) {
77 long next=counter++;
78 referenceMap.put(o, new Long(next));
79 return next;
80 }
81
82 return ref.longValue();
83 }
84
85 IdentityWrapper iw = new IdentityWrapper(o);
86
87 Long ref=(Long) identityMap.get(iw);
88 if (ref==null) {
89 long next=counter++;
90 identityMap.put(iw, new Long(next));
91 return next;
92 }
93
94 return ref.longValue();
95 }
96 }
97
98 private static ThreadLocal stack=new ThreadLocal();
99
100 private Set badMethods=new HashSet();
101
102 public DomSerializable convert(final Object object, final Converter master) {
103 if (object!=null) {
104 return new DomSerializable() {
105
106 public void toDom(Element holder) {
107 if (object instanceof Class) {
108 holder.appendChild(holder.getOwnerDocument().createTextNode(((Class) object).getName()));
109 return;
110 }
111
112 StackEntry sEntry=(StackEntry) stack.get();
113 boolean clean = sEntry==null;
114 if (clean) {
115 sEntry=new StackEntry();
116 stack.set(sEntry);
117 }
118
119 try {
120
121 Long refId=sEntry.getReference(object);
122 if (refId!=null) {
123 holder.setAttribute("refid", refId.toString());
124 return;
125 }
126
127 long nextCounter = sEntry.addReference(object);
128 //System.out.println("New id: "+nextCounter);
129 holder.setAttribute("id", String.valueOf(nextCounter));
130
131 holder.setAttribute("type", object.getClass().getName());
132 holder.appendChild(holder.getOwnerDocument().createTextNode(object.toString()));
133
134 if (master!=null) {
135 Class beanClass=object.getClass();
136 final Object[] args = new Object[] {};
137 Method[] methods = beanClass.getMethods();
138 for (int i=0; i<methods.length; i++) {
139 // getXXX() methods. Object.getClass() is not included.
140 Method method = methods[i];
141 if (!(void.class.equals(method.getReturnType()))
142 && Modifier.isPublic(method.getModifiers())
143 && !Modifier.isAbstract(method.getModifiers())
144 && !(method.getDeclaringClass().equals(Object.class))
145 && !Modifier.isStatic(method.getModifiers())
146 && method.getName().startsWith("get")
147 && method.getParameterTypes().length==0
148 && !isBad(method)) {
149 try {
150 Object value=method.invoke(object, args);
151 if (value!=object) {
152 DomSerializable vds=(DomSerializable) master.convert(value, DomSerializable.class, null);
153 if (vds!=null) {
154 Element ve=holder.getOwnerDocument().createElement(method.getName().substring(3));
155 holder.appendChild(ve);
156 vds.toDom(ve);
157 }
158 }
159 } catch (Exception e) {
160 synchronized (badMethods) {
161 badMethods.add(method);
162 }
163 handleAccessError(holder, method, e, master);
164 }
165 }
166 }
167
168 Field[] fields = beanClass.getFields();
169 for (int i=0; i<fields.length; i++) {
170 Field field = fields[i];
171 if (!Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers())) {
172 try {
173 Object value=field.get(object);
174 DomSerializable vds=(DomSerializable) master.convert(value, DomSerializable.class, null);
175 if (vds!=null) {
176 Element ve=holder.getOwnerDocument().createElement(field.getName());
177 holder.appendChild(ve);
178 vds.toDom(ve);
179 }
180 } catch (Exception e) {
181 handleAccessError(holder, field, e, master);
182 }
183 }
184 }
185 }
186 } finally {
187 if (clean) {
188 stack.set(null);
189 }
190 }
191 }
192
193 private boolean isBad(Method method) {
194 synchronized (badMethods) {
195 return badMethods.contains(method);
196 }
197 }
198 };
199 }
200
201 return null;
202 }
203
204 private void handleAccessError(Element holder, java.lang.reflect.Member member, Throwable e, Converter master) {
205 Element ee=holder.getOwnerDocument().createElement("access-error");
206 holder.appendChild(ee);
207 ee.setAttribute("member", member.toString());
208 DomSerializable eds=(DomSerializable) master.convert(e, DomSerializable.class, null);
209 eds.toDom(ee);
210 }
211}
212