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 dependencies.
31   *
32   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
33   * @version $JDTAUS: Dependencies.java 8743 2012-10-07 03:06:20Z schulte $
34   */
35  public class Dependencies extends ModelObject implements Cloneable, Serializable
36  {
37      //--Constants---------------------------------------------------------------
38  
39      /** Serial version UID for backwards compatibility with 1.0.x classes. */
40      private static final long serialVersionUID = 4207539567564921413L;
41  
42      //---------------------------------------------------------------Constants--
43      //--Dependencies------------------------------------------------------------
44  
45      /**
46       * The dependencies held by the instance.
47       * @serial
48       */
49      private Dependency[] dependencies;
50  
51      /**
52       * Maps dependency names to dependencies.
53       * @serial
54       */
55      private final Map names = new HashMap();
56  
57      /**
58       * Hash code.
59       * @serial
60       */
61      private int hashCode;
62  
63      /** Creates a new {@code Dependencies} instance. */
64      public Dependencies()
65      {
66          super();
67      }
68  
69      /**
70       * Gets all dependencies of the collection.
71       *
72       * @return all dependencies of the collection.
73       */
74      public Dependency[] getDependencies()
75      {
76          if ( this.dependencies == null )
77          {
78              this.dependencies = new Dependency[ 0 ];
79              this.hashCode = 0;
80          }
81  
82          return this.dependencies;
83      }
84  
85      /**
86       * Setter for property {@code dependencies}.
87       *
88       * @param value the new dependencies for the collection.
89       *
90       * @throws DuplicateDependencyException if {@code value} contains duplicate
91       * dependencies.
92       */
93      public void setDependencies( final Dependency[] value )
94      {
95          this.names.clear();
96          this.hashCode = 0;
97          this.dependencies = null;
98  
99          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 }