View Javadoc

1   /*
2    *   Copyright (C) Christian Schulte, 2011-293
3    *   All rights reserved.
4    *
5    *   Redistribution and use in source and binary forms, with or without
6    *   modification, are permitted provided that the following conditions
7    *   are met:
8    *
9    *     o Redistributions of source code must retain the above copyright
10   *       notice, this list of conditions and the following disclaimer.
11   *
12   *     o Redistributions in binary form must reproduce the above copyright
13   *       notice, this list of conditions and the following disclaimer in
14   *       the documentation and/or other materials provided with the
15   *       distribution.
16   *
17   *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   *   $JOMC: KeyValueType.java 4613 2012-09-22 10:07:08Z schulte $
29   *
30   */
31  package org.jomc.mojo;
32  
33  import java.lang.reflect.InvocationTargetException;
34  import java.lang.reflect.Method;
35  import java.lang.reflect.Modifier;
36  import org.apache.commons.lang.builder.ToStringBuilder;
37  
38  /**
39   * Datatype holding a {@code key}, {@code value} and {@code type} property.
40   *
41   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
42   * @version $JOMC: KeyValueType.java 4613 2012-09-22 10:07:08Z schulte $
43   * @since 1.2
44   */
45  public class KeyValueType implements Cloneable
46  {
47  
48      /** The key of the type. */
49      private String key;
50  
51      /** The value of the type. */
52      private String value;
53  
54      /** The name of the class of the type of {@code value}. */
55      private String type;
56  
57      /** Creates a new {@code KeyValueType} instance. */
58      public KeyValueType()
59      {
60          super();
61      }
62  
63      /**
64       * Gets the value of the {@code key} property.
65       *
66       * @return The value of the {@code key} property.
67       *
68       * @see #setKey(java.lang.String)
69       */
70      public final String getKey()
71      {
72          return this.key;
73      }
74  
75      /**
76       * Sets the value of the {@code key} property.
77       *
78       * @param k The new value of the {@code key} property.
79       *
80       * @see #getKey()
81       */
82      public final void setKey( final String k )
83      {
84          this.key = k;
85      }
86  
87      /**
88       * Gets the value of the {@code value} property.
89       *
90       * @return The value of the {@code value} property or {@code null}.
91       *
92       * @see #setValue(java.lang.String)
93       */
94      public final String getValue()
95      {
96          return this.value;
97      }
98  
99      /**
100      * Sets the value of the {@code value} property.
101      *
102      * @param v The new value of the {@code value} property or {@code null}.
103      *
104      * @see #getValue()
105      */
106     public final void setValue( final String v )
107     {
108         this.value = v;
109     }
110 
111     /**
112      * Gets the value of the {@code type} property.
113      *
114      * @return The value of the {@code type} property or {@code null}.
115      *
116      * @see #setType(java.lang.String)
117      */
118     public final String getType()
119     {
120         return this.type;
121     }
122 
123     /**
124      * Sets the value of the {@code type} property.
125      *
126      * @param t The new value of the {@code type} property or {@code null}.
127      *
128      * @see #getType()
129      */
130     public final void setType( final String t )
131     {
132         this.type = t;
133     }
134 
135     /**
136      * Gets the object of the instance.
137      *
138      * @return The object of the instance or {@code null}.
139      *
140      * @throws InstantiationException if getting the object of the instance fails.
141      *
142      * @see #getType()
143      * @see #getValue()
144      */
145     public Object getObject() throws InstantiationException // JDK: As of JDK 7, "throws ReflectiveOperationException".
146     {
147         Class<?> javaClass = null;
148         Object o = this.getValue();
149 
150         try
151         {
152             if ( o != null )
153             {
154                 if ( this.getType() != null && !String.class.getName().equals( this.getType() ) )
155                 {
156                     javaClass = Class.forName( this.getType() );
157 
158                     try
159                     {
160                         o = javaClass.getConstructor( String.class ).newInstance( o );
161                     }
162                     catch ( final NoSuchMethodException e )
163                     {
164                         final Method valueOf = javaClass.getMethod( "valueOf", String.class );
165 
166                         if ( Modifier.isStatic( valueOf.getModifiers() )
167                              && valueOf.getReturnType().equals( javaClass ) )
168                         {
169                             o = valueOf.invoke( null, o );
170                         }
171                         else
172                         {
173                             throw (InstantiationException) new InstantiationException(
174                                 Messages.getMessage( "noSuchMethodCreatingObject", this.getType(), this.getValue(),
175                                                      javaClass.getSimpleName() ) ).initCause( e );
176 
177                         }
178                     }
179                 }
180             }
181             else if ( this.getType() != null )
182             {
183                 o = Class.forName( this.getType() ).newInstance();
184             }
185 
186             return o;
187         }
188         catch ( final ClassNotFoundException e )
189         {
190             throw (InstantiationException) new InstantiationException(
191                 Messages.getMessage( "failedCreatingObject", this.getType() ) ).initCause( e );
192 
193         }
194         catch ( final NoSuchMethodException e )
195         {
196             throw (InstantiationException) new InstantiationException(
197                 Messages.getMessage( "noSuchMethodCreatingObject", this.getType(), this.getValue(),
198                                      javaClass.getSimpleName() ) ).initCause( e );
199 
200         }
201         catch ( final IllegalAccessException e )
202         {
203             throw (InstantiationException) new InstantiationException(
204                 Messages.getMessage( "failedCreatingObject", this.getType() ) ).initCause( e );
205 
206         }
207         catch ( final InvocationTargetException e )
208         {
209             throw (InstantiationException) new InstantiationException(
210                 Messages.getMessage( "failedCreatingObject", this.getType() ) ).initCause( e );
211 
212         }
213     }
214 
215     /**
216      * Creates and returns a copy of this object.
217      *
218      * @return A copy of this object.
219      */
220     @Override
221     public KeyValueType clone()
222     {
223         try
224         {
225             return (KeyValueType) super.clone();
226         }
227         catch ( final CloneNotSupportedException e )
228         {
229             throw new AssertionError( e );
230         }
231     }
232 
233     /**
234      * Creates and returns a string representation of the object.
235      *
236      * @return A string representation of the object.
237      */
238     @Override
239     public String toString()
240     {
241         return ToStringBuilder.reflectionToString( this );
242     }
243 
244 }