001/* 002 * jDTAUS Core API 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.core.container; 022 023import java.io.Serializable; 024import java.util.Arrays; 025import java.util.Collection; 026import java.util.HashMap; 027import java.util.Map; 028 029/** 030 * Collection of arguments. 031 * 032 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 033 * @version $JDTAUS: Arguments.java 8743 2012-10-07 03:06:20Z schulte $ 034 */ 035public class Arguments extends ModelObject 036 implements Cloneable, Serializable 037{ 038 //--Constants--------------------------------------------------------------- 039 040 /** Serial version UID for backwards compatibility with 1.5.x classes. */ 041 private static final long serialVersionUID = -36607029931578091L; 042 043 //---------------------------------------------------------------Constants-- 044 //--Arguments--------------------------------------------------------------- 045 046 /** 047 * The arguments of the collection. 048 * @serial 049 */ 050 private Argument[] arguments; 051 052 /** 053 * Maps argument names to arguments. 054 * @serial 055 */ 056 private final Map names = new HashMap(); 057 058 /** 059 * Hash code. 060 * @serial 061 */ 062 private int hashCode; 063 064 /** Creates a new {@code Arguments} instance. */ 065 public Arguments() 066 { 067 super(); 068 } 069 070 /** 071 * Gets the arguments of the collection. 072 * 073 * @return the arguments of the collection. 074 */ 075 public Argument[] getArguments() 076 { 077 if ( this.arguments == null ) 078 { 079 this.arguments = new Argument[ 0 ]; 080 this.hashCode = 0; 081 } 082 083 return this.arguments; 084 } 085 086 /** 087 * Setter for property {@code arguments}. 088 * 089 * @param value the new arguments for the instance. 090 * 091 * @throws DuplicateArgumentException if {@code value} contains 092 * duplicate arguments. 093 */ 094 public void setArguments( final Argument[] value ) 095 { 096 this.names.clear(); 097 this.hashCode = 0; 098 this.arguments = null; 099 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}