1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/*
* Copyright © 2003-2009 Israfil Consulting Services Corporation
* Copyright © 2003-2009 Christian Edward Gruber
* All Rights Reserved
*
* This software is licensed under the Berkeley Standard Distribution license,
* (BSD license), as defined below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Israfil Consulting Services nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $Id: DynamicallyAccessibleObject.java 76 2006-08-03 15:37:05Z cgruber $
*/
package net.israfil.foundation.dynamic;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.israfil.foundation.core.Strings;
/**
* An implementation of the DynamicallyAccessible interface with the
* appropriate infrastructure for retrieving field data, via accessors if
* such are implemented, or directly from the field where not.
*
* @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
* @author Latest: $Author: cgruber $
* @version $Revision: 76 $
*/
public abstract class DynamicallyAccessibleObject extends DynamicObject implements DynamicallyAccessible {
private static Logger logger = Logger.getLogger(DynamicallyAccessibleObject.class.getName());
public Object get(String attributeName) {
return get(this,attributeName);
}
public static Object get(Object receiver, String attributeName) {
try {
return _get(receiver, attributeName);
} catch (NoSuchFieldException e) {
logger.log(Level.FINE,"Object attempted to dynamically access a non-existant or unreadable field.",e);
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
logger.log(Level.FINE,"Object attempted to dynamically access a inaccessible field.",e);
throw new RuntimeException(e);
}
}
/** @deprecated This method is deprecated in favour of the static _get(receiver, attributeName) */
Object _get(String attributeName) throws NoSuchFieldException, IllegalAccessException {
return _get(this,attributeName);
}
/**
* Internal _get method that throws all the exceptions, to be wrapped by public methods
* so that the various exceptions can be given meaning in different contexts (such
* as fetching data, vs. testing for the existance of something.
*
* @param attributeName
* @return
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
static Object _get(Object receiver, String attributeName) throws NoSuchFieldException, IllegalAccessException {
if (hasAccessor(receiver,attributeName)) return DynamicUtil.performOn(receiver,_getAccessorSelector(receiver,attributeName), new Object[]{});
return receiver.getClass().getField(attributeName).get(receiver);
}
/**
* Determines whether an attribute of the given name exists on this object's
* definition, or if not, if there is a javabeans-style accessor named
* appropriately for that attribute. Put another way, determines whether
* a get() call would work against this attribute name.
*
* The existing implementation is inefficient, but simple to maintain.
*/
public boolean hasAttribute(String attributeName) {
return hasAttribute(this,attributeName);
}
public static boolean hasAttribute(Object receiver, String attributeName) {
try {
_get(receiver,attributeName);
return true;
} catch (NoSuchFieldException e) {
logger.log(Level.FINEST,"Object attempted to dynamically access a non-existant or unreadable field.",e);
return false;
} catch (IllegalAccessException e) {
logger.log(Level.FINEST,"Object attempted to dynamically access a inaccessible field.",e);
return false;
}
}
protected static final String[] accessPrefixes = new String[] { "get","is" };
/** @deprecated This method is deprecated in favour of the static _getAccessorSelector(receiver,attribute) */
protected String getAccessorSelector(String attributeName) { return _getAccessorSelector(this,attributeName); }
protected static String _getAccessorSelector(Object receiver, String attributeName) {
if (attributeName == null || attributeName.equals("")) return null;
String camelAttr = camel(attributeName);
for (String prefix : accessPrefixes) {
String selector = prefix+camelAttr;
if (DynamicUtil.respondsTo(receiver,selector)) return selector;
}
// No accessor, try a NeXTSTEP-style accessor, named the same as the property.
if (DynamicUtil.respondsTo(receiver,attributeName)) return attributeName;
return null;
}
public boolean hasAccessor(String attributeName) {
return hasAccessor(this,attributeName);
}
public static boolean hasAccessor(Object receiver, String attributeName) {
return _getAccessorSelector(receiver,attributeName) != null;
}
/** @deprecated This method has been moved to net.israfil.foundation.core.Strings.camel(String) */
public static String camel(String string) {
return Strings.camel(string);
}
}
|