Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/clra/web/OarsetSet.java


1   /*
2    * Copyright (c) Carnegie Lake Rowing Association 2002. All rights reserved.
3    * Distributed under the GPL license. See doc/COPYING.
4    * $RCSfile: OarsetSet.java,v $
5    * $Date: 2003/02/26 03:38:46 $
6    * $Revision: 1.4 $
7    */
8   
9   package com.clra.web;
10  
11  import com.clra.rowing.OarsetView;
12  import com.clra.util.DBConfiguration;
13  import com.clra.util.ValidationException;
14  import java.io.InputStream;
15  import java.net.URL;
16  import java.sql.Connection;
17  import java.sql.Driver;
18  import java.sql.DriverManager;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  import java.util.Collection;
23  import java.util.Comparator;
24  import java.util.GregorianCalendar;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.Map;
28  import java.util.Properties;
29  import java.util.SortedSet;
30  import java.util.TreeSet;
31  import org.apache.log4j.Category;
32  import org.apache.log4j.helpers.Loader;
33  
34  /**
35   * A collection of "finder" methods that return read-only, sorted sets
36   * of oarsets.<p>
37   * FIXME: when this class changes to a "Session-like" design, make sure
38   *
39   * @version $Id: OarsetSet.java,v 1.4 2003/02/26 03:38:46 rphall Exp $
40   * @author <a href="mailto:rphall@pluto.njcc.com">Rick Hall</a>
41   */
42  public class OarsetSet implements SortedSet {
43  
44    private final static String base = OarsetSet.class.getName();
45    private final static Category theLog = Category.getInstance( base );
46  
47    /**
48     * The current implementations return data in an in-memory collections.
49     * Since the underlaying Oarset database table may already be
50     * cached in memory, this can lead to duplicate caching. Future
51     * implementations should avoid in-memory duplicates by implementing
52     * SortedSet and Iterator methods directly in SQL.<p>
53     */
54    private final SortedSet data = new TreeSet();
55  
56    /**
57     * Finds all active oarsets of the CLRA. Oarsets are sorted by name
58     * (the natural comparator for oarsets).
59     */
60    public static OarsetSet findAllActiveOarsets()
61      throws WebException {
62  
63      Connection conn = null;
64      PreparedStatement stmt = null;
65      OarsetSet retVal = new OarsetSet();
66      try {
67        conn = DBConfiguration.getConnection();
68        stmt = conn.prepareStatement(
69            Configuration.SQL_OARSET_01,
70            ResultSet.TYPE_FORWARD_ONLY,
71            ResultSet.CONCUR_READ_ONLY);
72        loadOarsetSet( stmt, retVal.data );
73      }
74      catch(SQLException x) {
75        String msg = "SQLException: " + x.getMessage();
76        theLog.fatal( msg, x );
77        throw new WebException( msg );
78      }
79      finally {
80        DBConfiguration.closeSQLStatement( stmt );
81        DBConfiguration.closeSQLConnection( conn );
82      }
83      conn = null;
84      stmt = null;
85  
86      return retVal;
87    } // findAllActiveOarsets()
88  
89    /**
90     * Finds the oarset that has the given id. This "finder" returns at most
91     * one oarset.
92     */
93    public static OarsetView findOarsetById( int id )
94      throws WebException {
95  
96      Connection conn = null;
97      PreparedStatement stmt = null;
98      OarsetView retVal = null;
99      try {
100       conn = DBConfiguration.getConnection();
101       stmt = conn.prepareStatement(
102           Configuration.SQL_OARSET_02,
103           ResultSet.TYPE_FORWARD_ONLY,
104           ResultSet.CONCUR_READ_ONLY);
105       stmt.setInt( 1, id );
106       retVal = loadOarset( stmt );
107     }
108     catch(SQLException x) {
109       String msg = "SQLException for id == '" + id + "': "
110           + x.getMessage();
111       theLog.fatal( msg, x );
112       throw new WebException( msg );
113     }
114     finally {
115       DBConfiguration.closeSQLStatement( stmt );
116       DBConfiguration.closeSQLConnection( conn );
117     }
118     conn = null;
119     stmt = null;
120 
121     return retVal;
122   } // findOarsetById(int)
123 
124   /**
125    * Finds the oarset that has the given name. Names
126    * are unique, so this "finder" returns at most one oarset.
127    */
128   public static OarsetView findOarsetByName( String name )
129     throws WebException {
130 
131     Connection conn = null;
132     PreparedStatement stmt = null;
133     OarsetView retVal = null;
134     try {
135       conn = DBConfiguration.getConnection();
136       stmt = conn.prepareStatement(
137           Configuration.SQL_OARSET_03,
138           ResultSet.TYPE_FORWARD_ONLY,
139           ResultSet.CONCUR_READ_ONLY);
140       stmt.setString( 1, name );
141       retVal = loadOarset( stmt );
142     }
143     catch(SQLException x) {
144       String msg = "SQLException for name == '" + name + "': "
145           + x.getMessage();
146       theLog.fatal( msg, x );
147       throw new WebException( msg );
148     }
149     finally {
150       DBConfiguration.closeSQLStatement( stmt );
151       DBConfiguration.closeSQLConnection( conn );
152     }
153     conn = null;
154     stmt = null;
155 
156     return retVal;
157   } // findOarsetByName(String)
158 
159   /** OarsetSet instances are created by static "finder" methods */
160   private OarsetSet() {}
161 
162   /**
163    * Returns the comparator associated with this sorted set, or
164    * <tt>null</tt> if it uses its elements' natural ordering.
165    *
166    * @return the comparator associated with this sorted set, or
167    *          <tt>null</tt> if it uses its elements' natural ordering.
168    */
169   public Comparator comparator() {
170     return this.data.comparator();
171   }
172 
173   /**
174    * Returns a view of the portion of this sorted set whose elements range
175    * from <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>, exclusive.
176    *
177    * @param fromElement low endpoint (inclusive) of the subSet.
178    * @param toElement high endpoint (exclusive) of the subSet.
179    * @return a view of the specified range within this sorted set.
180    * 
181    * @throws ClassCastException if <tt>fromElement</tt> and
182    *         <tt>toElement</tt> are not <tt>Oarset</tt> objects.
183    * @throws IllegalArgumentException if <tt>fromElement</tt> is greater than
184    *         <tt>toElement</tt>; or if this set is itself a subSet, headSet,
185    *         or tailSet, and <tt>fromElement</tt> or <tt>toElement</tt> are
186    *         not within the specified range of the subSet, headSet, or
187    *         tailSet.
188    * @throws NullPointerException if <tt>fromElement</tt> or
189    *         <tt>toElement</tt> is <tt>null</tt>
190    */
191   public SortedSet subSet(Object fromElement, Object toElement) {
192     return this.data.subSet(fromElement,toElement);
193   }
194 
195   /**
196    * Returns a view of the portion of this sorted set whose elements are
197    * strictly less than <tt>toElement</tt>.
198    *
199    * @param toElement high endpoint (exclusive) of the headSet.
200    * @return a view of the specified initial range of this sorted set.
201    * @throws ClassCastException if <tt>toElement</tt> is not compatible
202    *         with this set's comparator (or, if the set has no comparator,
203    *         if <tt>toElement</tt> does not implement <tt>Comparable</tt>).
204    * @throws NullPointerException if <tt>toElement</tt> is <tt>null</tt>
205    * @throws IllegalArgumentException if this set is itself a subSet,
206    *         headSet, or tailSet, and <tt>toElement</tt> is not within the
207    *         specified range of the subSet, headSet, or tailSet.
208    */
209   public SortedSet headSet(Object toElement) {
210     return this.data.headSet(toElement);
211   }
212 
213   /**
214    * Returns a view of the portion of this sorted set whose elements are
215    * greater than or equal to <tt>fromElement</tt>.
216    *
217    * @param fromElement low endpoint (inclusive) of the tailSet.
218    * @return a view of the specified final range of this sorted set.
219    * @throws ClassCastException if <tt>fromElement</tt> is not compatible
220    *         with this set's comparator (or, if the set has no comparator,
221    *         if <tt>fromElement</tt> does not implement <tt>Comparable</tt>).
222    * @throws NullPointerException if <tt>fromElement</tt> is <tt>null</tt>
223    * @throws IllegalArgumentException if this set is itself a subSet,
224    *         headSet, or tailSet, and <tt>fromElement</tt> is not within the
225    *         specified range of the subSet, headSet, or tailSet.
226    */
227   public SortedSet tailSet(Object fromElement) {
228     return this.data.tailSet(fromElement);
229   }
230 
231   /**
232    * Returns the first (lowest) element currently in this sorted set.
233    *
234    * @return the first (lowest) element currently in this sorted set.
235    * @throws    NoSuchElementException sorted set is empty.
236    */
237   public Object first() {
238     return this.data.first();
239   }
240 
241   /**
242    * Returns the last (highest) element currently in this sorted set.
243    *
244    * @return the last (highest) element currently in this sorted set.
245    * @throws    NoSuchElementException sorted set is empty.
246    */
247   public Object last() {
248     return this.data.last();
249   }
250 
251   /**
252    * Returns the number of elements in this set (its cardinality).  If this
253    * set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
254    * <tt>Integer.MAX_VALUE</tt>.
255    *
256    * @return the number of elements in this set (its cardinality).
257    */
258   public int size() {
259     return this.data.size();
260   }
261 
262   /**
263    * Returns <tt>true</tt> if this set contains no elements.
264    *
265    * @return <tt>true</tt> if this set contains no elements.
266    */
267   public boolean isEmpty() {
268     return this.data.isEmpty();
269   }
270 
271   /**
272    * Returns <tt>true</tt> if this set contains the specified element.
273    *
274    * @param o element whose presence in this set is to be tested.
275    * @return <tt>true</tt> if this set contains the specified element.
276    */
277   public boolean contains(Object o) {
278    /*
279    * formally, returns <tt>true</tt> if and only if this set contains an
280    * element <code>e</code> such that <code>(o==null ? e==null :
281    * o.equals(e))</code>.
282    */
283     return this.data.contains(o);
284   }
285 
286   /**
287    * Returns an iterator over the (sorted) elements in this set.
288    *
289    * @return an iterator over the elements in this set.
290    */
291   public Iterator iterator() {
292     return this.data.iterator();
293   }
294 
295   /**
296    * Returns an array containing all of the elements in this set.
297    *
298    * @return an array containing all of the elements in this set.
299    */
300   public Object[] toArray() {
301     return this.data.toArray();
302   }
303 
304   /**
305    * Returns an array containing all of the elements in this set whose
306    * runtime type is that of the specified array.
307    *
308    * @param a the array into which the elements of this set are to
309    *    be stored, if it is big enough; otherwise, a new array of the
310    *     same runtime type is allocated for this purpose.
311    * @return an array containing the elements of this set.
312    * @throws    ArrayStoreException the runtime type of a is not a supertype
313    * of the runtime type of Oarset.
314    */
315   public Object[] toArray(Object a[]) {
316     return this.data.toArray(a);
317   }
318 
319   // Bulk Operations
320 
321   /**
322    * Returns <tt>true</tt> if this set contains all of the elements of the
323    * specified collection.
324    *
325    * @param c collection to be checked for containment in this set.
326    * @return <tt>true</tt> if this set contains all of the elements of the
327    *          specified collection.
328    */
329   public boolean containsAll(Collection c) {
330     return this.data.containsAll(c);
331   }
332 
333   // Comparison and hashing
334 
335   /**
336    * Compares the specified object with this set for equality.
337    *
338    * @param o Object to be compared for equality with this set.
339    * @return <tt>true</tt> if the specified Object is equal to this set.
340    */
341   public boolean equals(Object o) {
342     return this.data.equals(o);
343   }
344 
345   /**
346    * Returns the hash code value for this set.  The hash code of a set is
347    * defined to be the sum of the hash codes of the elements in the set.
348    *
349    * @return the hash code value for this set.
350    */
351   public int hashCode() {
352     return this.data.hashCode();
353   }
354 
355   // Modification Operations are not supported
356 
357   /**
358    * @throws UnsupportedOperationException since the <tt>add</tt> method is
359    *           not supported by this set.
360    */
361   public boolean add(Object o) {
362     throw new UnsupportedOperationException( "not supported" );
363   }
364 
365   /**
366    * @throws UnsupportedOperationException since the <tt>remove</tt> method is
367    *         not supported by this set.
368    */
369   public boolean remove(Object o) {
370     throw new UnsupportedOperationException( "not supported" );
371   }
372 
373   /**
374    * @throws UnsupportedOperationException since the <tt>addAll</tt> method is
375    *       not supported by this set.
376    */
377   public boolean addAll(Collection c) {
378     throw new UnsupportedOperationException( "not supported" );
379   }
380 
381   /**
382    * @throws UnsupportedOperationException since the <tt>retainAll</tt> method
383    *       is not supported by this Collection.
384    */
385   public boolean retainAll(Collection c) {
386     throw new UnsupportedOperationException( "not supported" );
387   }
388 
389   /**
390    * @throws UnsupportedOperationException since the <tt>removeAll</tt>
391    *       method is not supported by this Collection.
392   */
393   public boolean removeAll(Collection c) {
394     throw new UnsupportedOperationException( "not supported" );
395   }
396 
397   /**
398    * @throws UnsupportedOperationException since the <tt>clear</tt> method
399    *       is not supported by this set.
400    */
401   public void clear() {
402     throw new UnsupportedOperationException( "not supported" );
403   }
404 
405   // UTILITIES
406 
407   /** Loads an in-memory object from a database using the specified SQL */
408   private static OarsetView loadOarset( PreparedStatement stmt )
409     throws SQLException, WebException {
410 
411     // Initialize result set and return value to facilitate error recovery
412     ResultSet rs = null;
413     OarsetView retVal = null;
414 
415     try {
416       rs = stmt.executeQuery();
417       if ( rs.next() ) {
418         retVal = mapRowToOarset(rs);
419       } // if
420     }
421     finally {
422       if (rs != null) {
423         try {
424           rs.close();
425           rs = null;
426         }
427         catch(Exception x) {
428           theLog.error(x.getMessage(),x);
429         }
430       }
431     } // finally
432 
433     return retVal;
434   } // loadOarset(PreparedStatement)
435 
436   /** Loads an in-memory set from a database using the specified SQL */
437   private static void loadOarsetSet( PreparedStatement stmt, SortedSet set )
438     throws SQLException, WebException {
439 
440     // Initialize result set to facilitate error recovery
441     ResultSet rs = null;
442     int rowIdx = -1;
443 
444     try {
445       rs = stmt.executeQuery();
446       while ( rs.next() ) {
447         ++rowIdx;
448         OarsetView oarset = mapRowToOarset(rs);
449         set.add( oarset );
450       } // while
451     }
452     finally {
453       if (rs != null) {
454         try {
455           rs.close();
456           rs = null;
457         }
458         catch(Exception x) {
459           theLog.error(x.getMessage(),x);
460         }
461       }
462     } // finally
463   } // loadOarsetSet(PreparedStatement,SortedSet)
464 
465   /** Maps a row of SQL ResultSet to a OarsetView object */
466   private static OarsetView mapRowToOarset( ResultSet rs )
467     throws SQLException, WebException {
468 
469     final int oarset_id             = rs.getInt(    "oarset_id"   );
470     final String oarset_name        = rs.getString( "oarset_name" );
471     final int oarset_size           = rs.getInt(    "oarset_size" );
472     final String oarset_type        = rs.getString( "oarset_type" );
473 
474     if ( theLog.isDebugEnabled() ) {
475       theLog.debug( oarset_id + ", " + oarset_name );
476     }
477 
478     OarsetView retVal = null;
479     try {
480       retVal = new OarsetView( oarset_id, oarset_name, oarset_size, oarset_type );
481     }
482     catch( ValidationException x ) {
483       String msg = "Problem with data for oarset == '" + oarset_id + "', '"
484           + oarset_name + "': " + x.getMessage();
485       theLog.fatal( msg, x );
486       throw new WebException( msg );
487     }
488 
489     return retVal;
490   } // mapRowToOarset(ResultSet)
491 
492 } // OarsetSet
493 
494 /*
495  * $Log: OarsetSet.java,v $
496  * Revision 1.4  2003/02/26 03:38:46  rphall
497  * Added copyright and GPL license
498  *
499  * Revision 1.3  2003/02/19 22:38:40  rphall
500  * Removed gratuitous use of CLRA acronym
501  *
502  * Revision 1.2  2002/02/18 18:06:44  rphall
503  * Ran dos2unix to remove ^M (carriage return) from end of lines
504  */
505