Source Code Cross Referenced for FieldHandlerImpl.java in  » Database-ORM » castor » org » exolab » castor » mapping » loader » 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 » Database ORM » castor » org.exolab.castor.mapping.loader 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Redistribution and use of this software and associated documentation
003:         * ("Software"), with or without modification, are permitted provided
004:         * that the following conditions are met:
005:         *
006:         * 1. Redistributions of source code must retain copyright
007:         *    statements and notices.  Redistributions must also contain a
008:         *    copy of this document.
009:         *
010:         * 2. Redistributions in binary form must reproduce the
011:         *    above copyright notice, this list of conditions and the
012:         *    following disclaimer in the documentation and/or other
013:         *    materials provided with the distribution.
014:         *
015:         * 3. The name "Exolab" must not be used to endorse or promote
016:         *    products derived from this Software without prior written
017:         *    permission of Intalio, Inc.  For written permission,
018:         *    please contact info@exolab.org.
019:         *
020:         * 4. Products derived from this Software may not be called "Exolab"
021:         *    nor may "Exolab" appear in their names without prior written
022:         *    permission of Intalio, Inc. Exolab is a registered
023:         *    trademark of Intalio, Inc.
024:         *
025:         * 5. Due credit should be given to the Exolab Project
026:         *    (http://www.exolab.org/).
027:         *
028:         * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029:         * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030:         * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031:         * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
032:         * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033:         * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034:         * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035:         * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036:         * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037:         * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039:         * OF THE POSSIBILITY OF SUCH DAMAGE.
040:         *
041:         * Copyright 1999-2003 (C) Intalio, Inc. All Rights Reserved.
042:         *
043:         * $Id: FieldHandlerImpl.java 6457 2006-11-29 08:21:59Z wguttmn $
044:         */package org.exolab.castor.mapping.loader;
045:
046:        import java.lang.reflect.Array;
047:        import java.lang.reflect.Field;
048:        import java.lang.reflect.Method;
049:        import java.lang.reflect.Modifier;
050:        import java.lang.reflect.InvocationTargetException;
051:        import java.util.Enumeration;
052:        import java.util.Iterator;
053:
054:        import org.castor.util.Messages;
055:        import org.exolab.castor.core.exceptions.CastorIllegalStateException;
056:        import org.exolab.castor.mapping.AbstractFieldHandler;
057:        import org.exolab.castor.mapping.ExtendedFieldHandler;
058:        import org.exolab.castor.mapping.FieldHandler;
059:        import org.exolab.castor.mapping.TypeConvertor;
060:        import org.exolab.castor.mapping.CollectionHandler;
061:        import org.exolab.castor.mapping.MappingException;
062:        import org.exolab.castor.mapping.MappingRuntimeException;
063:        import org.exolab.castor.util.IteratorEnumeration;
064:
065:        /**
066:         * A field handler that knows how to get/set the values of a field
067:         * directly or through the get/set methods. Uses reflection.
068:         * <p>
069:         * Note: the field Java type is obtained from {@link TypeInfo#getFieldType()},
070:         * but if the field is a collection, the actual field/accessor type is
071:         * obtained from {@link TypeInfo#getCollectionHandler} and the object to create
072:         * (with {@link #newInstance(Object)}) is the former field type.
073:         *
074:         * @author <a href="arkin@intalio.com">Assaf Arkin</a>
075:         * @version $Revision: 6457 $ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
076:         */
077:        public final class FieldHandlerImpl extends AbstractFieldHandler {
078:            /**
079:             * The prefix for an "add" method
080:             **/
081:            private static final String ADD_PREFIX = "add";
082:
083:            /**
084:             * The prefix for an "enum" method
085:             */
086:            private static final String ENUM_PREFIX = "enum";
087:
088:            /**
089:             * The prefix for an "iter" method
090:             */
091:            private static final String ITER_PREFIX = "iter";
092:
093:            /**
094:             * The underlying field handler used by this handler.
095:             */
096:            private final FieldHandler _handler;
097:
098:            /**
099:             * The Java field described and accessed through this descriptor.
100:             */
101:            private final Field _field;
102:
103:            /**
104:             * The sequence of methods used to obtain the nested field. May be null.
105:             */
106:            private Method[] _getSequence;
107:
108:            /**
109:             * The sequence of methods used to create the nested object. May be null.
110:             */
111:            private Method[] _setSequence;
112:
113:            /** 
114:             * The method used to "incrementally" set the value of this field.  
115:             * This is only used if the field is a collection 
116:             */
117:            private Method _addMethod;
118:
119:            /**
120:             * The method used to enumerate entries of a container.
121:             */
122:            private Method _enumMethod;
123:
124:            /**
125:             * The method used to iterate over a container.
126:             */
127:            private Method _iterMethod;
128:
129:            /**
130:             * The method used to obtain the value of this field. May be null.
131:             */
132:            private Method _getMethod;
133:
134:            /**
135:             * The method used to set the value of this field. May be null.
136:             */
137:            private Method _setMethod;
138:
139:            /**
140:             * The method used to check if the value of this field exists. May be null.
141:             */
142:            private Method _hasMethod;
143:
144:            /**
145:             * The method used to delete the value of this field. May be null.
146:             */
147:            private Method _deleteMethod;
148:
149:            /**
150:             * The method used to create a new instance of the field.
151:             */
152:            private Method _createMethod;
153:
154:            /**
155:             * The Java field name.
156:             */
157:            private final String _fieldName;
158:
159:            /**
160:             * The Java field type.
161:             */
162:            private final Class _fieldType;
163:
164:            /**
165:             * True if this field is an immutable type.
166:             */
167:            private final boolean _immutable;
168:
169:            /**
170:             * The default value for primitive fields. Will be set if the field is null.
171:             */
172:            private final Object _default;
173:
174:            /**
175:             * Convertor to apply when setting the value of the field. Converts from
176:             * the value to the field type. Null if no convertor is required.
177:             */
178:            private TypeConvertor _convertTo = null;
179:
180:            /**
181:             * Convertor to apply when reading the value of the field. Converts from
182:             * the field type to the return value. Null if no convertor is required.
183:             */
184:            private TypeConvertor _convertFrom = null;
185:
186:            /**
187:             * Parameter for the type convertor. Null if no convertor is required
188:             * or on parameter is specified.
189:             */
190:            private final String _convertParam;
191:
192:            /**
193:             * The collection handler for multi valued fields.
194:             */
195:            private final CollectionHandler _colHandler;
196:
197:            /**
198:             * Construct a new field handler for the specified field. The field must
199:             * be public, and may not be static or transient. The field name is
200:             * determined from the Java field, the type from the type information.
201:             *
202:             * @param handler
203:             * @param typeInfo Type information
204:             */
205:            public FieldHandlerImpl(FieldHandler handler, TypeInfo typeInfo) {
206:                _handler = handler;
207:                _field = null;
208:                _fieldName = handler.toString();
209:                _fieldType = Types.typeFromPrimitive(typeInfo.getFieldType());
210:                _immutable = typeInfo.isImmutable();
211:                _default = typeInfo.getDefaultValue();
212:                _convertTo = typeInfo.getConvertorTo();
213:                _convertFrom = typeInfo.getConvertorFrom();
214:                _convertParam = typeInfo.getConvertorParam();
215:                _colHandler = typeInfo.getCollectionHandler();
216:            }
217:
218:            /**
219:             * Construct a new field handler for the specified field. The field must
220:             * be public, and may not be static or transient. The field name is
221:             * determined from the Java field, the type from the type information.
222:             *
223:             * @param field The field being described
224:             * @param typeInfo Type information
225:             * @throws MappingException If the field is not public, is static or
226:             *    transient
227:             */
228:            public FieldHandlerImpl(Field field, TypeInfo typeInfo)
229:                    throws MappingException {
230:                if (field.getModifiers() != Modifier.PUBLIC
231:                        && field.getModifiers() != (Modifier.PUBLIC | Modifier.VOLATILE))
232:                    throw new MappingException("mapping.fieldNotAccessible",
233:                            field.getName(), field.getDeclaringClass()
234:                                    .getName());
235:                _handler = null;
236:                _field = field;
237:                _fieldType = Types.typeFromPrimitive(typeInfo.getFieldType());
238:                _fieldName = field.getName() + "(" + field.getType().getName()
239:                        + ")";
240:                _immutable = typeInfo.isImmutable();
241:                // If the field is of a primitive type or if it is required
242:                // we use the default value
243:                if (_field.getType().isPrimitive())
244:                    _default = typeInfo.getDefaultValue();
245:                else
246:                    _default = null;
247:                _convertTo = typeInfo.getConvertorTo();
248:                _convertFrom = typeInfo.getConvertorFrom();
249:                _convertParam = typeInfo.getConvertorParam();
250:                _colHandler = typeInfo.getCollectionHandler();
251:            }
252:
253:            /**
254:             * Construct a new field handler for the specified field that
255:             * is accessed through the accessor methods (get/set). The accessor
256:             * methods must be public and not static. The field name is
257:             * required for descriptive purposes. The field type must match
258:             * the return value of the get method and the single parameter of
259:             * the set method. Either get or set methods are optional.
260:             *
261:             * @param fieldName The field being described
262:             * @param getMethod The method used to retrieve the field value,
263:             *  must accept no parameters and have a return type castable to
264:             *  the field type
265:             * @param setMethod The method used to set the field value, must
266:             *  accept a single parameter that is castable to the field type
267:             * @param typeInfo Type information
268:             * @throws MappingException If the get or set method are not public,
269:             *   are static, or do not specify the proper types
270:             *
271:             */
272:            public FieldHandlerImpl(String fieldName, Method[] getSequence,
273:                    Method[] setSequence, Method getMethod, Method setMethod,
274:                    TypeInfo typeInfo) throws MappingException {
275:                _handler = null;
276:                _field = null;
277:                if (fieldName == null)
278:                    throw new IllegalArgumentException(
279:                            "Argument 'fieldName' is null");
280:
281:                // Originally commented out by Oleg....not sure why?
282:                // if ( getMethod == null && setMethod == null )
283:                //    throw new IllegalArgumentException( "Both arguments 'getMethod' and 'setMethod' are null" );
284:
285:                _getSequence = getSequence;
286:                _setSequence = setSequence;
287:
288:                if (setMethod != null) {
289:                    //-- might be an "add" method
290:                    if (setMethod.getName().startsWith(ADD_PREFIX)) {
291:                        Class pType = setMethod.getParameterTypes()[0];
292:                        if (pType != typeInfo.getFieldType())
293:                            setAddMethod(setMethod);
294:                        else
295:                            setWriteMethod(setMethod);
296:                    }
297:
298:                    //            for(Iterator iter = setMethods.iterator(); iter.hasNext(); ) {
299:                    //                Method method = (Method) iter.next();
300:                    //
301:                    //	            if (method.getName().startsWith(ADD_PREFIX)) {
302:                    //	                Class paraType = method.getParameterTypes()[0];
303:                    //
304:                    //	                if (paraType != typeInfo.getFieldType()) {
305:                    //	                    addMethods.add(method);
306:                    //	                    iter.remove();
307:                    //	                }
308:                    //	            }
309:                    //            }
310:                    else
311:                        setWriteMethod(setMethod);
312:                }
313:
314:                if (getMethod != null) {
315:                    // getMethod might be an enumeration or iteration.
316:                    if (getMethod.getName().startsWith(ENUM_PREFIX)) {
317:                        Class rType = getMethod.getReturnType();
318:
319:                        // Check if getMethod really returns an enumeration.
320:                        if (Enumeration.class.isAssignableFrom(rType))
321:                            setEnumMethod(getMethod);
322:                        else
323:                            // If getMethod does not return an enumeration, treat it as a normal getMethod.
324:                            setReadMethod(getMethod);
325:                    } else if (getMethod.getName().startsWith(ITER_PREFIX)) {
326:                        Class rType = getMethod.getReturnType();
327:
328:                        // Check if getMethod really returns an iterator.
329:                        if (Iterator.class.isAssignableFrom(rType))
330:                            setIterMethod(getMethod);
331:                        else
332:                            // If getMethod does not return an iterator, treat it as a normal getMethod.
333:                            setReadMethod(getMethod);
334:                    } else
335:                        setReadMethod(getMethod);
336:                }
337:
338:                _fieldType = Types.typeFromPrimitive(typeInfo.getFieldType());
339:                _fieldName = fieldName + "(" + _fieldType.getName() + ")";
340:                _immutable = typeInfo.isImmutable();
341:
342:                // If the field is of a primitive type or if it is required
343:                // we use the default value 
344:                if (setMethod != null
345:                        && setMethod.getParameterTypes()[0].isPrimitive())
346:                    _default = typeInfo.getDefaultValue();
347:                else
348:                    _default = null;
349:                _convertTo = typeInfo.getConvertorTo();
350:                _convertFrom = typeInfo.getConvertorFrom();
351:                _convertParam = typeInfo.getConvertorParam();
352:                _colHandler = typeInfo.getCollectionHandler();
353:            }
354:
355:            public TypeConvertor getConvertFrom() {
356:                return _convertFrom;
357:            }
358:
359:            public TypeConvertor getConvertTo() {
360:                return _convertTo;
361:            }
362:
363:            public String getConvertParam() {
364:                return _convertParam;
365:            }
366:
367:            public Object getValue(Object object) {
368:                Object value;
369:
370:                try {
371:                    // If field is accessed directly, get its value.  If not, we need to call
372:                    // its get method. It's possible to not have a way to access the field.
373:
374:                    if (_handler != null) {
375:                        value = _handler.getValue(object);
376:                    } else if (_field != null) {
377:                        value = _field.get(object);
378:                    } else if (_enumMethod != null) {
379:                        // If there is an enumeration method supplied, return the enumeration.
380:                        value = _enumMethod.invoke(object, (Object[]) null);
381:                    } else if (_iterMethod != null) {
382:                        // If there is an iterator method supplied, wrap it in an enumeration.
383:                        value = new IteratorEnumeration((Iterator) _iterMethod
384:                                .invoke(object, (Object[]) null));
385:                    } else if (_getMethod != null) {
386:                        if (_getSequence != null) {
387:                            for (int i = 0; i < _getSequence.length; i++) {
388:                                object = _getSequence[i].invoke(object,
389:                                        (Object[]) null);
390:                                if (object == null) {
391:                                    break;
392:                                }
393:                            }
394:                        }
395:
396:                        // Some of the objects in the sequence might be null, then the value is null.
397:                        // If field has 'has' method, false means field is null and do not attempt to
398:                        // call getValue. Otherwise, ????
399:                        if (object == null
400:                                || (_hasMethod != null && !((Boolean) _hasMethod
401:                                        .invoke(object, (Object[]) null))
402:                                        .booleanValue())) {
403:                            value = null;
404:                        } else {
405:                            value = _getMethod.invoke(object, (Object[]) null);
406:                        }
407:                    } else {
408:                        value = null;
409:                    }
410:                } catch (IllegalAccessException except) {
411:                    throw new CastorIllegalStateException(Messages.format(
412:                            "mapping.schemaChangeNoAccess", toString()), except);
413:                } catch (InvocationTargetException except) {
414:                    throw new CastorIllegalStateException(Messages.format(
415:                            "mapping.schemaChangeInvocation", toString(),
416:                            except), except);
417:                }
418:
419:                //-- If a collection, return an enumeration of it's values.
420:                //-- Only use collection handler, if there is no convertor or enum method.
421:                if (_colHandler != null && _enumMethod == null
422:                        && _iterMethod == null && _convertFrom == null) {
423:                    if (value == null) {
424:                        return new CollectionHandlers.EmptyEnumerator();
425:                    }
426:                    return _colHandler.elements(value);
427:                }
428:
429:                // If there is a convertor, apply it
430:                if (_convertFrom == null || value == null) {
431:                    return value;
432:                }
433:
434:                try {
435:                    return _convertFrom.convert(value, _convertParam);
436:                } catch (ClassCastException except) {
437:                    throw new IllegalArgumentException(Messages.format(
438:                            "mapping.wrongConvertor", value.getClass()
439:                                    .getName()));
440:                }
441:            }
442:
443:            public void setValue(Object object, Object value) {
444:                if (_colHandler == null || _addMethod != null) {
445:
446:                    // If there is a convertor, apply conversion here.
447:                    if (value != null && _convertTo != null) {
448:                        try {
449:                            value = _convertTo.convert(value, _convertParam);
450:                        } catch (ClassCastException except) {
451:                            throw new IllegalArgumentException(Messages.format(
452:                                    "mapping.wrongConvertor", value.getClass()
453:                                            .getName()));
454:                        }
455:                    } else {
456:                        //-- unwrap MapItem if necessary
457:                        //if (_colHandler != null) {
458:                        //    if ((value instanceof MapItem) && (_fieldType != MapItem.class))
459:                        //    {
460:                        //        value = ((MapItem)value).getValue();
461:                        //    }
462:                        //}
463:                    }
464:
465:                    try {
466:                        if (_handler != null)
467:                            _handler.setValue(object, value);
468:                        else if (_field != null)
469:                            _field
470:                                    .set(object, value == null ? _default
471:                                            : value);
472:                        else {
473:
474:                            //-- either add or set
475:                            Method setter = selectWriteMethod(value);
476:
477:                            if (setter != null) {
478:                                if (_getSequence != null)
479:                                    for (int i = 0; i < _getSequence.length; i++) {
480:                                        Object last;
481:
482:                                        last = object;
483:                                        object = _getSequence[i].invoke(object,
484:                                                (Object[]) null);
485:                                        if (object == null) {
486:                                            // if the value is not null, we must instantiate
487:                                            // the object in the sequence
488:                                            if (value == null
489:                                                    || _setSequence[i] == null)
490:                                                break;
491:                                            object = Types
492:                                                    .newInstance(_getSequence[i]
493:                                                            .getReturnType());
494:                                            _setSequence[i].invoke(last,
495:                                                    new Object[] { object });
496:                                        }
497:                                    }
498:                                if (object != null) {
499:                                    if (value == null && _deleteMethod != null)
500:                                        _deleteMethod.invoke(object,
501:                                                (Object[]) null);
502:                                    else
503:                                        setter
504:                                                .invoke(
505:                                                        object,
506:                                                        new Object[] { value == null ? _default
507:                                                                : value });
508:                                }
509:                            }
510:                        }
511:                        // If the field has no set method, ignore it.
512:                        // If this is a problem, identity it someplace else.
513:                    } catch (IllegalArgumentException except) {
514:                        // Graceful way of dealing with unwrapping exception
515:                        if (value == null)
516:                            throw new IllegalArgumentException(Messages.format(
517:                                    "mapping.typeConversionNull", toString()));
518:                        throw new IllegalArgumentException(Messages.format(
519:                                "mapping.typeConversion", toString(), value
520:                                        .getClass().getName()));
521:                    } catch (IllegalAccessException except) {
522:                        // This should never happen
523:                        throw new CastorIllegalStateException(Messages.format(
524:                                "mapping.schemaChangeNoAccess", toString()),
525:                                except);
526:                    } catch (InvocationTargetException except) {
527:                        // This should never happen
528:                        throw new MappingRuntimeException(except
529:                                .getTargetException());
530:                    }
531:
532:                } else if (value != null) {
533:                    Object collect;
534:                    try {
535:                        // Get the field value (the collection), add the value to it,
536:                        // possibly yielding a new collection (in the case of an array),
537:                        // and set that collection back into the field.
538:                        if (_handler != null) {
539:                            collect = _handler.getValue(object);
540:                            collect = _colHandler.add(collect, value);
541:                            if (collect != null)
542:                                _handler.setValue(object, collect);
543:                        } else if (_field != null) {
544:                            collect = _field.get(object);
545:                            if (collect == null) {
546:                                // The type of the collection.
547:                                Class type = _field.getType();
548:                                //-- Handle Arrays, we need to declare the array with
549:                                //-- the correct type. The other cases are handled in  
550:                                //-- the J1CollectionHandler during the 
551:                                //-- add(collect,value) call
552:                                if (type.isArray()) {
553:                                    Class componentType = type
554:                                            .getComponentType();
555:                                    Class valueType = value.getClass();
556:                                    if (componentType.isPrimitive()
557:                                            || ((!valueType.isArray()) && (valueType != componentType))) {
558:                                        try {
559:                                            collect = Array.newInstance(
560:                                                    componentType, 0);
561:                                        } catch (Exception e) {
562:                                            String err = "Unable to instantiate an array of '"
563:                                                    + componentType
564:                                                    + "' : "
565:                                                    + e;
566:                                            throw new CastorIllegalStateException(
567:                                                    err, e);
568:                                        }
569:                                    }
570:                                }
571:                            }
572:                            collect = _colHandler.add(collect, value);
573:                            if (collect != null)
574:                                _field.set(object, collect);
575:
576:                        } else if (_getMethod != null) {
577:                            if (_getSequence != null)
578:                                for (int i = 0; i < _getSequence.length; i++)
579:                                    object = _getSequence[i].invoke(object,
580:                                            (Object[]) null);
581:                            collect = _getMethod
582:                                    .invoke(object, (Object[]) null);
583:
584:                            // If we deal with a collection who is an array of primitive
585:                            // and that has not been instantiated, we have to handle the
586:                            // instantiation here rather than in J1CollectionHandler,
587:                            // because we have acces to the Field object here.
588:                            boolean setCollection = false;
589:                            if (collect == null) {
590:                                // The return type of the get method should be the type of the collection.
591:                                Class type = _getMethod.getReturnType();
592:
593:                                //-- Handle Arrays, we need to declare the array with
594:                                //-- the correct type. The other cases are handled in  
595:                                //-- the J1CollectionHandler during the 
596:                                //-- add(collect,value) call
597:                                if (type.isArray()) {
598:                                    Class componentType = type
599:                                            .getComponentType();
600:                                    Class valueType = value.getClass();
601:                                    if (componentType.isPrimitive()
602:                                            || ((!valueType.isArray()) && (valueType != componentType))) {
603:                                        try {
604:                                            collect = Array.newInstance(
605:                                                    componentType, 0);
606:                                        } catch (Exception e) {
607:                                            String err = "Unable to instantiate an array of '"
608:                                                    + componentType
609:                                                    + "' : "
610:                                                    + e;
611:                                            throw new CastorIllegalStateException(
612:                                                    err, e);
613:                                        }
614:                                    }
615:                                }
616:                                setCollection = true;
617:                            } else {
618:                                setCollection = collect.getClass().isArray();
619:                            }
620:
621:                            Object tmp = _colHandler.add(collect, value);
622:
623:                            //-- make sure we do not overwrite collect unless
624:                            //-- the new collection is not null
625:                            if (tmp != null)
626:                                collect = tmp;
627:
628:                            if (setCollection && (_setMethod != null))
629:                                _setMethod.invoke(object,
630:                                        new Object[] { collect });
631:                        }
632:                    } catch (IllegalAccessException except) {
633:                        // This should never happen
634:                        throw new IllegalStateException(Messages.format(
635:                                "mapping.schemaChangeNoAccess", toString()));
636:                    } catch (InvocationTargetException except) {
637:                        // This should never happen
638:                        throw new MappingRuntimeException(except
639:                                .getTargetException());
640:                    }
641:                }
642:            }
643:
644:            public void resetValue(Object object) {
645:                if (_colHandler == null) {
646:
647:                    try {
648:                        if (_handler != null)
649:                            _handler.resetValue(object);
650:                        else if (_field != null)
651:                            _field.set(object, _default);
652:                        else if (_setMethod != null) {
653:                            if (_getSequence != null)
654:                                for (int i = 0; i < _getSequence.length; i++) {
655:                                    object = _getSequence[i].invoke(object,
656:                                            (Object[]) null);
657:                                    if (object == null)
658:                                        break;
659:                                }
660:                            if (object != null) {
661:                                if (_deleteMethod != null)
662:                                    _deleteMethod.invoke(object,
663:                                            (Object[]) null);
664:                                else
665:                                    _setMethod.invoke(object,
666:                                            new Object[] { _default });
667:                            }
668:                        }
669:                        // If the field has no set method, ignore it.
670:                        // If this is a problem, identity it someplace else.
671:                    } catch (IllegalArgumentException except) {
672:                        // Graceful way of dealing with unwrapping exception
673:                        throw new IllegalArgumentException(Messages.format(
674:                                "mapping.typeConversionNull", toString()));
675:                    } catch (IllegalAccessException except) {
676:                        // This should never happen
677:                        throw new IllegalStateException(Messages.format(
678:                                "mapping.schemaChangeNoAccess", toString()));
679:                    } catch (InvocationTargetException except) {
680:                        // This should never happen
681:                        throw new MappingRuntimeException(except
682:                                .getTargetException());
683:                    }
684:
685:                } else {
686:                    Object collect;
687:
688:                    try {
689:                        // Get the field value (the collection), add the value to it,
690:                        // possibly yielding a new collection (in the case of an array),
691:                        // and set that collection back into the field.
692:                        if (_handler != null) {
693:                            _handler.resetValue(object);
694:                        } else if (_field != null) {
695:                            collect = _field.get(object);
696:                            collect = _colHandler.clear(collect);
697:                            if (collect != null)
698:                                _field.set(object, collect);
699:                        } else if (_getMethod != null) {
700:                            if (_getSequence != null)
701:                                for (int i = 0; i < _getSequence.length; i++)
702:                                    object = _getSequence[i].invoke(object,
703:                                            (Object[]) null);
704:                            collect = _getMethod
705:                                    .invoke(object, (Object[]) null);
706:                            collect = _colHandler.clear(collect);
707:                            if (collect != null && _setMethod != null)
708:                                _setMethod.invoke(object,
709:                                        new Object[] { collect });
710:                        }
711:                    } catch (IllegalAccessException except) {
712:                        // This should never happen
713:                        throw new IllegalStateException(Messages.format(
714:                                "mapping.schemaChangeNoAccess", toString()));
715:                    } catch (InvocationTargetException except) {
716:                        // This should never happen
717:                        throw new MappingRuntimeException(except
718:                                .getTargetException());
719:                    }
720:
721:                }
722:            }
723:
724:            /**
725:             * Creates a new instance of the object described by this field.
726:             *
727:             * @param parent The object for which the field is created
728:             * @return A new instance of the field's value
729:             * @throws IllegalStateException This field is a simple type and
730:             *  cannot be instantiated
731:             */
732:            public Object newInstance(Object parent)
733:                    throws IllegalStateException {
734:                return newInstance(parent, null);
735:            }
736:
737:            /**
738:             * Creates a new instance of the object described by this field.
739:             *
740:             * @param parent The object for which the field is created
741:             * @param args the set of constructor arguments
742:             * @return A new instance of the field's value
743:             * @throws IllegalStateException This field is a simple type and
744:             *  cannot be instantiated
745:             */
746:            public Object newInstance(Object parent, Object[] args)
747:                    throws IllegalStateException {
748:                if (_fieldType.isInterface() && _createMethod == null)
749:                    return null;
750:
751:                if ((_immutable) && ((args == null) || (args.length == 0)))
752:                    throw new IllegalStateException(Messages.format(
753:                            "mapping.classNotConstructable", _fieldType));
754:
755:                if (_handler != null) {
756:                    if (_handler instanceof  ExtendedFieldHandler)
757:                        return ((ExtendedFieldHandler) _handler).newInstance(
758:                                parent, args);
759:                    return _handler.newInstance(parent);
760:                }
761:                // If we have a create method and parent object, call the create method.
762:                if (_createMethod != null && parent != null) {
763:                    try {
764:                        return _createMethod.invoke(parent, args);
765:                    } catch (IllegalAccessException except) {
766:                        // This should never happen
767:                        throw new IllegalStateException(Messages.format(
768:                                "mapping.schemaChangeNoAccess", toString()));
769:                    } catch (InvocationTargetException except) {
770:                        // This should never happen
771:                        throw new MappingRuntimeException(except
772:                                .getTargetException());
773:                    }
774:                }
775:                return Types.newInstance(_fieldType, args);
776:            } //-- newInstance
777:
778:            /**
779:             * Mutator method used by {@link AbstractMappingLoader}.
780:             */
781:            void setRequired(final boolean required) {
782:            }
783:
784:            /**
785:             * Sets the TypeConvertor used during calls to getValue
786:             *
787:             * @param convertor the TypeConvertor to use during calls
788:             * to getValue
789:             **/
790:            public void setConvertFrom(TypeConvertor convertor) {
791:                _convertFrom = convertor;
792:            } //-- setConvertFrom
793:
794:            /**
795:             * Sets the TypeConvertor used during calls to setValue
796:             *
797:             * @param convertor the TypeConvertor to use during calls
798:             * to setValue
799:             **/
800:            public void setConvertTo(TypeConvertor convertor) {
801:                _convertTo = convertor;
802:            } //-- setConvertTo
803:
804:            /**
805:             * Mutator method used by {@link AbstractMappingLoader} and
806:             * {@link org.exolab.castor.xml.Introspector}.
807:             * Please understand how this method is used before you start
808:             * playing with it! :-)
809:             */
810:            public void setCreateMethod(Method method) throws MappingException {
811:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
812:                        || (method.getModifiers() & Modifier.STATIC) != 0)
813:                    throw new MappingException("mapping.accessorNotAccessible",
814:                            method, method.getDeclaringClass().getName());
815:                if (method.getParameterTypes().length != 0)
816:                    throw new MappingException("mapping.createMethodNoParam",
817:                            method, method.getDeclaringClass().getName());
818:                _createMethod = method;
819:            }
820:
821:            /**
822:             * Mutator method used by {@link AbstractMappingLoader} and
823:             * {@link org.exolab.castor.xml.Introspector}.
824:             * Please understand how this method is used before you start
825:             * playing with it! :-)
826:             */
827:            public void setHasDeleteMethod(Method hasMethod, Method deleteMethod)
828:                    throws MappingException {
829:                if (hasMethod != null) {
830:                    if ((hasMethod.getModifiers() & Modifier.PUBLIC) == 0
831:                            || (hasMethod.getModifiers() & Modifier.STATIC) != 0)
832:                        throw new MappingException(
833:                                "mapping.accessorNotAccessible", hasMethod,
834:                                hasMethod.getDeclaringClass().getName());
835:                    if (hasMethod.getParameterTypes().length != 0)
836:                        throw new MappingException(
837:                                "mapping.createMethodNoParam", hasMethod,
838:                                hasMethod.getDeclaringClass().getName());
839:                    _hasMethod = hasMethod;
840:                }
841:
842:                if (deleteMethod != null) {
843:                    if ((deleteMethod.getModifiers() & Modifier.PUBLIC) == 0
844:                            || (deleteMethod.getModifiers() & Modifier.STATIC) != 0)
845:                        throw new MappingException(
846:                                "mapping.accessorNotAccessible", deleteMethod,
847:                                deleteMethod.getDeclaringClass().getName());
848:                    if (deleteMethod.getParameterTypes().length != 0)
849:                        throw new MappingException(
850:                                "mapping.createMethodNoParam", deleteMethod,
851:                                deleteMethod.getDeclaringClass().getName());
852:                    _deleteMethod = deleteMethod;
853:                }
854:            }
855:
856:            /**
857:             * Mutator method used by {@link org.exolab.castor.xml.Introspector}.
858:             * Please understand how this method is used before you start
859:             * playing with it! :-)
860:             */
861:            public void setReadMethod(Method method) throws MappingException {
862:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
863:                        || (method.getModifiers() & Modifier.STATIC) != 0)
864:                    throw new MappingException("mapping.accessorNotAccessible",
865:                            method, method.getDeclaringClass().getName());
866:                if (method.getParameterTypes().length != 0)
867:                    throw new MappingException("mapping.readMethodHasParam",
868:                            method, method.getDeclaringClass().getName());
869:                _getMethod = method;
870:            }
871:
872:            /**
873:             * Mutator method used by {@link org.exolab.castor.xml.Introspector}.
874:             * Please understand how this method is used before you start
875:             * playing with it! :-)
876:             */
877:            public void setWriteMethod(Method method) throws MappingException {
878:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
879:                        || (method.getModifiers() & Modifier.STATIC) != 0)
880:                    throw new MappingException("mapping.accessorNotAccessible",
881:                            method, method.getDeclaringClass().getName());
882:                if (method.getParameterTypes().length != 1)
883:                    throw new MappingException("mapping.writeMethodNoParam",
884:                            method, method.getDeclaringClass().getName());
885:                _setMethod = method;
886:            }
887:
888:            /**
889:             * Mutator method used by {@link org.exolab.castor.xml.Introspector}.
890:             * Please understand how this method is used before you start
891:             * playing with it! :-)
892:             */
893:            public void setAddMethod(Method method) throws MappingException {
894:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
895:                        || (method.getModifiers() & Modifier.STATIC) != 0)
896:                    throw new MappingException("mapping.accessorNotAccessible",
897:                            method, method.getDeclaringClass().getName());
898:                if (method.getParameterTypes().length != 1)
899:                    throw new MappingException("mapping.writeMethodNoParam",
900:                            method, method.getDeclaringClass().getName());
901:                _addMethod = method;
902:
903:                //-- make sure add method is not the same as the set method
904:                if (_addMethod == _setMethod)
905:                    _setMethod = null;
906:
907:            } //-- setAddMethod
908:
909:            /**
910:             * Sets the enumeration method.
911:             */
912:            public void setEnumMethod(Method method) throws MappingException {
913:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
914:                        || (method.getModifiers() & Modifier.STATIC) != 0)
915:                    throw new MappingException("mapping.accessorNotAccessible",
916:                            method, method.getDeclaringClass().getName());
917:                if (method.getParameterTypes().length != 0)
918:                    throw new MappingException("mapping.readMethodHasParam",
919:                            method, method.getDeclaringClass().getName());
920:
921:                _enumMethod = method;
922:            }
923:
924:            /**
925:             * Sets the iteration method.
926:             */
927:            public void setIterMethod(Method method) throws MappingException {
928:                if ((method.getModifiers() & Modifier.PUBLIC) == 0
929:                        || (method.getModifiers() & Modifier.STATIC) != 0)
930:                    throw new MappingException("mapping.accessorNotAccessible",
931:                            method, method.getDeclaringClass().getName());
932:                if (method.getParameterTypes().length != 0)
933:                    throw new MappingException("mapping.readMethodHasParam",
934:                            method, method.getDeclaringClass().getName());
935:
936:                _iterMethod = method;
937:            }
938:
939:            /** 
940:             * Selects the appropriate "write" method based on the 
941:             * value. This is used when there is an "add" method 
942:             * and a "set" method. 
943:             * 
944:             * @return the selected write method 
945:             **/
946:            private Method selectWriteMethod(Object value) {
947:                if (_setMethod != null) {
948:
949:                    if (_addMethod == null)
950:                        return _setMethod;
951:
952:                    if (value == null) {
953:                        if (_default != null)
954:                            value = _default;
955:                        else
956:                            return _setMethod;
957:                    }
958:
959:                    //-- check value's class type 
960:                    Class paramType = _setMethod.getParameterTypes()[0];
961:
962:                    if (paramType.isAssignableFrom(value.getClass()))
963:                        return _setMethod;
964:                }
965:
966:                return _addMethod;
967:
968:            } //-- selectWriteMethod 
969:
970:            /**
971:             * Return true if the field is a collection.
972:             */
973:            public boolean isCollection() {
974:                return (_colHandler != null);
975:            }
976:
977:            public String toString() {
978:                return _fieldName;
979:            }
980:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.