Project

General

Profile

1 72 bojilova
/**
2
 *        Name: DBSAXHandler.java
3
 *     Purpose: A Class that implements org.xml.sax.EntityResolver interface
4
 *              for resolving external entities
5
 *   Copyright: 2000 Regents of the University of California and the
6
 *              National Center for Ecological Analysis and Synthesis
7
 *     Authors: Jivka Bojilova
8
 *
9
 *     Version: '$Id$'
10
 */
11
12 74 jones
package edu.ucsb.nceas.metacat;
13 72 bojilova
14
import org.xml.sax.*;
15
16
import java.sql.*;
17
import java.net.URL;
18
import java.net.MalformedURLException;
19
import java.util.Stack;
20
import java.util.EmptyStackException;
21
22
/**
23
 * A database aware Class implementing EntityResolver interface for the SAX parser to
24
 * call when processing the XML stream and intercepting any external entities
25
 * (including the external DTD subset and external parameter entities, if any) before including them.
26
 */
27
public class DBEntityResolver implements EntityResolver
28
{
29
30
   static String doctype = null;
31
   static Connection conn = null;
32
   private int pIdCounter = 0;
33
   private long currentElementNo;
34
35
   /** Construct an instance of the DBEntityResolver clas
36
    *
37
    * @param conn the JDBC connection to which information is written
38
    */
39
   public DBEntityResolver(Connection conn)
40
   {
41
      this.conn = conn;
42
   }
43
44
45
   /** The Parser call this method before opening any external entity
46
     * except the top-level document entity (including the external DTD subset,
47
     * external entities referenced within the DTD, and external entities referenced
48
     * within the document element)*/
49
   public InputSource resolveEntity (String publicId, String systemId)
50
            throws MalformedURLException
51
   {
52
     String dbSystemId;
53
54
     if (publicId != null) {
55
        pIdCounter += 1;
56
        currentElementNo = DBSAXHandler.elementNo;
57
        System.out.println("from DBEntityResolver: current element is " + DBSAXHandler.elementNo);
58
        System.out.println("from DBEntityResolver: " + pIdCounter + " " + publicId);
59
        // look at the db XML Catalog and get dbSystemId by this publicId
60
        if (currentElementNo == 0) {
61
            doctype = publicId;
62
            dbSystemId = getDTDSystemID (conn, publicId);
63
            if (dbSystemId == "")
64
                // register publicId in db and use the provided systemId
65
                if (systemId != "") {
66
                    System.out.println("from DBEntityResolver: " + systemId);
67
                    new URL(systemId);
68
                    registerDTDPublicID (conn, publicId, systemId);
69
                    return null;
70
                }
71
            new URL(dbSystemId);
72
            System.out.println("from DBEntityResolver: db System ID: " + dbSystemId);
73
            return new InputSource(dbSystemId);
74
        }
75
        else {
76
            // look at the db XML Catalog and get dbSystemId by this publicId for a given doctype
77
            dbSystemId = getEntitySystemID (conn, doctype, publicId);
78
            if (dbSystemId == "")
79
                // register publicId in db for a given doctype and use the provided systemId
80
                if (systemId != "") {
81
                    System.out.println("from DBEntityResolver: " + systemId);
82
                    new URL(systemId);
83
                    registerEntityPublicID (conn, doctype, publicId, systemId);
84
                    return null;
85
                }
86
            new URL(dbSystemId);
87
            System.out.println("from DBEntityResolver: db System ID: " + dbSystemId);
88
            return new InputSource(dbSystemId);
89
        }
90
     }
91
     if ( systemId != null) {
92
        System.out.println("from DBEntityResolver: " + systemId);
93
        new URL(systemId);
94
     }
95
96
     // use the default behaviour
97
     return null;
98
   }
99
100
   /** Look at db XML Catalog to get System ID (if any) for that Public ID.
101
     * Return empty string if there are not */
102
   private String getDTDSystemID (Connection conn, String publicId)
103
   {
104
        String system_id = "";
105
        Statement stmt;
106
        try {
107
          stmt = conn.createStatement();
108
          stmt.execute("SELECT system_id FROM xml_catalog_entities a, xml_catalog b " +
109
                       "WHERE a.entity_type = 'DTD' AND a.source_doctype = b.doctype AND b.doctype = '" + publicId + "'");
110
          try {
111
            ResultSet rs = stmt.getResultSet();
112
            try {
113
              boolean tableHasRows = rs.next();
114
              if (tableHasRows) {
115
                try {
116
                  system_id = rs.getString(1);
117
                } catch (SQLException e) {
118
                  System.out.println("DBEntityResolver.getDTDSystemID() - Error with getString: " + e.getMessage());
119
                }
120
              }
121
            } catch (SQLException e) {
122
              System.out.println("DBEntityResolver.getDTDSystemID() - Error with next: " + e.getMessage());
123
            }
124
          } catch (SQLException e) {
125
            System.out.println("DBEntityResolver.getDTDSystemID() - Error with getrset: " + e.getMessage());
126
          }
127
          stmt.close();
128
        } catch (SQLException e) {
129
          System.out.println("DBEntityResolver.getDTDSystemID() - Error getting id: " + e.getMessage());
130
        }
131
132
        // return the selected System ID
133
        return system_id;
134
   }
135
136
   /** Register Public ID in db XML Catalog */
137
   private void registerDTDPublicID (Connection conn, String publicId, String systemId)
138
   {
139
        try {
140
          conn.setAutoCommit(false);
141
          PreparedStatement pstmt;
142
          pstmt = conn.prepareStatement(
143
                "INSERT INTO xml_catalog (doctype) VALUES (?)");
144
          // Bind the values to the query
145
          pstmt.setString(1, publicId);
146
          // Do the insertion
147
          pstmt.execute();
148
          pstmt.close();
149
          pstmt = conn.prepareStatement(
150
                "INSERT INTO xml_catalog_entities (entity_id, entity_type, source_doctype, system_id) " +
151
                "VALUES (null, 'DTD', ?, ?)");
152
          // Bind the values to the query
153
          pstmt.setString(1, publicId);
154
          pstmt.setString(2, systemId);
155
          // Do the insertion
156
          pstmt.execute();
157
          pstmt.close();
158
          conn.commit();
159
          conn.setAutoCommit(true);
160
        } catch (SQLException e) {
161
          System.out.println(e.getMessage());
162
        }
163
   }
164
165
   /** Look at db XML Catalog to get System ID (if any) for that Public ID and doctype.
166
     * Return empty string if there are not */
167
   private String getEntitySystemID (Connection conn, String doctype, String publicId)
168
   {
169
        String system_id = "";
170
        Statement stmt;
171
        try {
172
          stmt = conn.createStatement();
173
          stmt.execute("SELECT system_id FROM xml_catalog_entities " +
174
                       "WHERE entity_type = 'ENTITY' AND source_doctype = '" + doctype + "' AND public_id = '" + publicId + "'");
175
          try {
176
            ResultSet rs = stmt.getResultSet();
177
            try {
178
              boolean tableHasRows = rs.next();
179
              if (tableHasRows) {
180
                try {
181
                  system_id = rs.getString(1);
182
                } catch (SQLException e) {
183
                  System.out.println("DBEntityResolver.getEntitySystemID() - Error with getString: " + e.getMessage());
184
                }
185
              }
186
            } catch (SQLException e) {
187
              System.out.println("DBEntityResolver.getEntitySystemID() - Error with next: " + e.getMessage());
188
            }
189
          } catch (SQLException e) {
190
            System.out.println("DBEntityResolver.getEntitySystemID() - Error with getrset: " + e.getMessage());
191
          }
192
          stmt.close();
193
        } catch (SQLException e) {
194
          System.out.println("DBEntityResolver.getEntitySystemID() - Error getting id: " + e.getMessage());
195
        }
196
197
        // return the selected System ID number
198
        return system_id;
199
   }
200
201
   /** Register Public ID in db XML Catalog */
202
   private void registerEntityPublicID (Connection conn, String doctype, String publicId, String systemId)
203
   {
204
        try {
205
          conn.setAutoCommit(false);
206
          PreparedStatement pstmt;
207
          pstmt = conn.prepareStatement(
208
                "INSERT INTO xml_catalog_entities (entity_id, entity_name, entity_type, source_doctype, public_id, system_id) " +
209
                "VALUES (null, null, 'ENTITY', ?, ?, ?)");
210
          // Bind the values to the query
211
          pstmt.setString(1, doctype);
212
          pstmt.setString(2, publicId);
213
          pstmt.setString(3, systemId);
214
          // Do the insertion
215
          pstmt.execute();
216
          pstmt.close();
217
          conn.commit();
218
          conn.setAutoCommit(true);
219
        } catch (SQLException e) {
220
          System.out.println(e.getMessage());
221
        }
222
   }
223
224
}