Project

General

Profile

1 301 bojilova
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements utility methods like:
4
 *             1/ Reding all doctypes from db connection
5
 *             2/ Reading Lore type Data Guide from db connection
6
 *  Copyright: 2000 Regents of the University of California and the
7
 *             National Center for Ecological Analysis and Synthesis
8 315 bojilova
 *    Authors: Jivka Bojilova
9 349 jones
 *    Release: @release@
10 301 bojilova
 *
11
 *   '$Author$'
12
 *     '$Date$'
13
 * '$Revision$'
14 669 jones
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program 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
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 301 bojilova
 */
29
30
package edu.ucsb.nceas.metacat;
31
32
import java.sql.Connection;
33
import java.sql.SQLException;
34
import java.sql.PreparedStatement;
35
import java.sql.ResultSet;
36
import java.util.Enumeration;
37
import java.util.Vector;
38 374 bojilova
import java.util.Stack;
39 301 bojilova
40
/**
41
 * A suite of utility classes for quering DB
42
 */
43
public class DBUtil {
44
45
  private Connection	conn = null;
46
47
  /**
48
   * main routine used for testing.
49
   * <p>
50
   * Usage: java DBUtil <-dt|-dg>
51
   *
52
   * @param -dt for selecting all doctypes
53
   *        -dg for selecting DataGuide
54
   */
55
  static public void main(String[] args) {
56
57
     if (args.length < 1)
58
     {
59
        System.err.println("Wrong number of arguments!!!");
60 374 bojilova
        System.err.println("USAGE: java DBUtil <-dt | -dg [doctype]>");
61 301 bojilova
        return;
62
     } else {
63
        try {
64
65
          // Open a connection to the database
66
          MetaCatUtil   util = new MetaCatUtil();
67
          Connection dbconn = util.openDBConnection();
68
69
          DBUtil dbutil = new DBUtil( dbconn );
70
71
          if ( args[0].equals("-dt") ) {
72
            String doctypes = dbutil.readDoctypes();
73
            System.out.println(doctypes);
74
          } else if ( args[0].equals("-dg") ) {
75 315 bojilova
            String doctype = null;
76
            if ( args.length == 2 ) { doctype = args[1]; }
77
            String dataguide = dbutil.readDataGuide(doctype);
78 301 bojilova
            System.out.println(dataguide);
79
          } else {
80 374 bojilova
            System.err.println("USAGE: java DBUtil <-dt | -dg [doctype]>");
81 301 bojilova
          }
82
83
        } catch (Exception e) {
84 675 berkley
          System.err.println("error in DBUtil.main");
85 301 bojilova
          System.err.println(e.getMessage());
86
          e.printStackTrace(System.err);
87
        }
88
     }
89
  }
90
91
  /**
92
   * Construct an instance of the utility class
93
   */
94
  public DBUtil( Connection conn ) {
95
    this.conn = conn;
96
  }
97
98
  /**
99
   * read all doctypes from db connection in XML format
100
   * select all Public Id from xml_catalog table
101
   */
102
  public String readDoctypes()
103
        throws SQLException  {
104
105
    Vector doctypeList = new Vector();
106
107
    try {
108
109
      PreparedStatement pstmt =
110 413 bojilova
        conn.prepareStatement("SELECT public_id FROM xml_catalog " +
111
                              "WHERE entry_type = 'DTD'");
112 301 bojilova
113
      pstmt.execute();
114
      ResultSet rs = pstmt.getResultSet();
115
      boolean tableHasRows = rs.next();
116
      while (tableHasRows) {
117
           doctypeList.addElement(rs.getString(1));
118
           tableHasRows = rs.next();
119
      }
120
121
      pstmt.close();
122
123
    } catch (SQLException e) {
124
      System.out.println("DBUtil.readDoctypes(): " + e.getMessage());
125
      throw e;
126
    }
127
128
    return formatToXML(doctypeList, "doctype");
129
  }
130
131
  /**
132
   * read Data Guide for a given doctype from db connection in XML format
133
   * select all distinct absolute paths from xml_index table
134
   */
135
  public String readDataGuide( String doctype )
136
        throws SQLException  {
137
138
    Vector dataguide = new Vector();
139
    String path;
140 315 bojilova
    PreparedStatement pstmt;
141
142 301 bojilova
    try {
143
144 315 bojilova
        if ( doctype != null ) {
145
            pstmt = conn.prepareStatement("SELECT distinct path, nodeid " +
146
                                          "FROM xml_index " +
147
                                          "WHERE path LIKE '/%' " +
148
                                          "AND doctype LIKE ? " +
149
                                          "ORDER BY nodeid");
150
            pstmt.setString(1, doctype);
151
        } else {
152 374 bojilova
            pstmt = conn.prepareStatement("SELECT distinct path, doctype, nodeid " +
153 315 bojilova
                                          "FROM xml_index " +
154
                                          "WHERE path LIKE '/%' " +
155 374 bojilova
                                          "ORDER BY doctype, nodeid");
156 315 bojilova
        }
157
158
        pstmt.execute();
159
        ResultSet rs = pstmt.getResultSet();
160
        boolean tableHasRows = rs.next();
161
        while (tableHasRows) {
162
            path = rs.getString(1);
163
            if ( dataguide.indexOf(path) == -1 ) {
164
                dataguide.addElement(path);
165
            }
166
            tableHasRows = rs.next();
167
        }
168 301 bojilova
169 315 bojilova
        pstmt.close();
170 301 bojilova
171
    } catch (SQLException e) {
172 374 bojilova
      System.out.println("DBUtil.readDataGuide(): " + e.getMessage());
173 301 bojilova
      throw e;
174
    }
175
176 374 bojilova
    return formatToXML(dataguide);
177 301 bojilova
  }
178
179
  /**
180 374 bojilova
   * format the DataGuide ResultSet to XML
181
   */
182
  private String formatToXML(Vector resultset) {
183
184
    String currPath = null;
185
    String currElement = null;
186
    String prevElement = null;
187
    StringBuffer result = new StringBuffer();
188
    Enumeration rs = resultset.elements();
189
    Stack st = new Stack();
190
    int i = 0;
191
192
    result.append("<?xml version=\"1.0\"?>\n");
193
    result.append("<resultset>\n");
194
195
    while (rs.hasMoreElements()) {
196
        currPath = (String)rs.nextElement();
197
        while ( !In(prevElement, currPath) ) {
198
            currElement = (String)st.pop();
199
            result.append(pad(" ",i--) + "</" + currElement + ">\n");
200
            if ( st.empty() )
201
                prevElement = null;
202
            else
203
                prevElement = (String)st.peek();
204
        }
205
        currElement = getElementFromPath(currPath);
206
        st.push(currElement);
207
        result.append(pad(" ",++i) + "<" + currElement + ">\n");
208
        prevElement = currElement;
209
    }
210
    while ( !st.empty() ) {
211
        prevElement = (String)st.pop();
212
        result.append(pad(" ",i--) + "</" + prevElement + ">\n");
213
    }
214
    result.append("</resultset>\n");
215
216
    return result.toString();
217
  }
218
219
  /**
220
   * check if element is in path like /elem1/elem2/elemn3
221
   */
222
  private boolean In(String element, String path) {
223
224
    if ( element == null ) return true;
225
    return ( path.indexOf(element) != -1 );
226
  }
227
228
  /**
229
   * get last element from path like /elem1/elem2/elemn3
230
   */
231
  private String getElementFromPath(String path) {
232
233
    return ( path.substring(path.lastIndexOf("/")+1) );
234
  }
235
236
  /**
237
   * repeates the str n-times
238
   */
239
  private String pad(String str, int n) {
240
241
    String result = "";
242
    for ( int i = 0; i < n; i++ )
243
        result = result.concat(str);
244
245
    return result;
246
  }
247
248
  /**
249 301 bojilova
   * format the ResultSet to XML
250
   */
251
  private String formatToXML(Vector resultset, String tag) {
252
253
    String val = null;
254
    StringBuffer result = new StringBuffer();
255
    Enumeration rs = resultset.elements();
256
257
    result.append("<?xml version=\"1.0\"?>\n");
258
    result.append("<resultset>\n");
259
    while (rs.hasMoreElements()) {
260
        val = (String)rs.nextElement();
261
        result.append("   <" + tag + ">" + val + "</" + tag + ">\n");
262
    }
263
    result.append("</resultset>\n");
264
265
    return result.toString();
266
  }
267
268
269
}