View Javadoc
1   /*
2    *    Copyright 2012-2022 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.caches.memcached;
17  
18  import java.beans.BeanInfo;
19  import java.beans.IntrospectionException;
20  import java.beans.Introspector;
21  import java.beans.PropertyDescriptor;
22  import java.lang.reflect.Method;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  /**
28   * Converts a keyed property string in the Config to a proper Java object representation.
29   *
30   * @author Simone Tripodi
31   */
32  abstract class AbstractPropertySetter<T> {
33  
34    /**
35     * 'propertyName'='writermethod' index of {@link MemcachedConfiguration} properties.
36     */
37    private static Map<String, Method> WRITERS = new HashMap<String, Method>();
38  
39    static {
40      try {
41        BeanInfo memcachedConfigInfo = Introspector.getBeanInfo(MemcachedConfiguration.class);
42        for (PropertyDescriptor descriptor : memcachedConfigInfo.getPropertyDescriptors()) {
43          WRITERS.put(descriptor.getName(), descriptor.getWriteMethod());
44        }
45      } catch (IntrospectionException e) {
46        // handle quietly
47      }
48    }
49  
50    /**
51     * The Config property key.
52     */
53    private final String propertyKey;
54  
55    /**
56     * The {@link MemcachedConfiguration} property name.
57     */
58    private final String propertyName;
59  
60    /**
61     * The {@link MemcachedConfiguration} property method writer.
62     */
63    private final Method propertyWriterMethod;
64  
65    /**
66     * The default value used if something goes wrong during the conversion or the property is not set in the config.
67     */
68    private final T defaultValue;
69  
70    /**
71     * Build a new property setter.
72     *
73     * @param propertyKey
74     *          the Config property key.
75     * @param propertyName
76     *          the {@link MemcachedConfiguration} property name.
77     * @param defaultValue
78     *          the property default value.
79     */
80    public AbstractPropertySetter(final String propertyKey, final String propertyName, final T defaultValue) {
81      this.propertyKey = propertyKey;
82      this.propertyName = propertyName;
83  
84      this.propertyWriterMethod = WRITERS.get(propertyName);
85      if (this.propertyWriterMethod == null) {
86        throw new RuntimeException(
87            "Class '" + MemcachedConfiguration.class.getName() + "' doesn't contain a property '" + propertyName + "'");
88      }
89  
90      this.defaultValue = defaultValue;
91    }
92  
93    /**
94     * Extract a property from the, converts and puts it to the {@link MemcachedConfiguration}.
95     *
96     * @param config
97     *          the Config
98     * @param memcachedConfiguration
99     *          the {@link MemcachedConfiguration}
100    */
101   public final void set(Properties config, MemcachedConfiguration memcachedConfiguration) {
102     String propertyValue = config.getProperty(propertyKey);
103     T value;
104 
105     try {
106       value = this.convert(propertyValue);
107       if (value == null) {
108         value = defaultValue;
109       }
110     } catch (Exception e) {
111       value = defaultValue;
112     }
113 
114     try {
115       propertyWriterMethod.invoke(memcachedConfiguration, value);
116     } catch (Exception e) {
117       throw new RuntimeException("Impossible to set property '" + propertyName + "' with value '" + value
118           + "', extracted from ('" + propertyKey + "'=" + propertyValue + ")", e);
119     }
120   }
121 
122   /**
123    * Convert a string representation to a proper Java Object.
124    *
125    * @param value
126    *          the value has to be converted.
127    *
128    * @return the converted value.
129    *
130    * @throws Exception
131    *           if any error occurs.
132    */
133   protected abstract T convert(String value) throws Exception;
134 
135 }