Project

General

Profile

1
/**
2
 *      Name: DBEntityResolver.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: DBEntityResolver.java 122 2000-06-07 00:43:31Z jones $'
10
 */
11

    
12
package edu.ucsb.nceas.metacat;
13

    
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 
24
 * parser to call when processing the XML stream and intercepting any 
25
 * external entities (including the external DTD subset and external 
26
 * parameter entities, if any) before including them.
27
 */
28
public class DBEntityResolver implements EntityResolver
29
{
30

    
31
   static String doctype = null;
32
   private Connection conn = null;
33
   private int pIdCounter = 0;
34
   private long currentElementNo;
35

    
36
   /** Construct an instance of the DBEntityResolver clas
37
    *
38
    * @param conn the JDBC connection to which information is written
39
    */
40
   public DBEntityResolver(Connection conn)
41
   {
42
      this.conn = conn;
43
   }
44
   
45
   
46
   /** 
47
    * The Parser call this method before opening any external entity 
48
    * except the top-level document entity (including the external DTD subset,
49
    * external entities referenced within the DTD, and external entities 
50
    * referenced within the document element)
51
    */
52
   public InputSource resolveEntity (String publicId, String systemId)
53
            throws MalformedURLException
54
   {
55
     String dbSystemId;
56
     
57
     currentElementNo = DBSAXHandler.elementNo;
58
     
59
     if (publicId != null) {
60
        pIdCounter += 1;
61
        System.out.println("from DBEntityResolver: current element is " + 
62
                           DBSAXHandler.elementNo);
63
        System.out.println("from DBEntityResolver: " + pIdCounter + " " + 
64
                           publicId);
65
        // look at the db XML Catalog and get dbSystemId by this publicId
66
        if (currentElementNo == 0) {
67
            doctype = publicId;
68
            dbSystemId = getDTDSystemID (conn, publicId);
69
            if (dbSystemId == "")
70
                // register publicId in db and use the provided systemId
71
                if (systemId != "") {
72
                    new URL(systemId);
73
                    registerDTDSystemID (conn, doctype, publicId, systemId);
74
                    return null;
75
                }
76
            new URL(dbSystemId);
77
            return new InputSource(dbSystemId);
78
        } 
79
/*
80
          else {
81
            // look at the db XML Catalog and get dbSystemId by this 
82
            // publicId for a given doctype
83
            dbSystemId = getEntitySystemID (conn, doctype, publicId);
84
            if (dbSystemId == "")
85
                // register publicId in db for a given doctype and 
86
                // use the provided systemId
87
                if (systemId != "") {
88
                    new URL(systemId);
89
                    registerEntityPublicID (conn, doctype, publicId, systemId);
90
                    return null;
91
                }
92
            new URL(dbSystemId);
93
            return new InputSource(dbSystemId);
94
        }
95
*/  
96
     }
97
     // publicId is null => doctype is null => doctype = docname
98
     if ( systemId != null) {
99
        if (currentElementNo == 0) {
100
            doctype = DBSAXHandler.docname;
101
            dbSystemId = getDTDSystemID (conn, doctype);
102
            if (dbSystemId == "") {
103
                new URL(systemId);
104
                registerDTDSystemID (conn, doctype, doctype, systemId);
105
                return null;
106
            }    
107
            new URL(dbSystemId);
108
            return new InputSource(dbSystemId);
109
        }
110
     }
111
    
112
     // use the default behaviour
113
     return null;
114
   }
115

    
116
   /** 
117
    * Look at db XML Catalog to get System ID (if any) for that doctype.
118
    * Return empty string if there are not 
119
    */
120
   private String getDTDSystemID (Connection conn, String doctype)  {
121
        String system_id = "";
122
        Statement stmt;
123
        try {
124
          stmt = conn.createStatement();
125
          stmt.execute("SELECT system_id FROM xml_catalog " + 
126
                       "WHERE entry_type = 'DTD' AND public_id = '" + 
127
                       doctype + "'");
128
          try {
129
            ResultSet rs = stmt.getResultSet();
130
            try {
131
              boolean tableHasRows = rs.next();
132
              if (tableHasRows) {
133
                try {
134
                  system_id = rs.getString(1);
135
                } catch (SQLException e) {
136
                  System.out.println("DBEntityResolver.getDTDSystemID() " +
137
                             "- Error with getString: " + e.getMessage());
138
                }
139
              }
140
            } catch (SQLException e) {
141
              System.out.println("DBEntityResolver.getDTDSystemID() " +
142
                             "- Error with next: " + e.getMessage());
143
            }
144
          } catch (SQLException e) {
145
            System.out.println("DBEntityResolver.getDTDSystemID() " +
146
                             "- Error with getrset: " + e.getMessage());
147
          }
148
          stmt.close();
149
        } catch (SQLException e) {
150
          System.out.println("DBEntityResolver.getDTDSystemID() " +
151
                             "- Error getting id: " + e.getMessage());
152
          System.exit(1);
153
        }
154

    
155
        // return the selected System ID
156
        return system_id;
157
   }
158

    
159
   /** 
160
    * Register DTD System ID in db XML Catalog 
161
    */
162
   private void registerDTDSystemID (Connection conn, String doctype, 
163
                                     String publicId, String systemId)
164
   {
165
        try {
166
            java.net.URLConnection urlConn = 
167
                     (new URL(systemId)).openConnection();
168
            urlConn.connect();
169
        } catch (java.io.IOException e) {
170
            System.out.println("IOException: " + e.getMessage());
171
            return;
172
        }    
173
        try {
174
          conn.setAutoCommit(false);
175
          PreparedStatement pstmt;
176
          pstmt = conn.prepareStatement(
177
                "INSERT INTO xml_catalog " +
178
                "(catalog_id, entry_type, source_doctype, " +
179
                "public_id, system_id) " +
180
                "VALUES (null, 'DTD', ?, ?, ?)");
181
          // Bind the values to the query
182
          pstmt.setString(1, doctype);
183
          pstmt.setString(2, publicId);
184
          pstmt.setString(3, systemId);
185
          // Do the insertion
186
          pstmt.execute();
187
          pstmt.close();
188
          conn.commit();
189
          conn.setAutoCommit(true);
190
        } catch (SQLException e) {
191
          System.out.println(e.getMessage());
192
        }
193
   }
194
   
195
   /** 
196
    * Look at db XML Catalog to get System ID (if any) for that Public ID 
197
    * and doctype. Return empty string if there are not 
198
    */
199
   private String getEntitySystemID (Connection conn, String doctype, 
200
                                     String publicId)
201
   {
202
        String system_id = "";
203
        Statement stmt;
204
        try {
205
          stmt = conn.createStatement();
206
          stmt.execute("SELECT system_id FROM xml_catalog " + 
207
                       "WHERE entry_type = 'ENTITY' AND source_doctype = '" + 
208
                       doctype + "' AND public_id = '" + publicId + "'");
209
          try {
210
            ResultSet rs = stmt.getResultSet();
211
            try {
212
              boolean tableHasRows = rs.next();
213
              if (tableHasRows) {
214
                try {
215
                  system_id = rs.getString(1);
216
                } catch (SQLException e) {
217
                  System.out.println("DBEntityResolver.getEntitySystemID() " +
218
                         "- Error with getString: " + e.getMessage());
219
                }
220
              }
221
            } catch (SQLException e) {
222
              System.out.println("DBEntityResolver.getEntitySystemID() " +
223
                         "- Error with next: " + e.getMessage());
224
            }
225
          } catch (SQLException e) {
226
            System.out.println("DBEntityResolver.getEntitySystemID() " +
227
                         "- Error with getrset: " + e.getMessage());
228
          }
229
          stmt.close();
230
        } catch (SQLException e) {
231
          System.out.println("DBEntityResolver.getEntitySystemID() " +
232
                         "- Error getting id: " + e.getMessage());
233
        }
234

    
235
        // return the selected System ID number
236
        return system_id;
237
   }
238

    
239
   /** 
240
    * Register Public ID in db XML Catalog 
241
    */
242
   private void registerEntityPublicID (Connection conn, String doctype, 
243
                                        String publicId, String systemId)
244
   {
245
        try {
246
          conn.setAutoCommit(false);
247
          PreparedStatement pstmt;
248
          pstmt = conn.prepareStatement(
249
                "INSERT INTO xml_catalog (catalog_id, entry_type, " +
250
                "source_doctype, public_id, system_id) " +
251
                "VALUES (null, 'ENTITY', ?, ?, ?)");
252
          // Bind the values to the query
253
          pstmt.setString(1, doctype);
254
          pstmt.setString(2, publicId);
255
          pstmt.setString(3, systemId);
256
          // Do the insertion
257
          pstmt.execute();
258
          pstmt.close();
259
          conn.commit();
260
          conn.setAutoCommit(true);
261
        } catch (SQLException e) {
262
          System.out.println(e.getMessage());
263
        }
264
   }
265
}
(3-3/19)