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 }