001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
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;
009: * version 2.1 of the License.
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: package org.geotools.index.rtree.database;
017:
018: import org.geotools.index.TreeException;
019: import org.geotools.index.rtree.Entry;
020: import org.geotools.index.rtree.Node;
021: import java.io.ByteArrayInputStream;
022: import java.io.IOException;
023: import java.sql.Connection;
024: import java.sql.PreparedStatement;
025: import java.sql.SQLException;
026: import javax.sql.DataSource;
027:
028: /**
029: * DOCUMENT ME!
030: *
031: * @author Tommaso Nolli
032: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/main/java/org/geotools/index/rtree/database/DatabaseNode.java $
033: */
034: public class DatabaseNode extends Node {
035: private DataSource dataSource;
036: private Dialect dialect;
037: private String tableName;
038: private Integer parentId;
039: private Integer pageId;
040:
041: /**
042: * Constructor
043: *
044: * @param maxNodeEntries
045: * @param ds
046: * @param dialect
047: * @param tableName
048: */
049: public DatabaseNode(int maxNodeEntries, DataSource ds,
050: Dialect dialect, String tableName) {
051: super (maxNodeEntries);
052: this .dataSource = ds;
053: this .dialect = dialect;
054: this .tableName = tableName;
055: }
056:
057: /**
058: * Constructor that retrieves data from the db
059: *
060: * @param maxNodeEntries
061: * @param ds
062: * @param dialect
063: * @param tableName
064: * @param pageId
065: *
066: * @throws TreeException DOCUMENT ME!
067: */
068: public DatabaseNode(int maxNodeEntries, DataSource ds,
069: Dialect dialect, String tableName, Integer pageId)
070: throws TreeException {
071: this (maxNodeEntries, ds, dialect, tableName);
072:
073: // TODO Retrieve the data
074: }
075:
076: /**
077: * @see org.geotools.index.rtree.Node#doSave()
078: */
079: protected void doSave() throws TreeException {
080: // TODO Fill this array
081: byte[] bytes = null;
082:
083: Connection cnn = null;
084:
085: try {
086: cnn = this .dataSource.getConnection();
087:
088: if (this .pageId == null) {
089: this .doInsert(cnn, bytes);
090: } else {
091: this .doUpdate(cnn, bytes);
092: }
093: } catch (SQLException e) {
094: throw new TreeException(e);
095: } catch (IOException e) {
096: throw new TreeException(e);
097: } finally {
098: try {
099: cnn.close();
100: } catch (Exception ee) {
101: }
102: }
103: }
104:
105: /**
106: * Inserts this Node into the database
107: *
108: * @param cnn
109: * @param bytes
110: *
111: * @throws SQLException
112: * @throws IOException
113: */
114: protected void doInsert(Connection cnn, byte[] bytes)
115: throws SQLException, IOException {
116: PreparedStatement pst = null;
117:
118: try {
119: int i = 1;
120: int id = dialect.getNextPageId(cnn, tableName);
121: ByteArrayInputStream is = new ByteArrayInputStream(bytes);
122: pst = cnn
123: .prepareStatement(dialect.getInsertPage(tableName));
124: pst.setInt(i++, id);
125: pst.setString(i++, this .isLeaf() ? "Y" : "N");
126: pst.setBinaryStream(i++, is, bytes.length);
127: pst.executeUpdate();
128:
129: cnn.commit();
130: is.close();
131:
132: this .pageId = new Integer(id);
133: } catch (SQLException e) {
134: try {
135: cnn.rollback();
136: } catch (Exception ee) {
137: }
138: } finally {
139: try {
140: pst.close();
141: } catch (Exception ee) {
142: }
143: }
144: }
145:
146: /**
147: * Update the databse with this Node informations
148: *
149: * @param cnn
150: * @param bytes
151: *
152: * @throws SQLException
153: * @throws IOException
154: */
155: protected void doUpdate(Connection cnn, byte[] bytes)
156: throws SQLException, IOException {
157: PreparedStatement pst = null;
158:
159: try {
160: int i = 1;
161: ByteArrayInputStream is = new ByteArrayInputStream(bytes);
162: pst = cnn
163: .prepareStatement(dialect.getUpdatePage(tableName));
164: pst.setString(i++, this .isLeaf() ? "Y" : "N");
165: pst.setBinaryStream(i++, is, bytes.length);
166: pst.setInt(i++, this .pageId.intValue());
167: pst.executeUpdate();
168:
169: cnn.commit();
170: is.close();
171: } catch (SQLException e) {
172: try {
173: cnn.rollback();
174: } catch (Exception ee) {
175: }
176: } finally {
177: try {
178: pst.close();
179: } catch (Exception ee) {
180: }
181: }
182: }
183:
184: /**
185: * @see org.geotools.index.rtree.Node#getEntry(org.geotools.index.rtree.Node)
186: */
187: protected Entry getEntry(Node node) {
188: DatabaseNode dn = (DatabaseNode) node;
189:
190: Entry ret = null;
191: Integer id = null;
192:
193: for (int i = 0; i < this .getEntriesCount(); i++) {
194: id = (Integer) this .entries[i].getData();
195:
196: if (id.equals(dn.getPageId())) {
197: ret = this .entries[i];
198:
199: break;
200: }
201: }
202:
203: return ret;
204: }
205:
206: /**
207: * @see org.geotools.index.rtree.Node#getParent()
208: */
209: public Node getParent() throws TreeException {
210: if (this .parentId == null) {
211: return null;
212: }
213:
214: return new DatabaseNode(this .maxNodeEntries, this .dataSource,
215: this .dialect, this .tableName, this .parentId);
216: }
217:
218: /**
219: * @see org.geotools.index.rtree.Node#setParent(org.geotools.index.rtree.Node)
220: */
221: public void setParent(Node node) {
222: this .parentId = ((DatabaseNode) node).getPageId();
223: }
224:
225: /**
226: * DOCUMENT ME!
227: *
228: * @return Returns the pageId.
229: */
230: public Integer getPageId() {
231: return this .pageId;
232: }
233:
234: /**
235: * DOCUMENT ME!
236: *
237: * @param pageId The pageId to set.
238: */
239: public void setPageId(Integer pageId) {
240: this.pageId = pageId;
241: }
242: }
|