View Javadoc
1   /*
2    *   Copyright (C) Christian Schulte <cs@schulte.it>, 2005-206
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 5043 2015-05-27 07:03:39Z schulte $
29   *
30   */
31  package org.jomc.ant.types;
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  import org.apache.tools.ant.BuildException;
38  import org.apache.tools.ant.Location;
39  
40  /**
41   * Datatype holding a {@code key}, {@code value} and {@code type} property.
42   *
43   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
44   * @version $JOMC: KeyValueType.java 5043 2015-05-27 07:03:39Z schulte $
45   */
46  public class KeyValueType implements Cloneable
47  {
48  
49      /**
50       * The key of the type.
51       */
52      private String key;
53  
54      /**
55       * The value of the type.
56       */
57      private String value;
58  
59      /**
60       * The class of the type of {@code value}.
61       */
62      private Class<?> type;
63  
64      /**
65       * Creates a new {@code KeyValueType} instance.
66       */
67      public KeyValueType()
68      {
69          super();
70      }
71  
72      /**
73       * Gets the value of the {@code key} property.
74       *
75       * @return The value of the {@code key} property.
76       *
77       * @see #setKey(java.lang.String)
78       */
79      public final String getKey()
80      {
81          return this.key;
82      }
83  
84      /**
85       * Sets the value of the {@code key} property.
86       *
87       * @param k The new value of the {@code key} property.
88       *
89       * @see #getKey()
90       */
91      public final void setKey( final String k )
92      {
93          this.key = k;
94      }
95  
96      /**
97       * Gets the value of the {@code value} property.
98       *
99       * @return The value of the {@code value} property or {@code null}.
100      *
101      * @see #setValue(java.lang.String)
102      */
103     public final String getValue()
104     {
105         return this.value;
106     }
107 
108     /**
109      * Sets the value of the {@code value} property.
110      *
111      * @param v The new value of the {@code value} property or {@code null}.
112      *
113      * @see #getValue()
114      */
115     public final void setValue( final String v )
116     {
117         this.value = v;
118     }
119 
120     /**
121      * Gets the value of the {@code type} property.
122      *
123      * @return The value of the {@code type} property or {@code null}.
124      *
125      * @see #setType(java.lang.Class)
126      */
127     public final Class<?> getType()
128     {
129         return this.type;
130     }
131 
132     /**
133      * Sets the value of the {@code type} property.
134      *
135      * @param t The new value of the {@code type} property or {@code null}.
136      *
137      * @see #getType()
138      */
139     public final void setType( final Class<?> t )
140     {
141         this.type = t;
142     }
143 
144     /**
145      * Gets the object of the instance.
146      *
147      * @param location The location the object is requested at.
148      *
149      * @return The object of the instance or {@code null}.
150      *
151      * @throws NullPointerException if {@code location} is {@code null}.
152      * @throws BuildException if getting the object fails.
153      *
154      * @see #getType()
155      * @see #getValue()
156      */
157     public Object getObject( final Location location ) throws BuildException
158     {
159         if ( location == null )
160         {
161             throw new NullPointerException( "location" );
162         }
163 
164         try
165         {
166             Object o = this.getValue();
167 
168             if ( o != null )
169             {
170                 if ( this.getType() != null && !String.class.equals( this.getType() ) )
171                 {
172                     try
173                     {
174                         o = this.getType().getConstructor( String.class ).newInstance( o );
175                     }
176                     catch ( final NoSuchMethodException e )
177                     {
178                         final Method valueOf = this.getType().getMethod( "valueOf", String.class );
179 
180                         if ( Modifier.isStatic( valueOf.getModifiers() )
181                                  && valueOf.getReturnType().equals( this.getType() ) )
182                         {
183                             o = valueOf.invoke( null, o );
184                         }
185                         else
186                         {
187                             throw new BuildException(
188                                 Messages.getMessage( "noSuchMethodCreatingValueObject", this.getType(),
189                                                      this.getValue(), this.getType().getSimpleName() ), e, location );
190 
191                         }
192                     }
193                 }
194             }
195             else if ( this.getType() != null )
196             {
197                 o = this.getType().newInstance();
198             }
199 
200             return o;
201         }
202         catch ( final NoSuchMethodException e )
203         {
204             throw new BuildException(
205                 Messages.getMessage( "noSuchMethodCreatingValueObject", this.getType(),
206                                      this.getValue(), this.getType().getSimpleName() ), e, location );
207 
208         }
209         catch ( final InstantiationException e )
210         {
211             throw new BuildException( Messages.getMessage( "failureCreatingValueObject", this.getType(),
212                                                            this.getValue() ), e, location );
213 
214         }
215         catch ( final IllegalAccessException e )
216         {
217             throw new BuildException( Messages.getMessage( "failureCreatingValueObject", this.getType(),
218                                                            this.getValue() ), e, location );
219 
220         }
221         catch ( final InvocationTargetException e )
222         {
223             throw new BuildException( Messages.getMessage( "failureCreatingValueObject", this.getType(),
224                                                            this.getValue() ), e, location );
225 
226         }
227     }
228 
229     /**
230      * Creates and returns a copy of this object.
231      *
232      * @return A copy of this object.
233      */
234     @Override
235     public KeyValueType clone()
236     {
237         try
238         {
239             return (KeyValueType) super.clone();
240         }
241         catch ( final CloneNotSupportedException e )
242         {
243             throw new AssertionError( e );
244         }
245     }
246 
247     /**
248      * Creates and returns a string representation of the object.
249      *
250      * @return A string representation of the object.
251      */
252     @Override
253     public String toString()
254     {
255         return ToStringBuilder.reflectionToString( this );
256     }
257 
258 }