View Javadoc

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