001 /*
002 * jDTAUS - DTAUS fileformat.
003 * Copyright (c) 2005 Christian Schulte <cs@schulte.it>
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either
008 * version 2.1 of the License, or any later version.
009 *
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013 * Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public
016 * License along with this library; if not, write to the Free Software
017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
018 *
019 */
020 package org.jdtaus.core.container;
021
022 import java.io.Serializable;
023 import java.util.Arrays;
024 import java.util.Collection;
025 import java.util.HashMap;
026 import java.util.Map;
027
028 /**
029 * Collection of dependencies.
030 *
031 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
032 * @version $Id: Dependencies.java 2230 2007-03-26 01:37:48Z schulte2005 $
033 */
034 public class Dependencies implements Cloneable, Serializable
035 {
036
037 //--Dependencies------------------------------------------------------------
038
039 /**
040 * The dependencies held by the instance.
041 * @serial
042 */
043 private Dependency[] dependencies;
044
045 /**
046 * Maps dependency names to dependencies.
047 * @serial
048 */
049 private final Map names = new HashMap();
050
051 /**
052 * Hash code.
053 * @serial
054 */
055 private int hashCode;
056
057 /**
058 * Gets all dependencies of the collection.
059 *
060 * @return all dependencies of the collection.
061 */
062 public Dependency[] getDependencies()
063 {
064 if(this.dependencies == null)
065 {
066 this.dependencies = new Dependency[0];
067 this.hashCode = 0;
068 }
069
070 return this.dependencies;
071 }
072
073 /**
074 * Setter for property {@code dependencies}.
075 *
076 * @param value the new dependencies for the collection.
077 *
078 * @throws DuplicateDependencyException if {@code value} contains duplicate
079 * dependencies.
080 */
081 public void setDependencies(final Dependency[] value)
082 {
083 this.names.clear();
084 this.hashCode = 0;
085 this.dependencies = value;
086
087 if(value != null)
088 {
089 for(int i = value.length - 1; i >= 0; i--)
090 {
091 this.hashCode += value[i].hashCode();
092 if(this.names.put(value[i].getName(), value[i]) != null)
093 {
094 throw new DuplicateDependencyException(value[i].getName());
095 }
096
097 }
098 }
099 }
100
101 /**
102 * Gets a dependency for a name.
103 *
104 * @param name the name of the dependency to return.
105 *
106 * @return a reference to the dependency named {@code name}.
107 *
108 * @throws NullPointerException if {@code name} is {@code null}.
109 * @throws MissingDependencyException if no dependency matching {@code name}
110 * exists in the collection.
111 */
112 public Dependency getDependency(final String name)
113 {
114 if(name == null)
115 {
116 throw new NullPointerException("name");
117 }
118
119 final Dependency ret = (Dependency) this.names.get(name);
120
121 if(ret == null)
122 {
123 throw new MissingDependencyException(name);
124 }
125
126 return ret;
127 }
128
129 /**
130 * Gets a dependency for an index.
131 *
132 * @param index the index of the dependency to return.
133 *
134 * @return a reference to the dependency at {@code index}.
135 *
136 * @throws IndexOutOfBoundsException if {@code index} is negativ,
137 * greater than or equal to {@code size()}.
138 */
139 public final Dependency getDependency(final int index)
140 {
141 if(index < 0 || index >= this.size())
142 {
143 throw new ArrayIndexOutOfBoundsException(index);
144 }
145
146 return this.getDependencies()[index];
147 }
148
149 /**
150 * Gets the number of dependencies held by the instance.
151 *
152 * @return the number of dependencies held by the instance.
153 */
154 public final int size()
155 {
156 return this.getDependencies().length;
157 }
158
159 /**
160 * Creates a string representing the properties of the instance.
161 *
162 * @return a string representing the properties of the instance.
163 */
164 private String internalString()
165 {
166 final StringBuffer buf = new StringBuffer(200);
167 final Dependency[] dependencies = this.getDependencies();
168 for(int i = dependencies.length - 1; i >= 0; i--)
169 {
170 buf.append("\n\tdependency[").append(i).append("]=").
171 append(dependencies[i]);
172
173 }
174
175 return buf.toString();
176 }
177
178 //------------------------------------------------------------Dependencies--
179 //--Object------------------------------------------------------------------
180
181 /**
182 * Indicates whether some other object is equal to this one by comparing
183 * the values of all properties.
184 *
185 * @param o the reference object with which to compare.
186 *
187 * @return {@code true} if this object is the same as {@code o};
188 * {@code false} otherwise.
189 */
190 public boolean equals(final Object o)
191 {
192 boolean equal = this == o;
193
194 if(!equal && o instanceof Dependencies)
195 {
196 final Dependencies that = (Dependencies) o;
197 final Collection these = Arrays.asList(this.getDependencies());
198 final Collection those = Arrays.asList(that.getDependencies());
199
200 equal = these.size() == that.size() && these.containsAll(those);
201 }
202
203 return equal;
204 }
205
206 /**
207 * Returns a hash code value for this object.
208 *
209 * @return a hash code value for this object.
210 */
211 public int hashCode()
212 {
213 return this.hashCode;
214 }
215
216 /**
217 * Returns a string representation of the object.
218 *
219 * @return a string representation of the object.
220 */
221 public String toString()
222 {
223 return super.toString() + this.internalString();
224 }
225
226 /**
227 * Creates and returns a deep copy of this object.
228 *
229 * @return a clone of this instance.
230 */
231 public Object clone()
232 {
233 try
234 {
235 final Dependencies ret = (Dependencies) super.clone();
236 final Dependency[] deps = this.getDependencies();
237 ret.dependencies = new Dependency[deps.length];
238 for(int i = deps.length - 1; i >= 0; i--)
239 {
240 ret.dependencies[i] = (Dependency) deps[i].clone();
241 }
242
243 return ret;
244 }
245 catch(CloneNotSupportedException e)
246 {
247 throw new AssertionError(e);
248 }
249 }
250
251 //------------------------------------------------------------------Object--
252
253 }