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 dependencies. 031 * 032 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 033 * @version $JDTAUS: Dependencies.java 8743 2012-10-07 03:06:20Z schulte $ 034 */ 035public class Dependencies extends ModelObject implements Cloneable, Serializable 036{ 037 //--Constants--------------------------------------------------------------- 038 039 /** Serial version UID for backwards compatibility with 1.0.x classes. */ 040 private static final long serialVersionUID = 4207539567564921413L; 041 042 //---------------------------------------------------------------Constants-- 043 //--Dependencies------------------------------------------------------------ 044 045 /** 046 * The dependencies held by the instance. 047 * @serial 048 */ 049 private Dependency[] dependencies; 050 051 /** 052 * Maps dependency names to dependencies. 053 * @serial 054 */ 055 private final Map names = new HashMap(); 056 057 /** 058 * Hash code. 059 * @serial 060 */ 061 private int hashCode; 062 063 /** Creates a new {@code Dependencies} instance. */ 064 public Dependencies() 065 { 066 super(); 067 } 068 069 /** 070 * Gets all dependencies of the collection. 071 * 072 * @return all dependencies of the collection. 073 */ 074 public Dependency[] getDependencies() 075 { 076 if ( this.dependencies == null ) 077 { 078 this.dependencies = new Dependency[ 0 ]; 079 this.hashCode = 0; 080 } 081 082 return this.dependencies; 083 } 084 085 /** 086 * Setter for property {@code dependencies}. 087 * 088 * @param value the new dependencies for the collection. 089 * 090 * @throws DuplicateDependencyException if {@code value} contains duplicate 091 * dependencies. 092 */ 093 public void setDependencies( final Dependency[] value ) 094 { 095 this.names.clear(); 096 this.hashCode = 0; 097 this.dependencies = null; 098 099 if ( value != null ) 100 { 101 for ( int i = value.length - 1; i >= 0; i-- ) 102 { 103 this.hashCode += value[i].hashCode(); 104 if ( this.names.put( value[i].getName(), value[i] ) != null ) 105 { 106 this.names.clear(); 107 this.hashCode = 0; 108 109 throw new DuplicateDependencyException( value[i].getName() ); 110 } 111 112 } 113 114 this.dependencies = value; 115 } 116 } 117 118 /** 119 * Gets a dependency for a name. 120 * 121 * @param name the name of the dependency to return. 122 * 123 * @return a reference to the dependency named {@code name}. 124 * 125 * @throws NullPointerException if {@code name} is {@code null}. 126 * @throws MissingDependencyException if no dependency matching {@code name} 127 * exists in the collection. 128 */ 129 public Dependency getDependency( final String name ) 130 { 131 if ( name == null ) 132 { 133 throw new NullPointerException( "name" ); 134 } 135 136 final Dependency ret = (Dependency) this.names.get( name ); 137 138 if ( ret == null ) 139 { 140 throw new MissingDependencyException( name ); 141 } 142 143 return ret; 144 } 145 146 /** 147 * Gets a dependency for an index. 148 * 149 * @param index the index of the dependency to return. 150 * 151 * @return a reference to the dependency at {@code index}. 152 * 153 * @throws IndexOutOfBoundsException if {@code index} is negativ, 154 * greater than or equal to {@code size()}. 155 */ 156 public final Dependency getDependency( final int index ) 157 { 158 if ( index < 0 || index >= this.size() ) 159 { 160 throw new ArrayIndexOutOfBoundsException( index ); 161 } 162 163 return this.getDependencies()[index]; 164 } 165 166 /** 167 * Gets the number of dependencies held by the instance. 168 * 169 * @return the number of dependencies held by the instance. 170 */ 171 public final int size() 172 { 173 return this.getDependencies().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 Dependency[] deps = this.getDependencies(); 187 for ( int i = deps.length - 1; i >= 0; i-- ) 188 { 189 buf.append( ", [" ).append( i ).append( "]=" ). 190 append( deps[i] ); 191 192 } 193 buf.append( '}' ); 194 return buf.toString(); 195 } 196 197 //------------------------------------------------------------Dependencies-- 198 //--Object------------------------------------------------------------------ 199 200 /** 201 * Indicates whether some other object is equal to this one by comparing 202 * the values of all properties. 203 * 204 * @param o the reference object with which to compare. 205 * 206 * @return {@code true} if this object is the same as {@code o}; 207 * {@code false} otherwise. 208 */ 209 public boolean equals( final Object o ) 210 { 211 boolean equal = this == o; 212 213 if ( !equal && o instanceof Dependencies ) 214 { 215 final Dependencies that = (Dependencies) o; 216 final Collection these = Arrays.asList( this.getDependencies() ); 217 final Collection those = Arrays.asList( that.getDependencies() ); 218 219 equal = this.size() == that.size() && these.containsAll( those ); 220 } 221 222 return equal; 223 } 224 225 /** 226 * Returns a hash code value for this object. 227 * 228 * @return a hash code value for this object. 229 */ 230 public int hashCode() 231 { 232 return this.hashCode; 233 } 234 235 /** 236 * Returns a string representation of the object. 237 * 238 * @return a string representation of the object. 239 */ 240 public String toString() 241 { 242 return super.toString() + this.internalString(); 243 } 244 245 /** 246 * Creates and returns a deep copy of this object. 247 * 248 * @return a clone of this instance. 249 */ 250 public Object clone() 251 { 252 try 253 { 254 final Dependencies ret = (Dependencies) super.clone(); 255 final Dependency[] deps = this.getDependencies(); 256 final Dependency[] cloned = new Dependency[ deps.length ]; 257 for ( int i = deps.length - 1; i >= 0; i-- ) 258 { 259 cloned[i] = (Dependency) deps[i].clone(); 260 } 261 262 ret.setDependencies( cloned ); 263 return ret; 264 } 265 catch ( final CloneNotSupportedException e ) 266 { 267 throw new AssertionError( e ); 268 } 269 } 270 271 //------------------------------------------------------------------Object-- 272}