Source Code Cross Referenced for MethodProperty.java in  » Web-Framework » Millstone » org » millstone » base » data » util » 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 » Web Framework » Millstone » org.millstone.base.data.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *************************************************************************
002:         
003:                                        Millstone(TM) 
004:                           Open Sourced User Interface Library for
005:                               Internet Development with Java
006:
007:                     Millstone is a registered trademark of IT Mill Ltd
008:                          Copyright (C) 2000-2005 IT Mill Ltd
009:                             
010:         *************************************************************************
011:
012:           This library is free software; you can redistribute it and/or
013:           modify it under the terms of the GNU Lesser General Public
014:           license version 2.1 as published by the Free Software Foundation.
015:
016:           This library is distributed in the hope that it will be useful,
017:           but WITHOUT ANY WARRANTY; without even the implied warranty of
018:           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:           Lesser General Public License for more details.
020:
021:           You should have received a copy of the GNU Lesser General Public
022:           License along with this library; if not, write to the Free Software
023:           Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         *************************************************************************
026:           
027:           For more information, contact:
028:           
029:           IT Mill Ltd                           phone: +358 2 4802 7180
030:           Ruukinkatu 2-4                        fax:  +358 2 4802 7181
031:           20540, Turku                          email: info@itmill.com
032:           Finland                               company www: www.itmill.com
033:           
034:           Primary source for MillStone information and releases: www.millstone.org
035:
036:         ********************************************************************** */
037:
038:        package org.millstone.base.data.util;
039:
040:        import java.lang.reflect.InvocationTargetException;
041:        import java.lang.reflect.Method;
042:        import java.lang.reflect.Constructor;
043:        import java.util.LinkedList;
044:        import org.millstone.base.data.Property;
045:
046:        /** <p>Proxy class for creating Properties from pairs of getter and setter
047:         * methods of a Bean property. An instance of this class can be thought as
048:         * having been attached to a field of an object. Accessing the object
049:         * through the Property interface directly manipulates the underlying
050:         * field.</p>
051:         * 
052:         * <p>It's assumed that the return value returned by the getter method 
053:         * is assignable to the type of the property, and the setter method
054:         * parameter is assignable to that value.</p>
055:         * 
056:         * <p>A valid getter method must always be available, but instance of this
057:         * class can be constructed with a <code>null</code> setter method in which
058:         * case the resulting MethodProperty is read-only.</p>
059:         *
060:         * @author IT Mill Ltd.
061:         * @version 3.1.1
062:         * @since 3.0
063:         */
064:        public class MethodProperty implements  Property {
065:
066:            /** The object that includes the property the MethodProperty is bound to */
067:            private Object instance;
068:
069:            /** Argument arrays for the getter and setter methods */
070:            private Object[] setArgs, getArgs;
071:
072:            /** Is the MethodProperty read-only? */
073:            private boolean readOnly;
074:
075:            /** The getter and setter methods */
076:            private Method setMethod, getMethod;
077:
078:            /** Index of the new value in the argument list for the setter method.
079:             * If the setter method requires several parameters, this index tells
080:             * which one is the actual value to change.
081:             */
082:            private int setArgumentIndex;
083:
084:            /** Type of the property */
085:            private Class type;
086:
087:            /** List of listeners who are interested in the read-only status changes
088:             * of the MethodProperty
089:             */
090:            private LinkedList readOnlyStatusChangeListeners = null;
091:
092:            /** <p>Creates a new instance of MethodProperty from a named bean
093:             * property. This constructor takes an object and the name of a bean
094:             * property and initializes itself with the accessor methods for the
095:             * property. The getter method of a MethodProperty instantiated
096:             * with this constructor will be called with no arguments, and the
097:             * setter method with only the new value as the sole argument.</p>
098:             * 
099:             * <p>If the setter method is unavailable, the resulting MethodProperty
100:             * will be read-only, otherwise it will be read-write.</p>
101:             * 
102:             * <p>Method names are constucted from the bean property by adding
103:             * get/is/are/set prefix and capitalising the first character in the 
104:             * name of the given bean property</p>
105:             * 
106:             * @param instance object that includes the property
107:             * @param beanPropertyName name of the property to bind to
108:             */
109:            public MethodProperty(Object instance, String beanPropertyName) {
110:
111:                Class beanClass = instance.getClass();
112:
113:                // Assure that the first letter is upper cased (it is a common
114:                // mistake to write firstName, not FirstName).
115:                if (Character.isLowerCase(beanPropertyName.charAt(0))) {
116:                    char[] buf = beanPropertyName.toCharArray();
117:                    buf[0] = Character.toUpperCase(buf[0]);
118:                    beanPropertyName = new String(buf);
119:                }
120:
121:                // Find the get method
122:                getMethod = null;
123:                try {
124:                    getMethod = beanClass.getMethod("get" + beanPropertyName,
125:                            new Class[] {});
126:                } catch (java.lang.NoSuchMethodException ignored) {
127:                    try {
128:                        getMethod = beanClass.getMethod(
129:                                "is" + beanPropertyName, new Class[] {});
130:                    } catch (java.lang.NoSuchMethodException ignoredAsWell) {
131:                        try {
132:                            getMethod = beanClass.getMethod("are"
133:                                    + beanPropertyName, new Class[] {});
134:                        } catch (java.lang.NoSuchMethodException e) {
135:                            throw new MethodProperty.MethodException(
136:                                    "Bean property " + beanPropertyName
137:                                            + " can not be found");
138:                        }
139:                    }
140:                }
141:
142:                // In case the get method is found, resolve the type
143:                type = getMethod.getReturnType();
144:
145:                // Find the set method
146:                setMethod = null;
147:                try {
148:                    setMethod = beanClass.getMethod("set" + beanPropertyName,
149:                            new Class[] { type });
150:                } catch (java.lang.NoSuchMethodException skipped) {
151:                }
152:
153:                // Get the return type from get method
154:                if (type.isPrimitive()) {
155:                    if (type.equals(Boolean.TYPE))
156:                        type = Boolean.class;
157:                    else if (type.equals(Integer.TYPE))
158:                        type = Integer.class;
159:                    else if (type.equals(Float.TYPE))
160:                        type = Float.class;
161:                    else if (type.equals(Double.TYPE))
162:                        type = Double.class;
163:                    else if (type.equals(Byte.TYPE))
164:                        type = Byte.class;
165:                    else if (type.equals(Character.TYPE))
166:                        type = Character.class;
167:                    else if (type.equals(Short.TYPE))
168:                        type = Short.class;
169:                    else if (type.equals(Long.TYPE))
170:                        type = Long.class;
171:                }
172:
173:                setArguments(new Object[] {}, new Object[] { null }, 0);
174:                this .readOnly = (setMethod == null);
175:                this .instance = instance;
176:            }
177:
178:            /** <p>Creates a new instance of MethodProperty from named getter and
179:             * setter methods. The getter method of a MethodProperty instantiated
180:             * with this constructor will be called with no arguments, and the
181:             * setter method with only the new value as the sole argument.</p>
182:             *
183:             * <p>If the setter method is <code>null</code>, the resulting
184:             * MethodProperty will be read-only, otherwise it will be
185:             * read-write.</p>
186:             * 
187:             * @param type type of the property
188:             * @param instance object that includes the property
189:             * @param getMethodName name of the getter method
190:             * @param setMethodName name of the setter method
191:             *
192:             */
193:            public MethodProperty(Class type, Object instance,
194:                    String getMethodName, String setMethodName) {
195:                this (type, instance, getMethodName, setMethodName,
196:                        new Object[] {}, new Object[] { null }, 0);
197:            }
198:
199:            /** <p>Creates a new instance of MethodProperty with the getter and
200:             * setter methods. The getter method of a MethodProperty instantiated
201:             * with this constructor will be called with no arguments, and the
202:             * setter method with only the new value as the sole argument.</p>
203:             *
204:             * <p>If the setter method is <code>null</code>, the resulting
205:             * MethodProperty will be read-only, otherwise it will be
206:             * read-write.</p>
207:             *
208:             * @param type type of the property
209:             * @param instance object that includes the property
210:             * @param getMethod the getter method
211:             * @param setMethod the setter method
212:             */
213:            public MethodProperty(Class type, Object instance,
214:                    Method getMethod, Method setMethod) {
215:                this (type, instance, getMethod, setMethod, new Object[] {},
216:                        new Object[] { null }, 0);
217:            }
218:
219:            /** <p>Creates a new instance of MethodProperty from named getter and
220:             * setter methods and argument lists. The getter method of a
221:             * MethodProperty instantiated with this constructor will be called with
222:             * <code>getArgs</code> as arguments. <code>setArgs</code> will be used
223:             * as the arguments for the setter method, though the argument indexed
224:             * by <code>setArgumentIndex</code> will be replaced with the argument
225:             * passed to the {@link #setValue(Object newValue)} method.</p>
226:             * 
227:             * <p>For example, if the <code>setArgs</code> contains <code>A</code>,
228:             * <code>B</code> and <code>C</code>, and <code>setArgumentIndex =
229:             * 1</code>, the call <code>methodProperty.setValue(X)</code> would
230:             * result in the setter method to be called with the parameter set of
231:             * <code>{A, X, C}</code></p>
232:             *
233:             * @param type type of the property
234:             * @param instance object that includes the property
235:             * @param getMethodName the name of the getter method
236:             * @param setMethodName the name of the setter method
237:             * @param getArgs fixed argument list to be passed to the getter method
238:             * @param setArgs fixed argument list to be passed to the setter method
239:             * @param setArgumentIndex the index of the argument in
240:             * <code>setArgs</code> to be replaced with <code>newValue</code> when
241:             * {@link #setValue(Object newValue)} is called
242:             */
243:            public MethodProperty(Class type, Object instance,
244:                    String getMethodName, String setMethodName,
245:                    Object[] getArgs, Object[] setArgs, int setArgumentIndex) {
246:
247:                // Check the setargs and setargs index
248:                if (setMethodName != null && setArgs == null)
249:                    throw new IndexOutOfBoundsException(
250:                            "The setArgs can not be null");
251:                if (setMethodName != null
252:                        && (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length))
253:                    throw new IndexOutOfBoundsException(
254:                            "The setArgumentIndex must be >= 0 and < setArgs.length");
255:
256:                // Set type
257:                this .type = type;
258:
259:                // Find set and get -methods    
260:                Method[] m = instance.getClass().getMethods();
261:
262:                // Find get method
263:                boolean found = false;
264:                for (int i = 0; i < m.length; i++) {
265:
266:                    // Test the name of the get Method
267:                    if (!m[i].getName().equals(getMethodName)) {
268:
269:                        // name does not match, try next method
270:                        continue;
271:                    }
272:
273:                    // Test return type
274:                    if (!type.equals(m[i].getReturnType()))
275:                        continue;
276:
277:                    // Test the parameter types
278:                    Class[] c = m[i].getParameterTypes();
279:                    if (c.length != getArgs.length) {
280:
281:                        // not the right amount of parameters, try next method
282:                        continue;
283:                    }
284:                    int j = 0;
285:                    while (j < c.length) {
286:                        if (getArgs[j] != null
287:                                && !c[j]
288:                                        .isAssignableFrom(getArgs[j].getClass())) {
289:
290:                            // parameter type does not match, try next method
291:                            break;
292:                        }
293:                        j++;
294:                    }
295:                    if (j == c.length) {
296:
297:                        // all paramteters matched
298:                        if (found == true) {
299:                            throw new MethodProperty.MethodException(
300:                                    "Could not uniquely identify "
301:                                            + getMethodName + "-method");
302:                        } else {
303:                            found = true;
304:                            getMethod = m[i];
305:                        }
306:                    }
307:                }
308:                if (found != true) {
309:                    throw new MethodProperty.MethodException("Could not find "
310:                            + getMethodName + "-method");
311:                }
312:
313:                // Find set method
314:                if (setMethodName != null) {
315:
316:                    // Find setMethod
317:                    found = false;
318:                    for (int i = 0; i < m.length; i++) {
319:
320:                        // Check name
321:                        if (!m[i].getName().equals(setMethodName)) {
322:
323:                            // name does not match, try next method
324:                            continue;
325:                        }
326:
327:                        // Check parameter compatibility
328:                        Class[] c = m[i].getParameterTypes();
329:                        if (c.length != setArgs.length) {
330:
331:                            // not the right amount of parameters, try next method
332:                            continue;
333:                        }
334:                        int j = 0;
335:                        while (j < c.length) {
336:                            if (setArgs[j] != null
337:                                    && !c[j].isAssignableFrom(setArgs[j]
338:                                            .getClass())) {
339:
340:                                // parameter type does not match, try next method
341:                                break;
342:                            } else if (j == setArgumentIndex
343:                                    && !c[j].equals(type)) {
344:
345:                                // Property type is not the same as setArg type
346:                                break;
347:                            }
348:                            j++;
349:                        }
350:                        if (j == c.length) {
351:
352:                            // all parameters match
353:                            if (found == true) {
354:                                throw new MethodProperty.MethodException(
355:                                        "Could not identify unique "
356:                                                + setMethodName + "-method");
357:                            } else {
358:                                found = true;
359:                                setMethod = m[i];
360:                            }
361:                        }
362:                    }
363:                    if (found != true) {
364:                        throw new MethodProperty.MethodException(
365:                                "Could not identify " + setMethodName
366:                                        + "-method");
367:                    }
368:                }
369:
370:                // Get the return type from get method
371:                if (type.isPrimitive()) {
372:                    if (type.equals(Boolean.TYPE))
373:                        type = Boolean.class;
374:                    else if (type.equals(Integer.TYPE))
375:                        type = Integer.class;
376:                    else if (type.equals(Float.TYPE))
377:                        type = Float.class;
378:                    else if (type.equals(Double.TYPE))
379:                        type = Double.class;
380:                    else if (type.equals(Byte.TYPE))
381:                        type = Byte.class;
382:                    else if (type.equals(Character.TYPE))
383:                        type = Character.class;
384:                    else if (type.equals(Short.TYPE))
385:                        type = Short.class;
386:                    else if (type.equals(Long.TYPE))
387:                        type = Long.class;
388:                }
389:
390:                setArguments(getArgs, setArgs, setArgumentIndex);
391:                this .readOnly = (setMethod == null);
392:                this .instance = instance;
393:            }
394:
395:            /** <p>Creates a new instance of MethodProperty from the getter and
396:             * setter methods, and argument lists. This constructor behaves exctly
397:             * like {@link #MethodProperty(Class type, Object instance, String
398:             * getMethodName, String setMethodName, Object [] getArgs, Object []
399:             * setArgs, int setArgumentIndex)} except that instead of names of
400:             * the getter and setter methods this constructor is given the actual
401:             * methods themselves.</p>
402:             *
403:             * @param type type of the property
404:             * @param instance object that includes the property
405:             * @param getMethod the getter method
406:             * @param setMethod the setter method
407:             * @param getArgs fixed argument list to be passed to the getter method
408:             * @param setArgs fixed argument list to be passed to the setter method
409:             * @param setArgumentIndex the index of the argument in
410:             * <code>setArgs</code> to be replaced with <code>newValue</code> when
411:             * {@link #setValue(Object newValue)} is called
412:             */
413:            public MethodProperty(Class type, Object instance,
414:                    Method getMethod, Method setMethod, Object[] getArgs,
415:                    Object[] setArgs, int setArgumentIndex) {
416:
417:                if (getMethod == null) {
418:                    throw new MethodProperty.MethodException(
419:                            "Property GET-method cannot not be null: " + type);
420:                }
421:
422:                if (setMethod != null
423:                        && (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length))
424:                    throw new IndexOutOfBoundsException(
425:                            "The setArgumentIndex must be >= 0 and < setArgs.length");
426:
427:                // Get the return type from get method
428:                if (type.isPrimitive()) {
429:                    if (type.equals(Boolean.TYPE))
430:                        type = Boolean.class;
431:                    else if (type.equals(Integer.TYPE))
432:                        type = Integer.class;
433:                    else if (type.equals(Float.TYPE))
434:                        type = Float.class;
435:                    else if (type.equals(Double.TYPE))
436:                        type = Double.class;
437:                    else if (type.equals(Byte.TYPE))
438:                        type = Byte.class;
439:                    else if (type.equals(Character.TYPE))
440:                        type = Character.class;
441:                    else if (type.equals(Short.TYPE))
442:                        type = Short.class;
443:                    else if (type.equals(Long.TYPE))
444:                        type = Long.class;
445:                }
446:
447:                this .getMethod = getMethod;
448:                this .setMethod = setMethod;
449:                setArguments(getArgs, setArgs, setArgumentIndex);
450:                this .readOnly = (setMethod == null);
451:                this .instance = instance;
452:                this .type = type;
453:            }
454:
455:            /** Returns the type of the Property. The methods <code>getValue</code>
456:             * and <code>setValue</code> must be compatible with this type: one
457:             * must be able to safely cast the value returned from
458:             * <code>getValue</code> to the given type and pass any variable
459:             * assignable to this type as an argument to <code>setValue</code>.
460:             * 
461:             * @return type of the Property
462:             */
463:            public final Class getType() {
464:                return type;
465:            }
466:
467:            /** Tests if the object is in read-only mode. In read-only mode calls
468:             * to <code>setValue</code> will throw <code>ReadOnlyException</code>s
469:             * and will not modify the value of the Property.
470:             *
471:             * @return <code>true</code> if the object is in read-only mode,
472:             * <code>false</code> if it's not
473:             */
474:            public boolean isReadOnly() {
475:                return readOnly;
476:            }
477:
478:            /** Gets the value stored in the Property. The value is resolved by
479:             * calling the specified getter method with the argument specified
480:             * at instantiation.
481:             *  
482:             * @return the value of the Property
483:             */
484:            public Object getValue() {
485:                try {
486:                    return getMethod.invoke(instance, getArgs);
487:                } catch (Throwable e) {
488:                    throw new MethodProperty.MethodException(e);
489:                }
490:            }
491:
492:            /** Returns the value of the MethodProperty in human readable textual
493:             * format. The return value should be assignable to the
494:             * <code>setValue</code> method if the Property is not in read-only
495:             * mode.
496:             * 
497:             * @return String representation of the value stored in the Property
498:             */
499:            public String toString() {
500:                Object value = getValue();
501:                if (value == null)
502:                    return null;
503:                return value.toString();
504:            }
505:
506:            /** <p>Sets the setter method and getter method argument lists.</p>
507:             *
508:             * @param getArgs fixed argument list to be passed to the getter method
509:             * @param setArgs fixed argument list to be passed to the setter method
510:             * @param setArgumentIndex the index of the argument in
511:             * <code>setArgs</code> to be replaced with <code>newValue</code> when
512:             * {@link #setValue(Object newValue)} is called
513:             */
514:            public void setArguments(Object[] getArgs, Object[] setArgs,
515:                    int setArgumentIndex) {
516:                this .getArgs = new Object[getArgs.length];
517:                for (int i = 0; i < getArgs.length; i++)
518:                    this .getArgs[i] = getArgs[i];
519:                this .setArgs = new Object[setArgs.length];
520:                for (int i = 0; i < setArgs.length; i++)
521:                    this .setArgs[i] = setArgs[i];
522:                this .setArgumentIndex = setArgumentIndex;
523:            }
524:
525:            /** Set the value of the property. This method supports setting from
526:             * <code>String</code>s if either <code>String</code> is directly
527:             * assignable to property type, or the type class contains a string
528:             * constructor.
529:             *
530:             * @param newValue New value of the property.
531:             * @throws <code>Property.ReadOnlyException</code> if the object is in
532:             * read-only mode
533:             * @throws <code>Property.ConversionException</code> if
534:             * <code>newValue</code> can't be converted into the Property's native
535:             * type directly or through <code>String</code>
536:             */
537:            public void setValue(Object newValue)
538:                    throws Property.ReadOnlyException,
539:                    Property.ConversionException {
540:
541:                // Check the mode
542:                if (isReadOnly())
543:                    throw new Property.ReadOnlyException();
544:
545:                // Try to assign the compatible value directly
546:                if (newValue == null
547:                        || type.isAssignableFrom(newValue.getClass()))
548:                    invokeSetMethod(newValue);
549:
550:                // Otherwise try to convert the value trough string constructor
551:                else {
552:
553:                    Object value;
554:                    try {
555:
556:                        // Get the string constructor
557:                        Constructor constr = getType().getConstructor(
558:                                new Class[] { String.class });
559:
560:                        value = constr.newInstance(new Object[] { newValue
561:                                .toString() });
562:
563:                    } catch (java.lang.Exception e) {
564:                        throw new Property.ConversionException(e);
565:                    }
566:
567:                    // Create new object from the string
568:                    invokeSetMethod(value);
569:                }
570:            }
571:
572:            /** Internal method to actually call the setter method of the wrapped
573:             * property.
574:             */
575:            private void invokeSetMethod(Object value) {
576:
577:                try {
578:                    // Construct a temporary argument array only if needed
579:                    if (setArgs.length == 1)
580:                        setMethod.invoke(instance, new Object[] { value });
581:                    else {
582:
583:                        // Set the value to argument array
584:                        Object[] args = new Object[setArgs.length];
585:                        for (int i = 0; i < setArgs.length; i++)
586:                            args[i] = (i == setArgumentIndex) ? value
587:                                    : setArgs[i];
588:                        setMethod.invoke(instance, args);
589:                    }
590:                } catch (InvocationTargetException e) {
591:                    Throwable targetException = e.getTargetException();
592:                    throw new MethodProperty.MethodException(targetException);
593:                } catch (Exception e) {
594:                    throw new MethodProperty.MethodException(e);
595:                }
596:            }
597:
598:            /** Sets the Property's read-only mode to the specified status.
599:             * 
600:             * @param newStatus new read-only status of the Property
601:             */
602:            public void setReadOnly(boolean newStatus) {
603:                if (newStatus)
604:                    readOnly = true;
605:                else
606:                    readOnly = (setMethod == null);
607:            }
608:
609:            /** <code>Exception</code> object that signals that there were
610:             * problems calling or finding the specified getter or setter methods
611:             * of the property.
612:             * @author IT Mill Ltd.
613:             * @version 3.1.1
614:             * @since 3.0
615:             */
616:            public class MethodException extends RuntimeException {
617:
618:                /**
619:                 * Serial generated by eclipse.
620:                 */
621:                private static final long serialVersionUID = 3690473623827855153L;
622:                /** Cause of the method exception */
623:                private Throwable cause;
624:
625:                /** Constructs a new <code>MethodException</code> with the
626:                 * specified detail message.
627:                 * 
628:                 * @param msg the detail message
629:                 */
630:                public MethodException(String msg) {
631:                    super (msg);
632:                }
633:
634:                /** Constructs a new <code>MethodException</code> from another
635:                 * exception.
636:                 * 
637:                 * @param exception cause of the exception
638:                 */
639:                public MethodException(Throwable cause) {
640:                    this .cause = cause;
641:                }
642:
643:                /**
644:                 * @see java.lang.Throwable#getCause()
645:                 */
646:                public Throwable getCause() {
647:                    return cause;
648:                }
649:
650:                /** Get the method property this exception originates from */
651:                public MethodProperty getMethodProperty() {
652:                    return MethodProperty.this ;
653:                }
654:            }
655:
656:            /* Events *************************************************************** */
657:
658:            /** An <code>Event</code> object specifying the Property whose read-only
659:             * status has been changed.
660:             * @author IT Mill Ltd.
661:             * @version 3.1.1
662:             * @since 3.0
663:             */
664:            private class ReadOnlyStatusChangeEvent extends
665:                    java.util.EventObject implements 
666:                    Property.ReadOnlyStatusChangeEvent {
667:
668:                /**
669:                 * Serial generated by eclipse.
670:                 */
671:                private static final long serialVersionUID = 3258129163305955896L;
672:
673:                /** Constructs a new read-only status change event for this object.
674:                 * 
675:                 * @param source source object of the event
676:                 */
677:                protected ReadOnlyStatusChangeEvent(MethodProperty source) {
678:                    super (source);
679:                }
680:
681:                /** Gets the Property whose read-only state has changed.
682:                 * 
683:                 * @return source Property of the event.
684:                 */
685:                public Property getProperty() {
686:                    return (Property) getSource();
687:                }
688:
689:            }
690:
691:            /** Registers a new read-only status change listener for this Property.
692:             * 
693:             * @param listener the new Listener to be registered
694:             */
695:            public void addListener(
696:                    Property.ReadOnlyStatusChangeListener listener) {
697:                if (readOnlyStatusChangeListeners == null)
698:                    readOnlyStatusChangeListeners = new LinkedList();
699:                readOnlyStatusChangeListeners.add(listener);
700:            }
701:
702:            /** Remove a previously registered read-only status change listener.
703:             * 
704:             * @param listener listener to be removed
705:             */
706:            public void removeListener(
707:                    Property.ReadOnlyStatusChangeListener listener) {
708:                if (readOnlyStatusChangeListeners != null)
709:                    readOnlyStatusChangeListeners.remove(listener);
710:            }
711:
712:            /** Send a read only status change event to all registered listeners.
713:             */
714:            private void fireReadOnlyStatusChange() {
715:                if (readOnlyStatusChangeListeners != null) {
716:                    Object[] l = readOnlyStatusChangeListeners.toArray();
717:                    Property.ReadOnlyStatusChangeEvent event = new MethodProperty.ReadOnlyStatusChangeEvent(
718:                            this );
719:                    for (int i = 0; i < l.length; i++)
720:                        ((Property.ReadOnlyStatusChangeListener) l[i])
721:                                .readOnlyStatusChange(event);
722:                }
723:            }
724:
725:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.