001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.common.beans;
017:
018: import java.util.List;
019: import java.util.Map;
020: import java.util.StringTokenizer;
021:
022: /**
023: * StaticBeanProbe provides methods that allow simple, reflective access to
024: * JavaBeans style properties. Methods are provided for all simple types as
025: * well as object types.
026: * <p/>
027: * Examples:
028: * <p/>
029: * StaticBeanProbe.setObject(object, propertyName, value);
030: * <P>
031: * Object value = StaticBeanProbe.getObject(object, propertyName);
032: */
033: public class GenericProbe extends BaseProbe {
034:
035: private static final BaseProbe BEAN_PROBE = new ComplexBeanProbe();
036: private static final BaseProbe DOM_PROBE = new DomProbe();
037:
038: protected GenericProbe() {
039: }
040:
041: /**
042: * Gets an object from a Map or bean
043: *
044: * @param object - the object to probe
045: * @param name - the name of the property (or map entry)
046: * @return The value of the property (or map entry)
047: * @see com.ibatis.common.beans.BaseProbe#getObject(java.lang.Object, java.lang.String)
048: */
049: public Object getObject(Object object, String name) {
050:
051: if (object instanceof org.w3c.dom.Document) {
052: return DOM_PROBE.getObject(object, name);
053: } else if (object instanceof List) {
054: return BEAN_PROBE.getIndexedProperty(object, name);
055: } else if (object instanceof Object[]) {
056: return BEAN_PROBE.getIndexedProperty(object, name);
057: } else if (object instanceof char[]) {
058: return BEAN_PROBE.getIndexedProperty(object, name);
059: } else if (object instanceof boolean[]) {
060: return BEAN_PROBE.getIndexedProperty(object, name);
061: } else if (object instanceof byte[]) {
062: return BEAN_PROBE.getIndexedProperty(object, name);
063: } else if (object instanceof double[]) {
064: return BEAN_PROBE.getIndexedProperty(object, name);
065: } else if (object instanceof float[]) {
066: return BEAN_PROBE.getIndexedProperty(object, name);
067: } else if (object instanceof int[]) {
068: return BEAN_PROBE.getIndexedProperty(object, name);
069: } else if (object instanceof long[]) {
070: return BEAN_PROBE.getIndexedProperty(object, name);
071: } else if (object instanceof short[]) {
072: return BEAN_PROBE.getIndexedProperty(object, name);
073: } else {
074: return BEAN_PROBE.getObject(object, name);
075: }
076: }
077:
078: /**
079: * Sets an object in a Map or bean
080: *
081: * @param object - the object to probe
082: * @param name - the name of the property (or map entry)
083: * @param value - the new value of the property (or map entry)
084: * @see com.ibatis.common.beans.BaseProbe#setObject(java.lang.Object, java.lang.String, java.lang.Object)
085: */
086: public void setObject(Object object, String name, Object value) {
087: if (object instanceof org.w3c.dom.Document) {
088: DOM_PROBE.setObject(object, name, value);
089: } else {
090: BEAN_PROBE.setObject(object, name, value);
091: }
092: }
093:
094: /**
095: * Gets an array of the readable properties in a Map or JavaBean
096: *
097: * @param object - the object to get properties for
098: * @return The array of properties (or map entries)
099: * @see com.ibatis.common.beans.BaseProbe#getReadablePropertyNames(java.lang.Object)
100: */
101: public String[] getReadablePropertyNames(Object object) {
102: if (object instanceof org.w3c.dom.Document) {
103: return DOM_PROBE.getReadablePropertyNames(object);
104: } else {
105: return BEAN_PROBE.getReadablePropertyNames(object);
106: }
107: }
108:
109: /**
110: * Gets an array of the writeable properties in a Map or JavaBean
111: *
112: * @param object - the object to get properties for
113: * @return The array of properties (or map entries)
114: * @see com.ibatis.common.beans.BaseProbe#getWriteablePropertyNames(java.lang.Object)
115: */
116: public String[] getWriteablePropertyNames(Object object) {
117: if (object instanceof org.w3c.dom.Document) {
118: return DOM_PROBE.getWriteablePropertyNames(object);
119: } else {
120: return BEAN_PROBE.getWriteablePropertyNames(object);
121: }
122: }
123:
124: /**
125: * Returns the class that the setter expects to receive as a parameter when
126: * setting a property value.
127: *
128: * @param object - The class to check
129: * @param name - the name of the property
130: * @return The type of the property
131: * @see com.ibatis.common.beans.Probe#getPropertyTypeForSetter(java.lang.Object, java.lang.String)
132: */
133: public Class getPropertyTypeForSetter(Object object, String name) {
134: if (object instanceof Class) {
135: return getClassPropertyTypeForSetter((Class) object, name);
136: } else if (object instanceof org.w3c.dom.Document) {
137: return DOM_PROBE.getPropertyTypeForSetter(object, name);
138: } else {
139: return BEAN_PROBE.getPropertyTypeForSetter(object, name);
140: }
141: }
142:
143: /**
144: * Returns the class that the getter will return when reading a property value.
145: *
146: * @param object The bean to check
147: * @param name The name of the property
148: * @return The type of the property
149: * @see com.ibatis.common.beans.Probe#getPropertyTypeForGetter(java.lang.Object, java.lang.String)
150: */
151: public Class getPropertyTypeForGetter(Object object, String name) {
152: if (object instanceof Class) {
153: return getClassPropertyTypeForGetter((Class) object, name);
154: } else if (object instanceof org.w3c.dom.Document) {
155: return DOM_PROBE.getPropertyTypeForGetter(object, name);
156: } else if (name.indexOf('[') > -1) {
157: return BEAN_PROBE.getIndexedType(object, name);
158: } else {
159: return BEAN_PROBE.getPropertyTypeForGetter(object, name);
160: }
161: }
162:
163: /**
164: * Checks to see if an object has a writable property by a given name
165: *
166: * @param object The bean to check
167: * @param propertyName The property to check for
168: * @return True if the property exists and is writable
169: * @see com.ibatis.common.beans.Probe#hasWritableProperty(java.lang.Object, java.lang.String)
170: */
171: public boolean hasWritableProperty(Object object,
172: String propertyName) {
173: if (object instanceof org.w3c.dom.Document) {
174: return DOM_PROBE.hasWritableProperty(object, propertyName);
175: } else {
176: return BEAN_PROBE.hasWritableProperty(object, propertyName);
177: }
178: }
179:
180: /**
181: * Checks to see if a bean has a readable property by a given name
182: *
183: * @param object The bean to check
184: * @param propertyName The property to check for
185: * @return True if the property exists and is readable
186: * @see com.ibatis.common.beans.Probe#hasReadableProperty(java.lang.Object, java.lang.String)
187: */
188: public boolean hasReadableProperty(Object object,
189: String propertyName) {
190: if (object instanceof org.w3c.dom.Document) {
191: return DOM_PROBE.hasReadableProperty(object, propertyName);
192: } else {
193: return BEAN_PROBE.hasReadableProperty(object, propertyName);
194: }
195: }
196:
197: protected void setProperty(Object object, String property,
198: Object value) {
199: if (object instanceof org.w3c.dom.Document) {
200: DOM_PROBE.setProperty(object, property, value);
201: } else {
202: BEAN_PROBE.setProperty(object, property, value);
203: }
204: }
205:
206: protected Object getProperty(Object object, String property) {
207: if (object instanceof org.w3c.dom.Document) {
208: return DOM_PROBE.getProperty(object, property);
209: } else {
210: return BEAN_PROBE.getProperty(object, property);
211: }
212: }
213:
214: private Class getClassPropertyTypeForGetter(Class type, String name) {
215:
216: if (name.indexOf('.') > -1) {
217: StringTokenizer parser = new StringTokenizer(name, ".");
218: while (parser.hasMoreTokens()) {
219: name = parser.nextToken();
220: if (Map.class.isAssignableFrom(type)) {
221: type = Object.class;
222: break;
223: }
224: type = ClassInfo.getInstance(type).getGetterType(name);
225: }
226: } else {
227: type = ClassInfo.getInstance(type).getGetterType(name);
228: }
229:
230: return type;
231: }
232:
233: /**
234: * Returns the class that the setter expects to receive as a parameter when
235: * setting a property value.
236: *
237: * @param type The class to check
238: * @param name The name of the property
239: * @return The type of the property
240: */
241: private Class getClassPropertyTypeForSetter(Class type, String name) {
242:
243: if (name.indexOf('.') > -1) {
244: StringTokenizer parser = new StringTokenizer(name, ".");
245: while (parser.hasMoreTokens()) {
246: name = parser.nextToken();
247: if (Map.class.isAssignableFrom(type)) {
248: type = Object.class;
249: break;
250: }
251: type = ClassInfo.getInstance(type).getSetterType(name);
252: }
253: } else {
254: type = ClassInfo.getInstance(type).getSetterType(name);
255: }
256:
257: return type;
258: }
259:
260: }
|