Source Code Cross Referenced for DefaultPersistenceDelegate.java in  » Apache-Harmony-Java-SE » java-package » java » beans » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » java package » java.beans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package java.beans;
019:
020:        import java.lang.reflect.Field;
021:        import java.lang.reflect.Method;
022:        import java.security.AccessController;
023:        import java.security.PrivilegedAction;
024:        import java.util.HashMap;
025:
026:        /**
027:         * Default PersistenceDelegate for normal classes. The instances of this class
028:         * are used when other customized PersistenceDelegate is not set in the encoders
029:         * for a particular type.
030:         * <p>
031:         * This PersistenceDelegate assumes that the bean to be made persistent has a
032:         * default constructor that takes no parameters or a constructor that takes some
033:         * properties as its parameters. Only the properties that can be got or set
034:         * based on the knowledge gained through an introspection will be made
035:         * persistent. In the case that a bean is constructed with some properties, the
036:         * value of these properties should be available via the conventional getter
037:         * method.
038:         * </p>
039:         * 
040:         * @see Encoder
041:         */
042:
043:        public class DefaultPersistenceDelegate extends PersistenceDelegate {
044:
045:            // shared empty property name array
046:            private static String[] EMPTY_PROPERTIES = new String[0];
047:
048:            // names of the properties accepted by the bean's constructor
049:            private String[] propertyNames = EMPTY_PROPERTIES;
050:
051:            /**
052:             * Constructs a <code>DefaultPersistenceDelegate</code> instance that
053:             * supports the persistence of a bean which has a default constructor.
054:             * 
055:             */
056:            public DefaultPersistenceDelegate() {
057:                // empty
058:            }
059:
060:            /**
061:             * Constructs a <code>DefaultPersistenceDelegate</code> instance that
062:             * supports the persistence of a bean which is constructed with some
063:             * properties.
064:             * 
065:             * @param propertyNames
066:             *            the name of the properties that are taken as parameters by the
067:             *            bean's constructor
068:             */
069:            public DefaultPersistenceDelegate(String[] propertyNames) {
070:                if (null != propertyNames) {
071:                    this .propertyNames = propertyNames;
072:                }
073:            }
074:
075:            /**
076:             * Initializes the new instance in the new environment so that it becomes
077:             * equivalent with the old one, meanwhile recording this process in the
078:             * encoder.
079:             * <p>
080:             * This is done by inspecting each property of the bean. The property value
081:             * from the old bean instance and the value from the new bean instance are
082:             * both retrieved and examined to see whether the latter mutates to the
083:             * former, and if not, issue a call to the write method to set the
084:             * equivalent value for the new instance. Exceptions occured during this
085:             * process are reported to the exception listener of the encoder.
086:             * </p>
087:             * 
088:             * @param type
089:             *            the type of the bean
090:             * @param oldInstance
091:             *            the original bean object to be recorded
092:             * @param newInstance
093:             *            the simmulating new bean object to be initialized
094:             * @param enc
095:             *            the encoder to write the outputs to
096:             */
097:            @Override
098:            protected void initialize(Class<?> type, Object oldInstance,
099:                    Object newInstance, Encoder enc) {
100:                // Call the initialization of the super type
101:                super .initialize(type, oldInstance, newInstance, enc);
102:                // Continue only if initializing the "current" type
103:                if (type != oldInstance.getClass()) {
104:                    return;
105:                }
106:
107:                // Get all bean properties
108:                BeanInfo info = null;
109:                try {
110:                    info = Introspector.getBeanInfo(type);
111:                } catch (IntrospectionException ex) {
112:                    enc.getExceptionListener().exceptionThrown(ex);
113:                    return;
114:                }
115:                PropertyDescriptor[] pds = info.getPropertyDescriptors();
116:
117:                // Initialize each found non-transient property
118:                for (int i = 0; i < pds.length; i++) {
119:                    // Skip a property whose transient attribute is true
120:                    if (Boolean.TRUE.equals(pds[i].getValue("transient"))) { //$NON-NLS-1$
121:                        continue;
122:                    }
123:                    // Skip a property having no setter or getter
124:                    if (null == pds[i].getWriteMethod()
125:                            || null == pds[i].getReadMethod()) {
126:                        continue;
127:                    }
128:
129:                    // Get the value of the property in the old instance
130:                    Expression getterExp = new Expression(oldInstance, pds[i]
131:                            .getReadMethod().getName(), null);
132:                    try {
133:                        // Calculate the old value of the property
134:                        Object oldVal = getterExp.getValue();
135:                        // Write the getter expression to the encoder
136:                        enc.writeExpression(getterExp);
137:                        // Get the target value that exists in the new environment
138:                        Object targetVal = enc.get(oldVal);
139:                        // Get the current property value in the new environment
140:                        Object newVal = new Expression(newInstance, pds[i]
141:                                .getReadMethod().getName(), null).getValue();
142:                        /*
143:                         * Make the target value and current property value equivalent
144:                         * in the new environment
145:                         */
146:                        if (null == targetVal) {
147:                            if (null != newVal) {
148:                                // Set to null
149:                                Statement setterStm = new Statement(
150:                                        oldInstance, pds[i].getWriteMethod()
151:                                                .getName(),
152:                                        new Object[] { null });
153:                                enc.writeStatement(setterStm);
154:                            }
155:                        } else {
156:                            PersistenceDelegate pd = enc
157:                                    .getPersistenceDelegate(targetVal
158:                                            .getClass());
159:                            if (!pd.mutatesTo(targetVal, newVal)) {
160:                                Statement setterStm = new Statement(
161:                                        oldInstance, pds[i].getWriteMethod()
162:                                                .getName(),
163:                                        new Object[] { oldVal });
164:                                enc.writeStatement(setterStm);
165:                            }
166:                        }
167:                    } catch (Exception ex) {
168:                        enc.getExceptionListener().exceptionThrown(ex);
169:                    }
170:                }
171:            }
172:
173:            /*
174:             * Get the field value of an object using privileged code.
175:             */
176:            private Object getFieldValue(Object oldInstance, String fieldName)
177:                    throws NoSuchFieldException, IllegalAccessException {
178:                Class<? extends Object> c = oldInstance.getClass();
179:                final Field f = c.getDeclaredField(fieldName);
180:                AccessController.doPrivileged(new PrivilegedAction<Object>() {
181:                    public Object run() {
182:                        f.setAccessible(true);
183:                        return null;
184:                    }
185:                });
186:                return f.get(oldInstance);
187:            }
188:
189:            /*
190:             * Get the value for the specified property of the given bean instance.
191:             */
192:            private Object getPropertyValue(
193:                    HashMap<String, PropertyDescriptor> proDscMap,
194:                    Object oldInstance, String propName) throws Exception {
195:                // Try to get the read method for the property
196:                Method getter = null;
197:                if (null != proDscMap) {
198:                    PropertyDescriptor pd = proDscMap.get(Introspector
199:                            .decapitalize(propName));
200:                    if (null != pd) {
201:                        getter = pd.getReadMethod();
202:                    }
203:                }
204:
205:                // Invoke read method to get the value if found
206:                if (null != getter) {
207:                    return getter.invoke(oldInstance, (Object[]) null);
208:                }
209:
210:                // Otherwise, try to access the field directly
211:                try {
212:                    return getFieldValue(oldInstance, propName);
213:                } catch (Exception ex) {
214:                    // Fail, throw an exception
215:                    throw new NoSuchMethodException(
216:                            "The getter method for the property " //$NON-NLS-1$
217:                                    + propName + " can't be found."); //$NON-NLS-1$
218:                }
219:
220:            }
221:
222:            /**
223:             * Returns an expression that represents a call to the bean's constructor.
224:             * The constructor may take zero or more parameters, as specified when this
225:             * <code>DefaultPersistenceDelegate</code> is constructed.
226:             * 
227:             * @param oldInstance
228:             *            the old instance
229:             * @param enc
230:             *            the encoder that wants to record the old instance
231:             * @return an expression for instantiating an object of the same type as the
232:             *         old instance
233:             */
234:            @Override
235:            protected Expression instantiate(Object oldInstance, Encoder enc) {
236:                Object[] args = null;
237:
238:                // Set the constructor arguments if any property names exist
239:                if (this .propertyNames.length > 0) {
240:                    // Prepare the property descriptors for finding getter method later
241:                    BeanInfo info = null;
242:                    HashMap<String, PropertyDescriptor> proDscMap = null;
243:                    try {
244:                        info = Introspector.getBeanInfo(oldInstance.getClass(),
245:                                Introspector.IGNORE_ALL_BEANINFO);
246:                        proDscMap = internalAsMap(info.getPropertyDescriptors());
247:                    } catch (IntrospectionException ex) {
248:                        enc.getExceptionListener().exceptionThrown(ex);
249:                        throw new Error(ex);
250:                    }
251:
252:                    // Get the arguments values
253:                    args = new Object[this .propertyNames.length];
254:                    for (int i = 0; i < this .propertyNames.length; i++) {
255:                        String propertyName = propertyNames[i];
256:                        if (null == propertyName || 0 == propertyName.length()) {
257:                            continue;
258:                        }
259:
260:                        // Get the value for each property of the given instance
261:                        try {
262:                            args[i] = getPropertyValue(proDscMap, oldInstance,
263:                                    this .propertyNames[i]);
264:                        } catch (Exception ex) {
265:                            enc.getExceptionListener().exceptionThrown(ex);
266:                        }
267:                    }
268:                }
269:
270:                return new Expression(oldInstance, oldInstance.getClass(),
271:                        Statement.CONSTRUCTOR_NAME, args);
272:            }
273:
274:            private static HashMap<String, PropertyDescriptor> internalAsMap(
275:                    PropertyDescriptor[] propertyDescs) {
276:                HashMap<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
277:                for (int i = 0; i < propertyDescs.length; i++) {
278:                    map.put(propertyDescs[i].getName(), propertyDescs[i]);
279:                }
280:                return map;
281:            }
282:
283:            /**
284:             * Determines whether one object mutates to the other object. If this
285:             * <code>DefaultPersistenceDelegate</code> is constructed with one or more
286:             * property names, and the class of <code>o1</code> overrides the
287:             * "equals(Object)" method, then <code>o2</code> is considered to mutate
288:             * to <code>o1</code> if <code>o1</code> equals to <code>o2</code>.
289:             * Otherwise, the result is the same as the definition in
290:             * <code>PersistenceDelegate</code>.
291:             * 
292:             * @param o1
293:             *            one object
294:             * @param o2
295:             *            the other object
296:             * @return true if second object mutates to the first object, otherwise
297:             *         false
298:             */
299:            @Override
300:            protected boolean mutatesTo(Object o1, Object o2) {
301:                if (null == o1 || null == o2) {
302:                    return false;
303:                }
304:                Class<? extends Object> c = o1.getClass();
305:                if (this .propertyNames.length > 0) {
306:                    // Check the "equals" method has been declared
307:                    Method equalMethod = null;
308:                    try {
309:                        equalMethod = c.getDeclaredMethod("equals", //$NON-NLS-1$
310:                                new Class[] { Object.class });
311:                    } catch (NoSuchMethodException ex) {
312:                        // ignore
313:                    }
314:
315:                    if (null != equalMethod) {
316:                        return o1.equals(o2);
317:                    }
318:                }
319:
320:                return super.mutatesTo(o1, o2);
321:            }
322:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.