View Javadoc

1   /*
2    *  jDTAUS Core API
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.core.container;
22  
23  import java.io.Serializable;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  /**
30   * Collection of arguments.
31   *
32   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
33   * @version $JDTAUS: Arguments.java 8743 2012-10-07 03:06:20Z schulte $
34   */
35  public class Arguments extends ModelObject
36      implements Cloneable, Serializable
37  {
38      //--Constants---------------------------------------------------------------
39  
40      /** Serial version UID for backwards compatibility with 1.5.x classes. */
41      private static final long serialVersionUID = -36607029931578091L;
42  
43      //---------------------------------------------------------------Constants--
44      //--Arguments---------------------------------------------------------------
45  
46      /**
47       * The arguments of the collection.
48       * @serial
49       */
50      private Argument[] arguments;
51  
52      /**
53       * Maps argument names to arguments.
54       * @serial
55       */
56      private final Map names = new HashMap();
57  
58      /**
59       * Hash code.
60       * @serial
61       */
62      private int hashCode;
63  
64      /** Creates a new {@code Arguments} instance. */
65      public Arguments()
66      {
67          super();
68      }
69  
70      /**
71       * Gets the arguments of the collection.
72       *
73       * @return the arguments of the collection.
74       */
75      public Argument[] getArguments()
76      {
77          if ( this.arguments == null )
78          {
79              this.arguments = new Argument[ 0 ];
80              this.hashCode = 0;
81          }
82  
83          return this.arguments;
84      }
85  
86      /**
87       * Setter for property {@code arguments}.
88       *
89       * @param value the new arguments for the instance.
90       *
91       * @throws DuplicateArgumentException if {@code value} contains
92       * duplicate arguments.
93       */
94      public void setArguments( final Argument[] value )
95      {
96          this.names.clear();
97          this.hashCode = 0;
98          this.arguments = null;
99  
100         if ( value != null )
101         {
102             for ( int i = 0; i < value.length; i++ )
103             {
104                 this.hashCode += value[i].hashCode();
105                 if ( this.names.put( value[i].getName(), value[i] ) != null )
106                 {
107                     this.names.clear();
108                     this.hashCode = 0;
109 
110                     throw new DuplicateArgumentException( value[i].getName() );
111                 }
112             }
113 
114             this.arguments = value;
115         }
116     }
117 
118     /**
119      * Gets an argument for a name.
120      *
121      * @param name the name of the argument to return.
122      *
123      * @return a reference to the argument with name {@code name}.
124      *
125      * @throws NullPointerException if {@code name} is {@code null}.
126      * @throws MissingArgumentException if no argument matching {@code name}
127      * exists in the collection.
128      */
129     public Argument getArgument( final String name )
130     {
131         if ( name == null )
132         {
133             throw new NullPointerException( "name" );
134         }
135 
136         final Argument ret = (Argument) this.names.get( name );
137 
138         if ( ret == null )
139         {
140             throw new MissingArgumentException( name );
141         }
142 
143         return ret;
144     }
145 
146     /**
147      * Gets an argument for an index.
148      *
149      * @param index the index of the argument to return.
150      *
151      * @return a reference to the argument at {@code index}.
152      *
153      * @throws IndexOutOfBoundsException if {@code index} is negativ,
154      * greater than or equal to {@code size()}.
155      */
156     public final Argument getArgument( final int index )
157     {
158         if ( index < 0 || index >= this.size() )
159         {
160             throw new ArrayIndexOutOfBoundsException( index );
161         }
162 
163         return this.getArguments()[index];
164     }
165 
166     /**
167      * Gets the number of arguments held by the instance.
168      *
169      * @return the number of arguments held by the instance.
170      */
171     public final int size()
172     {
173         return this.getArguments().length;
174     }
175 
176     /**
177      * Creates a string representing the properties of the instance.
178      *
179      * @return a string representing the properties of the instance.
180      */
181     private String internalString()
182     {
183         final StringBuffer buf = new StringBuffer( 200 ).append( '{' );
184         buf.append( this.internalString( this ) );
185 
186         final Argument[] args = this.getArguments();
187         for ( int i = args.length - 1; i >= 0; i-- )
188         {
189             buf.append( ", [" ).append( i ).append( "]=" ).
190                 append( args[i] );
191 
192         }
193 
194         buf.append( '}' );
195         return buf.toString();
196     }
197 
198     //----------------------------------------------------------Specifications--
199     //--Object------------------------------------------------------------------
200 
201     /**
202      * Indicates whether some other object is equal to this one by comparing
203      * the values of all properties.
204      *
205      * @param o the reference object with which to compare.
206      *
207      * @return {@code true} if this object is the same as {@code o};
208      * {@code false} otherwise.
209      */
210     public boolean equals( final Object o )
211     {
212         boolean equal = this == o;
213 
214         if ( !equal && o instanceof Arguments )
215         {
216             final Arguments that = (Arguments) o;
217             final Collection these = Arrays.asList( this.getArguments() );
218             final Collection those = Arrays.asList( that.getArguments() );
219 
220             equal = this.size() == that.size() && these.containsAll( those );
221         }
222 
223         return equal;
224     }
225 
226     /**
227      * Returns a hash code value for this object.
228      *
229      * @return a hash code value for this object.
230      */
231     public int hashCode()
232     {
233         return this.hashCode;
234     }
235 
236     /**
237      * Returns a string representation of the object.
238      *
239      * @return a string representation of the object.
240      */
241     public String toString()
242     {
243         return super.toString() + this.internalString();
244     }
245 
246     /**
247      * Creates and returns a deep copy of this object.
248      *
249      * @return a clone of this instance.
250      */
251     public Object clone()
252     {
253         try
254         {
255             final Arguments ret = (Arguments) super.clone();
256             final Argument[] args = this.getArguments();
257             final Argument[] cloned = new Argument[ args.length ];
258 
259             for ( int i = args.length - 1; i >= 0; i-- )
260             {
261                 cloned[i] = (Argument) args[i].clone();
262             }
263 
264             ret.setArguments( cloned );
265             return ret;
266         }
267         catch ( final CloneNotSupportedException e )
268         {
269             throw new AssertionError( e );
270         }
271     }
272 
273     //------------------------------------------------------------------Object--
274 }