Project

General

Profile

1 72 bojilova
/**
2 92 bojilova
 *        Name: DBEntityResolver.java
3 72 bojilova
 *     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 92 bojilova
   private Connection conn = null;
32 72 bojilova
   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 92 bojilova
     currentElementNo = DBSAXHandler.elementNo;
55
56 72 bojilova
     if (publicId != null) {
57
        pIdCounter += 1;
58
        System.out.println("from DBEntityResolver: current element is " + DBSAXHandler.elementNo);
59
        System.out.println("from DBEntityResolver: " + pIdCounter + " " + publicId);
60
        // look at the db XML Catalog and get dbSystemId by this publicId
61
        if (currentElementNo == 0) {
62
            doctype = publicId;
63
            dbSystemId = getDTDSystemID (conn, publicId);
64
            if (dbSystemId == "")
65
                // register publicId in db and use the provided systemId
66
                if (systemId != "") {
67
                    new URL(systemId);
68 92 bojilova
                    registerDTDPublicID (conn, doctype, publicId, systemId);
69 72 bojilova
                    return null;
70
                }
71
            new URL(dbSystemId);
72
            return new InputSource(dbSystemId);
73
        }
74 92 bojilova
        /*else {
75 72 bojilova
            // look at the db XML Catalog and get dbSystemId by this publicId for a given doctype
76
            dbSystemId = getEntitySystemID (conn, doctype, publicId);
77
            if (dbSystemId == "")
78
                // register publicId in db for a given doctype and use the provided systemId
79
                if (systemId != "") {
80
                    new URL(systemId);
81
                    registerEntityPublicID (conn, doctype, publicId, systemId);
82
                    return null;
83
                }
84
            new URL(dbSystemId);
85
            return new InputSource(dbSystemId);
86 92 bojilova
        }*/
87 72 bojilova
     }
88 92 bojilova
     // publicId is null => doctype is null => doctype = docname
89 72 bojilova
     if ( systemId != null) {
90 92 bojilova
        if (currentElementNo == 0) {
91
            doctype = DBSAXHandler.docname;
92
            registerDTDPublicID (conn, doctype, "", systemId);
93
        }
94 72 bojilova
        new URL(systemId);
95
     }
96
97
     // use the default behaviour
98
     return null;
99
   }
100
101
   /** Look at db XML Catalog to get System ID (if any) for that Public ID.
102
     * Return empty string if there are not */
103
   private String getDTDSystemID (Connection conn, String publicId)
104
   {
105
        String system_id = "";
106
        Statement stmt;
107
        try {
108
          stmt = conn.createStatement();
109 92 bojilova
          stmt.execute("SELECT system_id FROM xml_catalog " +
110
                       "WHERE entity_type = 'DTD' AND source_doctype = '" + publicId + "'");
111 72 bojilova
          try {
112
            ResultSet rs = stmt.getResultSet();
113
            try {
114
              boolean tableHasRows = rs.next();
115
              if (tableHasRows) {
116
                try {
117
                  system_id = rs.getString(1);
118
                } catch (SQLException e) {
119
                  System.out.println("DBEntityResolver.getDTDSystemID() - Error with getString: " + e.getMessage());
120
                }
121
              }
122
            } catch (SQLException e) {
123
              System.out.println("DBEntityResolver.getDTDSystemID() - Error with next: " + e.getMessage());
124
            }
125
          } catch (SQLException e) {
126
            System.out.println("DBEntityResolver.getDTDSystemID() - Error with getrset: " + e.getMessage());
127
          }
128
          stmt.close();
129
        } catch (SQLException e) {
130
          System.out.println("DBEntityResolver.getDTDSystemID() - Error getting id: " + e.getMessage());
131 92 bojilova
          System.exit(1);
132 72 bojilova
        }
133
134
        // return the selected System ID
135
        return system_id;
136
   }
137
138
   /** Register Public ID in db XML Catalog */
139 92 bojilova
   private void registerDTDPublicID (Connection conn, String doctype, String publicId, String systemId)
140 72 bojilova
   {
141
        try {
142
          conn.setAutoCommit(false);
143
          PreparedStatement pstmt;
144
          pstmt = conn.prepareStatement(
145 92 bojilova
                "INSERT INTO xml_catalog (entity_id, entity_type, source_doctype, public_id, system_id) " +
146
                "VALUES (null, 'DTD', ?, ?, ?)");
147 72 bojilova
          // Bind the values to the query
148 92 bojilova
          pstmt.setString(1, doctype);
149
          pstmt.setString(2, publicId);
150
          pstmt.setString(3, systemId);
151 72 bojilova
          // Do the insertion
152
          pstmt.execute();
153
          pstmt.close();
154
          conn.commit();
155
          conn.setAutoCommit(true);
156
        } catch (SQLException e) {
157
          System.out.println(e.getMessage());
158
        }
159
   }
160
161
   /** Look at db XML Catalog to get System ID (if any) for that Public ID and doctype.
162
     * Return empty string if there are not */
163
   private String getEntitySystemID (Connection conn, String doctype, String publicId)
164
   {
165
        String system_id = "";
166
        Statement stmt;
167
        try {
168
          stmt = conn.createStatement();
169 92 bojilova
          stmt.execute("SELECT system_id FROM xml_catalog " +
170 72 bojilova
                       "WHERE entity_type = 'ENTITY' AND source_doctype = '" + doctype + "' AND public_id = '" + publicId + "'");
171
          try {
172
            ResultSet rs = stmt.getResultSet();
173
            try {
174
              boolean tableHasRows = rs.next();
175
              if (tableHasRows) {
176
                try {
177
                  system_id = rs.getString(1);
178
                } catch (SQLException e) {
179
                  System.out.println("DBEntityResolver.getEntitySystemID() - Error with getString: " + e.getMessage());
180
                }
181
              }
182
            } catch (SQLException e) {
183
              System.out.println("DBEntityResolver.getEntitySystemID() - Error with next: " + e.getMessage());
184
            }
185
          } catch (SQLException e) {
186
            System.out.println("DBEntityResolver.getEntitySystemID() - Error with getrset: " + e.getMessage());
187
          }
188
          stmt.close();
189
        } catch (SQLException e) {
190
          System.out.println("DBEntityResolver.getEntitySystemID() - Error getting id: " + e.getMessage());
191
        }
192
193
        // return the selected System ID number
194
        return system_id;
195
   }
196
197
   /** Register Public ID in db XML Catalog */
198
   private void registerEntityPublicID (Connection conn, String doctype, String publicId, String systemId)
199
   {
200
        try {
201
          conn.setAutoCommit(false);
202
          PreparedStatement pstmt;
203
          pstmt = conn.prepareStatement(
204 92 bojilova
                "INSERT INTO xml_catalog (entity_id, entity_name, entity_type, source_doctype, public_id, system_id) " +
205 72 bojilova
                "VALUES (null, null, 'ENTITY', ?, ?, ?)");
206
          // Bind the values to the query
207
          pstmt.setString(1, doctype);
208
          pstmt.setString(2, publicId);
209
          pstmt.setString(3, systemId);
210
          // Do the insertion
211
          pstmt.execute();
212
          pstmt.close();
213
          conn.commit();
214
          conn.setAutoCommit(true);
215
        } catch (SQLException e) {
216
          System.out.println(e.getMessage());
217
        }
218
   }
219
220
}