1 package org.apache.maven.plugin.coreit;
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.lang.reflect.Field;
24 import java.lang.reflect.Method;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32
33
34
35
36
37
38
39 class ExpressionUtil
40 {
41
42 private static final Object[] NO_ARGS = {};
43
44 private static final Class[] NO_PARAMS = {};
45
46 private static final Class[] OBJECT_PARAM = { Object.class };
47
48 private static final Class[] STRING_PARAM = { String.class };
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public static Map evaluate( String expression, Object context )
65 {
66 Map values = Collections.EMPTY_MAP;
67
68 if ( expression != null && expression.length() > 0 )
69 {
70 List segments = Arrays.asList( expression.split( "/", 0 ) );
71 values = evaluate( "", segments, context );
72 }
73
74 return values;
75 }
76
77
78
79
80
81
82
83
84
85
86 private static Map evaluate( String prefix, List segments, Object context )
87 {
88 Map values = Collections.EMPTY_MAP;
89
90 if ( segments.isEmpty() )
91 {
92 values = Collections.singletonMap( prefix, context );
93 }
94 else if ( context != null )
95 {
96 Map targets = Collections.EMPTY_MAP;
97 String segment = (String) segments.get( 0 );
98 if ( context.getClass().isArray() && Character.isDigit( segment.charAt( 0 ) ) )
99 {
100 try
101 {
102 int index = Integer.parseInt( segment );
103 targets = Collections.singletonMap( segment, Array.get( context, index ) );
104 }
105 catch ( RuntimeException e )
106 {
107
108 }
109 }
110 else if ( ( context instanceof List ) && Character.isDigit( segment.charAt( 0 ) ) )
111 {
112 try
113 {
114 int index = Integer.parseInt( segment );
115 targets = Collections.singletonMap( segment, ( (List) context ).get( index ) );
116 }
117 catch ( RuntimeException e )
118 {
119
120 }
121 }
122 else if ( ( context instanceof Collection ) && "*".equals( segment ) )
123 {
124 targets = new LinkedHashMap();
125 int index = 0;
126 for ( Iterator it = ( (Collection) context ).iterator(); it.hasNext(); index++ )
127 {
128 targets.put( Integer.toString( index ), it.next() );
129 }
130 }
131 else if ( context.getClass().isArray() && "*".equals( segment ) )
132 {
133 targets = new LinkedHashMap();
134 for ( int index = 0, n = Array.getLength( context ); index < n; index++ )
135 {
136 targets.put( Integer.toString( index ), Array.get( context, index ) );
137 }
138 }
139 else
140 {
141 targets = Collections.singletonMap( segment, getProperty( context, segment ) );
142 }
143
144 values = new LinkedHashMap();
145 for ( Object key : targets.keySet() )
146 {
147 Object target = targets.get( key );
148 values.putAll(
149 evaluate( concat( prefix, String.valueOf( key ) ), segments.subList( 1, segments.size() ),
150 target ) );
151 }
152 }
153
154 return values;
155 }
156
157 private static String concat( String prefix, String segment )
158 {
159 return ( prefix == null || prefix.length() <= 0 ) ? segment : ( prefix + '/' + segment );
160 }
161
162
163
164
165
166
167
168
169 static Object getProperty( Object context, String property )
170 {
171 Object value;
172
173 Class type = context.getClass();
174 if ( context instanceof Collection )
175 {
176 type = Collection.class;
177 }
178 else if ( context instanceof Map )
179 {
180 type = Map.class;
181 }
182
183 try
184 {
185 try
186 {
187 Method method = type.getMethod( property, NO_PARAMS );
188 method.setAccessible( true );
189 value = method.invoke( context, NO_ARGS );
190 }
191 catch ( NoSuchMethodException e )
192 {
193 try
194 {
195 String name = "get" + Character.toUpperCase( property.charAt( 0 ) ) + property.substring( 1 );
196 Method method = type.getMethod( name, NO_PARAMS );
197 method.setAccessible( true );
198 value = method.invoke( context, NO_ARGS );
199 }
200 catch ( NoSuchMethodException e1 )
201 {
202 try
203 {
204 String name = "is" + Character.toUpperCase( property.charAt( 0 ) ) + property.substring( 1 );
205 Method method = type.getMethod( name, NO_PARAMS );
206 method.setAccessible( true );
207 value = method.invoke( context, NO_ARGS );
208 }
209 catch ( NoSuchMethodException e2 )
210 {
211 try
212 {
213 Method method;
214 try
215 {
216 method = type.getMethod( "get", STRING_PARAM );
217 }
218 catch ( NoSuchMethodException e3 )
219 {
220 method = type.getMethod( "get", OBJECT_PARAM );
221 }
222 method.setAccessible( true );
223 value = method.invoke( context, new Object[]{ property } );
224 }
225 catch ( NoSuchMethodException e3 )
226 {
227 try
228 {
229 Field field = type.getField( property );
230 field.setAccessible( true );
231 value = field.get( context );
232 }
233 catch ( NoSuchFieldException e4 )
234 {
235 if ( "length".equals( property ) && type.isArray() )
236 {
237 value = Array.getLength( context );
238 }
239 else
240 {
241 throw e4;
242 }
243 }
244 }
245 }
246 }
247 }
248 }
249 catch ( Exception e )
250 {
251 value = null;
252 }
253 return value;
254 }
255
256 }