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

Quick Search    Search Deep

Source code: nl/aidministrator/rdf/ral/rdbms/RecursiveSQLResourceIterator.java


1   /*  Sesame - Storage and Querying architecture for RDF and RDF Schema
2    *  Copyright (C) 2002 Aidministrator Nederland b.v.
3    *
4    *  Contact: 
5    *  Aidministrator Nederland b.v.
6    *  Julianaplein 14b 
7    *  3817 CS Amersfoort
8    *  The Netherlands
9    *  tel. +31(0)33 4659987
10   *  fax. +31(0)33 4659987
11   *  sesame@aidministrator.nl
12   *
13   *   http://www.aidministrator.nl/
14   *  
15   *  This library is free software; you can redistribute it and/or
16   *  modify it under the terms of the GNU Lesser General Public
17   *  License as published by the Free Software Foundation; either
18   *  version 2.1 of the License, or (at your option) any later version.
19   *
20   *  This library is distributed in the hope that it will be useful,
21   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   *  Lesser General Public License for more details.
24   *
25   *  You should have received a copy of the GNU Lesser General Public
26   *  License along with this library; if not, write to the Free Software
27   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28   */
29  
30  package nl.aidministrator.rdf.ral.rdbms;
31  
32  import nl.aidministrator.rdf.ral.ResourceIterator;
33  import nl.aidministrator.rdf.sail.model.*;
34  import java.util.*;
35  import java.sql.*;
36  
37  /**
38   * A ResourceIterator that executes SQL queries recursively by re-inserting
39   * part of the query's results into the query. The query should contain EXACTLY
40   * ONE IN-parameter (i.e. there is one '?' in the query) and the ResultSet
41   * should contain the following columns: id (int), namespace (String) and
42   * localname (String). The first value (the id) will be re-inserted into the
43   * query.
44   *
45   * @author Peter van 't Hof
46   * @version 1.4, 01/02/02
47   */
48  public class RecursiveSQLResourceIterator implements ResourceIterator {
49  
50  /*-----------+
51  | Variables  |
52  +-----------*/
53  
54    /**
55     * Connection to the database. */
56    protected Connection _databaseCon;
57    /**
58     * The query in the form of a PreparedStatement. */
59    protected PreparedStatement _statement;
60    /**
61     * Queue containing the results. */
62    protected Vector _resultsQueue;
63  
64    /**
65     * Stores Resources that have already been iterated. This prevents looping
66     * of the iterator and therefore supports multiple inheritance and loops
67     * in the class or property hierarchy.
68     */
69    protected Set _iterated;
70  
71  /*-------------+
72  | Constructors |
73  +-------------*/
74  
75    /**
76     * Constructor.
77     *
78     * @param databaseCon connection to the repository
79     * @param query query to execute
80     * @param initialResource initial resource who is returned first. Its id is
81     * then inserted in the query.
82     */
83    public RecursiveSQLResourceIterator(Connection databaseCon, String query, IdResource initialResource)
84      throws SQLException  {
85      _databaseCon = databaseCon;
86      _statement = _databaseCon.prepareStatement(query);
87      _resultsQueue = new Vector();
88      _iterated = new HashSet();
89      _add(initialResource);
90    }
91  
92  /*--------+
93  | Methods |
94  +--------*/
95  
96    private void _add(Resource resource) {
97      _resultsQueue.add(resource);
98      _iterated.add(resource);
99    }
100 
101   private void _fillQueue(int value) {
102     try {
103       _statement.setInt(1, value);
104       ResultSet rs = _statement.executeQuery();
105 
106       while (rs.next()) {
107         IdResource resource = new IdResource(rs.getInt(1), rs.getString(2), rs.getString(3));
108 
109         if (!_iterated.contains(resource)) {
110           _add(resource);
111         }
112       }
113       rs.close();
114     }
115     catch (SQLException e) {
116       // FIXME: should throw a RalException
117 
118       System.err.println("SQLException in _fillQueue(int)...");
119     }
120   }
121 
122   public boolean hasNext() {
123     return !_resultsQueue.isEmpty();
124   }
125 
126   /**
127    * Gets the next result.
128    *
129    * @exception NoSuchElementException If there are no more results
130    * available.
131    */
132   public Value next() {
133     if (hasNext()) {
134       IdResource result = (IdResource)_resultsQueue.remove(0);
135 
136       _fillQueue(result.getId());
137 
138       if (!hasNext()) {  // Close connection if there aren 't any results left.
139         close();
140       }
141       return result;
142     }
143     else {
144       throw new NoSuchElementException("No more resources...");
145     }
146   }
147 
148   public void close() {
149     _resultsQueue.clear();
150 
151     try {
152       if (_statement != null) {
153         _statement.close();
154       }
155       _databaseCon.close();
156     }
157     catch (SQLException e) {
158       // FIXME: should throw a RalException
159 
160       System.err.println("SQLException in close()...");
161     }
162   }
163 
164   /**
165    * Called by the garbage collector on SQLValueIterator when garbage
166    * collection determines that there are no more references to the
167    * SQLValueIterator.
168    */
169   protected void finalize() {
170     close();
171   }
172 }