9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.beans;
26
27 import java.util.*;
28 import java.lang.reflect.*;
29 import sun.reflect.misc.*;
30
31
32 /**
33 * The <code>DefaultPersistenceDelegate</code> is a concrete implementation of
34 * the abstract <code>PersistenceDelegate</code> class and
35 * is the delegate used by default for classes about
36 * which no information is available. The <code>DefaultPersistenceDelegate</code>
37 * provides, version resilient, public API-based persistence for
38 * classes that follow the JavaBeans™ conventions without any class specific
39 * configuration.
40 * <p>
41 * The key assumptions are that the class has a nullary constructor
42 * and that its state is accurately represented by matching pairs
43 * of "setter" and "getter" methods in the order they are returned
44 * by the Introspector.
45 * In addition to providing code-free persistence for JavaBeans,
46 * the <code>DefaultPersistenceDelegate</code> provides a convenient means
47 * to effect persistent storage for classes that have a constructor
48 * that, while not nullary, simply requires some property values
164 }
165 }
166 return new Expression(oldInstance, oldInstance.getClass(), "new", constructorArgs);
167 }
168
169 private Method findMethod(Class type, String property) {
170 if (property == null) {
171 throw new IllegalArgumentException("Property name is null");
172 }
173 PropertyDescriptor pd = getPropertyDescriptor(type, property);
174 if (pd == null) {
175 throw new IllegalStateException("Could not find property by the name " + property);
176 }
177 Method method = pd.getReadMethod();
178 if (method == null) {
179 throw new IllegalStateException("Could not find getter for the property " + property);
180 }
181 return method;
182 }
183
184 private static boolean equals(Object o1, Object o2) {
185 return (o1 == null) ? (o2 == null) : o1.equals(o2);
186 }
187
188 private void doProperty(Class type, PropertyDescriptor pd, Object oldInstance, Object newInstance, Encoder out) throws Exception {
189 Method getter = pd.getReadMethod();
190 Method setter = pd.getWriteMethod();
191
192 if (getter != null && setter != null) {
193 Expression oldGetExp = new Expression(oldInstance, getter.getName(), new Object[]{});
194 Expression newGetExp = new Expression(newInstance, getter.getName(), new Object[]{});
195 Object oldValue = oldGetExp.getValue();
196 Object newValue = newGetExp.getValue();
197 out.writeExpression(oldGetExp);
198 if (!equals(newValue, out.get(oldValue))) {
199 // Search for a static constant with this value;
200 Object e = (Object[])pd.getValue("enumerationValues");
201 if (e instanceof Object[] && Array.getLength(e) % 3 == 0) {
202 Object[] a = (Object[])e;
203 for(int i = 0; i < a.length; i = i + 3) {
204 try {
205 Field f = type.getField((String)a[i]);
206 if (f.get(null).equals(oldValue)) {
207 out.remove(oldValue);
208 out.writeExpression(new Expression(oldValue, f, "get", new Object[]{null}));
209 }
210 }
211 catch (Exception ex) {}
212 }
213 }
214 invokeStatement(oldInstance, setter.getName(), new Object[]{oldValue}, out);
215 }
216 }
217 }
218
219 static void invokeStatement(Object instance, String methodName, Object[] args, Encoder out) {
220 out.writeStatement(new Statement(instance, methodName, args));
221 }
222
223 // Write out the properties of this instance.
224 private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) {
225 for (Field field : type.getFields()) {
226 int mod = field.getModifiers();
227 if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
228 continue;
229 }
230 try {
231 Expression oldGetExp = new Expression(field, "get", new Object[] { oldInstance });
232 Expression newGetExp = new Expression(field, "get", new Object[] { newInstance });
233 Object oldValue = oldGetExp.getValue();
234 Object newValue = newGetExp.getValue();
235 out.writeExpression(oldGetExp);
236 if (!equals(newValue, out.get(oldValue))) {
237 out.writeStatement(new Statement(field, "set", new Object[] { oldInstance, oldValue }));
238 }
239 }
240 catch (Exception exception) {
241 out.getExceptionListener().exceptionThrown(exception);
242 }
243 }
244 BeanInfo info;
245 try {
246 info = Introspector.getBeanInfo(type);
247 } catch (IntrospectionException exception) {
248 return;
249 }
250 // Properties
251 for (PropertyDescriptor d : info.getPropertyDescriptors()) {
252 if (d.isTransient()) {
253 continue;
254 }
255 try {
256 doProperty(type, d, oldInstance, newInstance, out);
|
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package java.beans;
26
27 import java.util.*;
28 import java.lang.reflect.*;
29 import java.util.Objects;
30 import sun.reflect.misc.*;
31
32
33 /**
34 * The <code>DefaultPersistenceDelegate</code> is a concrete implementation of
35 * the abstract <code>PersistenceDelegate</code> class and
36 * is the delegate used by default for classes about
37 * which no information is available. The <code>DefaultPersistenceDelegate</code>
38 * provides, version resilient, public API-based persistence for
39 * classes that follow the JavaBeans™ conventions without any class specific
40 * configuration.
41 * <p>
42 * The key assumptions are that the class has a nullary constructor
43 * and that its state is accurately represented by matching pairs
44 * of "setter" and "getter" methods in the order they are returned
45 * by the Introspector.
46 * In addition to providing code-free persistence for JavaBeans,
47 * the <code>DefaultPersistenceDelegate</code> provides a convenient means
48 * to effect persistent storage for classes that have a constructor
49 * that, while not nullary, simply requires some property values
165 }
166 }
167 return new Expression(oldInstance, oldInstance.getClass(), "new", constructorArgs);
168 }
169
170 private Method findMethod(Class type, String property) {
171 if (property == null) {
172 throw new IllegalArgumentException("Property name is null");
173 }
174 PropertyDescriptor pd = getPropertyDescriptor(type, property);
175 if (pd == null) {
176 throw new IllegalStateException("Could not find property by the name " + property);
177 }
178 Method method = pd.getReadMethod();
179 if (method == null) {
180 throw new IllegalStateException("Could not find getter for the property " + property);
181 }
182 return method;
183 }
184
185 private void doProperty(Class type, PropertyDescriptor pd, Object oldInstance, Object newInstance, Encoder out) throws Exception {
186 Method getter = pd.getReadMethod();
187 Method setter = pd.getWriteMethod();
188
189 if (getter != null && setter != null) {
190 Expression oldGetExp = new Expression(oldInstance, getter.getName(), new Object[]{});
191 Expression newGetExp = new Expression(newInstance, getter.getName(), new Object[]{});
192 Object oldValue = oldGetExp.getValue();
193 Object newValue = newGetExp.getValue();
194 out.writeExpression(oldGetExp);
195 if (!Objects.equals(newValue, out.get(oldValue))) {
196 // Search for a static constant with this value;
197 Object e = (Object[])pd.getValue("enumerationValues");
198 if (e instanceof Object[] && Array.getLength(e) % 3 == 0) {
199 Object[] a = (Object[])e;
200 for(int i = 0; i < a.length; i = i + 3) {
201 try {
202 Field f = type.getField((String)a[i]);
203 if (f.get(null).equals(oldValue)) {
204 out.remove(oldValue);
205 out.writeExpression(new Expression(oldValue, f, "get", new Object[]{null}));
206 }
207 }
208 catch (Exception ex) {}
209 }
210 }
211 invokeStatement(oldInstance, setter.getName(), new Object[]{oldValue}, out);
212 }
213 }
214 }
215
216 static void invokeStatement(Object instance, String methodName, Object[] args, Encoder out) {
217 out.writeStatement(new Statement(instance, methodName, args));
218 }
219
220 // Write out the properties of this instance.
221 private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) {
222 for (Field field : type.getFields()) {
223 int mod = field.getModifiers();
224 if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
225 continue;
226 }
227 try {
228 Expression oldGetExp = new Expression(field, "get", new Object[] { oldInstance });
229 Expression newGetExp = new Expression(field, "get", new Object[] { newInstance });
230 Object oldValue = oldGetExp.getValue();
231 Object newValue = newGetExp.getValue();
232 out.writeExpression(oldGetExp);
233 if (!Objects.equals(newValue, out.get(oldValue))) {
234 out.writeStatement(new Statement(field, "set", new Object[] { oldInstance, oldValue }));
235 }
236 }
237 catch (Exception exception) {
238 out.getExceptionListener().exceptionThrown(exception);
239 }
240 }
241 BeanInfo info;
242 try {
243 info = Introspector.getBeanInfo(type);
244 } catch (IntrospectionException exception) {
245 return;
246 }
247 // Properties
248 for (PropertyDescriptor d : info.getPropertyDescriptors()) {
249 if (d.isTransient()) {
250 continue;
251 }
252 try {
253 doProperty(type, d, oldInstance, newInstance, out);
|