1 package org.apache.commons.ognl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.Array;
23 import java.util.Map;
24
25
26
27
28
29
30
31 public class ArrayPropertyAccessor
32 extends ObjectPropertyAccessor
33 implements PropertyAccessor
34 {
35
36 @Override
37 public Object getProperty( Map<String, Object> context, Object target, Object name )
38 throws OgnlException
39 {
40 Object result = null;
41
42 if ( name instanceof String )
43 {
44 if ( "length".equals( name ) )
45 {
46 result = Array.getLength( target );
47 }
48 else
49 {
50 result = super.getProperty( context, target, name );
51 }
52 }
53 else
54 {
55 Object index = name;
56
57 if ( index instanceof DynamicSubscript )
58 {
59 int len = Array.getLength( target );
60
61 switch ( ( (DynamicSubscript) index ).getFlag() )
62 {
63 case DynamicSubscript.ALL:
64 result = Array.newInstance( target.getClass().getComponentType(), len );
65 System.arraycopy( target, 0, result, 0, len );
66 break;
67 case DynamicSubscript.FIRST:
68 index = ( len > 0 ) ? 0 : -1;
69 break;
70 case DynamicSubscript.MID:
71 index = ( len > 0 ) ? ( len / 2 ) : -1;
72 break;
73 case DynamicSubscript.LAST:
74 index = ( len > 0 ) ? ( len - 1 ) : -1;
75 break;
76 default: break;
77 }
78 }
79 if ( result == null )
80 {
81 if ( index instanceof Number )
82 {
83 int i = ( (Number) index ).intValue();
84
85 result = ( i >= 0 ) ? Array.get( target, i ) : null;
86 }
87 else
88 {
89 throw new NoSuchPropertyException( target, index );
90 }
91 }
92 }
93 return result;
94 }
95
96 @Override
97 public void setProperty( Map<String, Object> context, Object target, Object name, Object value )
98 throws OgnlException
99 {
100 boolean isNumber = ( name instanceof Number );
101
102 if ( isNumber || ( name instanceof DynamicSubscript ) )
103 {
104 TypeConverter converter = ( (OgnlContext) context ).getTypeConverter();
105 Object convertedValue;
106
107 convertedValue = converter.convertValue( context, target, null, name.toString(), value,
108 target.getClass().getComponentType() );
109 if ( isNumber )
110 {
111 int i = ( (Number) name ).intValue();
112
113 if ( i >= 0 )
114 {
115 Array.set( target, i, convertedValue );
116 }
117 }
118 else
119 {
120 int len = Array.getLength( target );
121
122 switch ( ( (DynamicSubscript) name ).getFlag() )
123 {
124 case DynamicSubscript.ALL:
125 System.arraycopy( target, 0, convertedValue, 0, len );
126 return;
127 default:
128 break;
129 }
130 }
131 }
132 else
133 {
134 if ( name instanceof String )
135 {
136 super.setProperty( context, target, name, value );
137 }
138 else
139 {
140 throw new NoSuchPropertyException( target, name );
141 }
142 }
143 }
144
145 @Override
146 public String getSourceAccessor( OgnlContext context, Object target, Object index )
147 {
148 String indexStr = getIndexString( context, index );
149
150 context.setCurrentAccessor( target.getClass() );
151 context.setCurrentType( target.getClass().getComponentType() );
152
153 return "[" + indexStr + "]";
154 }
155
156 @Override
157 public String getSourceSetter( OgnlContext context, Object target, Object index )
158 {
159 String indexStr = getIndexString( context, index );
160
161 Class<?> type = target.getClass().isArray() ? target.getClass().getComponentType() : target.getClass();
162
163 context.setCurrentAccessor( target.getClass() );
164 context.setCurrentType( target.getClass().getComponentType() );
165
166 if ( type.isPrimitive() )
167 {
168 Class<?> wrapClass = OgnlRuntime.getPrimitiveWrapperClass( type );
169
170 return "[" + indexStr + "]=((" + wrapClass.getName() + ")org.apache.commons.ognl.OgnlOps.convertValue($3,"
171 + wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter( wrapClass );
172 }
173 return "[" + indexStr + "]=org.apache.commons.ognl.OgnlOps.convertValue($3," + type.getName() + ".class)";
174 }
175
176 private static String getIndexString( OgnlContext context, Object index )
177 {
178 String indexStr = index.toString();
179
180
181
182
183
184
185 if ( context.getCurrentType() != null && !context.getCurrentType().isPrimitive()
186 && Number.class.isAssignableFrom( context.getCurrentType() ) )
187 {
188 indexStr += "." + OgnlRuntime.getNumericValueGetter( context.getCurrentType() );
189 }
190 else if ( context.getCurrentObject() != null && Number.class.isAssignableFrom(
191 context.getCurrentObject().getClass() ) && !context.getCurrentType().isPrimitive() )
192 {
193
194
195 String toString =
196 String.class.isInstance( index ) && context.getCurrentType() != Object.class ? "" : ".toString()";
197
198 indexStr = "org.apache.commons.ognl.OgnlOps#getIntValue(" + indexStr + toString + ")";
199 }
200 return indexStr;
201 }
202 }