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
 */
15
16
package edu.ucsb.nceas.metacat;
17
18
import java.sql.Connection;
19
import java.sql.SQLException;
20
import java.sql.PreparedStatement;
21
import java.sql.ResultSet;
22
import java.util.Enumeration;
23
import java.util.Vector;
24 374 bojilova
import java.util.Stack;
25 301 bojilova
26
/**
27
 * A suite of utility classes for quering DB
28
 */
29
public class DBUtil {
30
31
  private Connection	conn = null;
32
33
  /**
34
   * main routine used for testing.
35
   * <p>
36
   * Usage: java DBUtil <-dt|-dg>
37
   *
38
   * @param -dt for selecting all doctypes
39
   *        -dg for selecting DataGuide
40
   */
41
  static public void main(String[] args) {
42
43
     if (args.length < 1)
44
     {
45
        System.err.println("Wrong number of arguments!!!");
46 374 bojilova
        System.err.println("USAGE: java DBUtil <-dt | -dg [doctype]>");
47 301 bojilova
        return;
48
     } else {
49
        try {
50
51
          // Open a connection to the database
52
          MetaCatUtil   util = new MetaCatUtil();
53
          Connection dbconn = util.openDBConnection();
54
55
          DBUtil dbutil = new DBUtil( dbconn );
56
57
          if ( args[0].equals("-dt") ) {
58
            String doctypes = dbutil.readDoctypes();
59
            System.out.println(doctypes);
60
          } else if ( args[0].equals("-dg") ) {
61 315 bojilova
            String doctype = null;
62
            if ( args.length == 2 ) { doctype = args[1]; }
63
            String dataguide = dbutil.readDataGuide(doctype);
64 301 bojilova
            System.out.println(dataguide);
65
          } else {
66 374 bojilova
            System.err.println("USAGE: java DBUtil <-dt | -dg [doctype]>");
67 301 bojilova
          }
68
69
        } catch (Exception e) {
70
          System.err.println("EXCEPTION HANDLING REQUIRED");
71
          System.err.println(e.getMessage());
72
          e.printStackTrace(System.err);
73
        }
74
     }
75
  }
76
77
  /**
78
   * Construct an instance of the utility class
79
   */
80
  public DBUtil( Connection conn ) {
81
    this.conn = conn;
82
  }
83
84
  /**
85
   * read all doctypes from db connection in XML format
86
   * select all Public Id from xml_catalog table
87
   */
88
  public String readDoctypes()
89
        throws SQLException  {
90
91
    Vector doctypeList = new Vector();
92
93
    try {
94
95
      PreparedStatement pstmt =
96 413 bojilova
        conn.prepareStatement("SELECT public_id FROM xml_catalog " +
97
                              "WHERE entry_type = 'DTD'");
98 301 bojilova
99
      pstmt.execute();
100
      ResultSet rs = pstmt.getResultSet();
101
      boolean tableHasRows = rs.next();
102
      while (tableHasRows) {
103
           doctypeList.addElement(rs.getString(1));
104
           tableHasRows = rs.next();
105
      }
106
107
      pstmt.close();
108
109
    } catch (SQLException e) {
110
      System.out.println("DBUtil.readDoctypes(): " + e.getMessage());
111
      throw e;
112
    }
113
114
    return formatToXML(doctypeList, "doctype");
115
  }
116
117
  /**
118
   * read Data Guide for a given doctype from db connection in XML format
119
   * select all distinct absolute paths from xml_index table
120
   */
121
  public String readDataGuide( String doctype )
122
        throws SQLException  {
123
124
    Vector dataguide = new Vector();
125
    String path;
126 315 bojilova
    PreparedStatement pstmt;
127
128 301 bojilova
    try {
129
130 315 bojilova
        if ( doctype != null ) {
131
            pstmt = conn.prepareStatement("SELECT distinct path, nodeid " +
132
                                          "FROM xml_index " +
133
                                          "WHERE path LIKE '/%' " +
134
                                          "AND doctype LIKE ? " +
135
                                          "ORDER BY nodeid");
136
            pstmt.setString(1, doctype);
137
        } else {
138 374 bojilova
            pstmt = conn.prepareStatement("SELECT distinct path, doctype, nodeid " +
139 315 bojilova
                                          "FROM xml_index " +
140
                                          "WHERE path LIKE '/%' " +
141 374 bojilova
                                          "ORDER BY doctype, nodeid");
142 315 bojilova
        }
143
144
        pstmt.execute();
145
        ResultSet rs = pstmt.getResultSet();
146
        boolean tableHasRows = rs.next();
147
        while (tableHasRows) {
148
            path = rs.getString(1);
149
            if ( dataguide.indexOf(path) == -1 ) {
150
                dataguide.addElement(path);
151
            }
152
            tableHasRows = rs.next();
153
        }
154 301 bojilova
155 315 bojilova
        pstmt.close();
156 301 bojilova
157
    } catch (SQLException e) {
158 374 bojilova
      System.out.println("DBUtil.readDataGuide(): " + e.getMessage());
159 301 bojilova
      throw e;
160
    }
161
162 374 bojilova
    return formatToXML(dataguide);
163 301 bojilova
  }
164
165
  /**
166 374 bojilova
   * format the DataGuide ResultSet to XML
167
   */
168
  private String formatToXML(Vector resultset) {
169
170
    String currPath = null;
171
    String currElement = null;
172
    String prevElement = null;
173
    StringBuffer result = new StringBuffer();
174
    Enumeration rs = resultset.elements();
175
    Stack st = new Stack();
176
    int i = 0;
177
178
    result.append("<?xml version=\"1.0\"?>\n");
179
    result.append("<resultset>\n");
180
181
    while (rs.hasMoreElements()) {
182
        currPath = (String)rs.nextElement();
183
        while ( !In(prevElement, currPath) ) {
184
            currElement = (String)st.pop();
185
            result.append(pad(" ",i--) + "</" + currElement + ">\n");
186
            if ( st.empty() )
187
                prevElement = null;
188
            else
189
                prevElement = (String)st.peek();
190
        }
191
        currElement = getElementFromPath(currPath);
192
        st.push(currElement);
193
        result.append(pad(" ",++i) + "<" + currElement + ">\n");
194
        prevElement = currElement;
195
    }
196
    while ( !st.empty() ) {
197
        prevElement = (String)st.pop();
198
        result.append(pad(" ",i--) + "</" + prevElement + ">\n");
199
    }
200
    result.append("</resultset>\n");
201
202
    return result.toString();
203
  }
204
205
  /**
206
   * check if element is in path like /elem1/elem2/elemn3
207
   */
208
  private boolean In(String element, String path) {
209
210
    if ( element == null ) return true;
211
    return ( path.indexOf(element) != -1 );
212
  }
213
214
  /**
215
   * get last element from path like /elem1/elem2/elemn3
216
   */
217
  private String getElementFromPath(String path) {
218
219
    return ( path.substring(path.lastIndexOf("/")+1) );
220
  }
221
222
  /**
223
   * repeates the str n-times
224
   */
225
  private String pad(String str, int n) {
226
227
    String result = "";
228
    for ( int i = 0; i < n; i++ )
229
        result = result.concat(str);
230
231
    return result;
232
  }
233
234
  /**
235 301 bojilova
   * format the ResultSet to XML
236
   */
237
  private String formatToXML(Vector resultset, String tag) {
238
239
    String val = null;
240
    StringBuffer result = new StringBuffer();
241
    Enumeration rs = resultset.elements();
242
243
    result.append("<?xml version=\"1.0\"?>\n");
244
    result.append("<resultset>\n");
245
    while (rs.hasMoreElements()) {
246
        val = (String)rs.nextElement();
247
        result.append("   <" + tag + ">" + val + "</" + tag + ">\n");
248
    }
249
    result.append("</resultset>\n");
250
251
    return result.toString();
252
  }
253
254
255
}