001: //--------------------------------------------------------------------------
002: // Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
003: // All rights reserved.
004: //
005: // Redistribution and use in source and binary forms, with or without
006: // modification, are permitted provided that the following conditions are
007: // met:
008: //
009: // Redistributions of source code must retain the above copyright notice,
010: // this list of conditions and the following disclaimer.
011: // Redistributions in binary form must reproduce the above copyright
012: // notice, this list of conditions and the following disclaimer in the
013: // documentation and/or other materials provided with the distribution.
014: // Neither the name of the Drew Davidson nor the names of its contributors
015: // may be used to endorse or promote products derived from this software
016: // without specific prior written permission.
017: //
018: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022: // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
023: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
024: // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
025: // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026: // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
027: // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
028: // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
029: // DAMAGE.
030: //--------------------------------------------------------------------------
031: package ognl;
032:
033: import java.lang.reflect.Array;
034: import java.util.Map;
035:
036: /**
037: * Implementation of PropertyAccessor that uses numbers and dynamic subscripts as
038: * properties to index into Java arrays.
039: * @author Luke Blanshard (blanshlu@netscape.net)
040: * @author Drew Davidson (drew@ognl.org)
041: */
042: public class ArrayPropertyAccessor extends ObjectPropertyAccessor
043: implements PropertyAccessor // This is here to make javadoc show this class as an implementor
044: {
045: public Object getProperty(Map context, Object target, Object name)
046: throws OgnlException {
047: Object result = null;
048:
049: if (name instanceof String) {
050: if (name.equals("length")) {
051: result = new Integer(Array.getLength(target));
052: } else {
053: result = super .getProperty(context, target, name);
054: }
055: } else {
056: Object index = name;
057:
058: if (index instanceof DynamicSubscript) {
059: int len = Array.getLength(target);
060:
061: switch (((DynamicSubscript) index).getFlag()) {
062: case DynamicSubscript.ALL:
063: result = Array.newInstance(target.getClass()
064: .getComponentType(), len);
065: System.arraycopy(target, 0, result, 0, len);
066: break;
067: case DynamicSubscript.FIRST:
068: index = new Integer((len > 0) ? 0 : -1);
069: break;
070: case DynamicSubscript.MID:
071: index = new Integer((len > 0) ? (len / 2) : -1);
072: break;
073: case DynamicSubscript.LAST:
074: index = new Integer((len > 0) ? (len - 1) : -1);
075: break;
076: }
077: }
078: if (result == null) {
079: if (index instanceof Number) {
080: int i = ((Number) index).intValue();
081:
082: result = (i >= 0) ? Array.get(target, i) : null;
083: } else {
084: throw new NoSuchPropertyException(target, index);
085: }
086: }
087: }
088: return result;
089: }
090:
091: public void setProperty(Map context, Object target, Object name,
092: Object value) throws OgnlException {
093: Object index = name;
094: boolean isNumber = (index instanceof Number);
095:
096: if (isNumber || (index instanceof DynamicSubscript)) {
097: TypeConverter converter = ((OgnlContext) context)
098: .getTypeConverter();
099: Object convertedValue;
100:
101: convertedValue = converter.convertValue(context, target,
102: null, name.toString(), value, target.getClass()
103: .getComponentType());
104: if (isNumber) {
105: int i = ((Number) index).intValue();
106:
107: if (i >= 0) {
108: Array.set(target, i, convertedValue);
109: }
110: } else {
111: int len = Array.getLength(target);
112:
113: switch (((DynamicSubscript) index).getFlag()) {
114: case DynamicSubscript.ALL:
115: System.arraycopy(target, 0, convertedValue, 0, len);
116: return;
117: case DynamicSubscript.FIRST:
118: index = new Integer((len > 0) ? 0 : -1);
119: break;
120: case DynamicSubscript.MID:
121: index = new Integer((len > 0) ? (len / 2) : -1);
122: break;
123: case DynamicSubscript.LAST:
124: index = new Integer((len > 0) ? (len - 1) : -1);
125: break;
126: }
127: }
128: } else {
129: if (name instanceof String) {
130: super .setProperty(context, target, name, value);
131: } else {
132: throw new NoSuchPropertyException(target, index);
133: }
134: }
135: }
136: }
|