View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.tools.test;
20  
21  import java.lang.reflect.Field;
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.codehaus.plexus.util.ReflectionUtils;
28  import org.codehaus.plexus.util.StringUtils;
29  
30  public class ReflectiveSetter
31  {
32  
33      private Map cachedPropertySetters = new HashMap();
34  
35      private final Class targetClass;
36  
37      public ReflectiveSetter( Class targetClass )
38      {
39          this.targetClass = targetClass;
40      }
41  
42      public void setProperty( String propertyName, Object value, Object target )
43          throws Throwable
44      {
45  
46          String preferredMethodName = "set" + StringUtils.capitalizeFirstLetter( propertyName );
47  
48          Setter setter = null;
49  
50          Method method = ReflectionUtils.getSetter( preferredMethodName, targetClass );
51  
52          if ( method != null )
53          {
54              setter = new MethodSetter( propertyName, method );
55          }
56          else
57          {
58              Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( propertyName, targetClass );
59  
60              setter = new FieldSetter( propertyName, field );
61          }
62  
63          if ( setter == null )
64          {
65              throw new IllegalArgumentException( "No such property: " + propertyName + " in: " + targetClass
66                  + ". Searched for: {method:" + preferredMethodName + ", method:" + propertyName + ", field:"
67                  + propertyName + "}" );
68          }
69  
70          cachedPropertySetters.put( setter.getProperty(), setter );
71  
72          try
73          {
74              setter.set( value, target );
75          }
76          catch ( InvocationTargetException e )
77          {
78              throw e.getTargetException();
79          }
80      }
81  
82      private interface Setter
83      {
84          void set( Object value, Object target )
85              throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
86  
87          String getProperty();
88      }
89  
90      private static class MethodSetter
91          implements Setter
92      {
93          private Method method;
94  
95          private String name;
96  
97          MethodSetter( String name, Method method )
98          {
99              this.name = name;
100             this.method = method;
101         }
102 
103         public String getProperty()
104         {
105             return name;
106         }
107 
108         public void set( Object value, Object target )
109             throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
110         {
111             boolean wasAccessible = method.isAccessible();
112 
113             method.setAccessible( true );
114             try
115             {
116                 method.invoke( target, new Object[] { value } );
117             }
118             finally
119             {
120                 method.setAccessible( wasAccessible );
121             }
122         }
123     }
124 
125     private static class FieldSetter
126         implements Setter
127     {
128         private Field field;
129 
130         private String name;
131 
132         FieldSetter( String name, Field field )
133         {
134             this.name = name;
135             this.field = field;
136         }
137 
138         public String getProperty()
139         {
140             return name;
141         }
142 
143         public void set( Object value, Object target )
144             throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
145         {
146             boolean wasAccessible = field.isAccessible();
147 
148             field.setAccessible( true );
149             try
150             {
151                 field.set( target, value );
152             }
153             finally
154             {
155                 field.setAccessible( wasAccessible );
156             }
157         }
158     }
159 
160 }