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 109 2000-05-31 00:56:56Z bojilova $'
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 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
   private 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
     currentElementNo = DBSAXHandler.elementNo;
55
     
56
     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
                    registerDTDSystemID (conn, doctype, publicId, systemId);
69
                    return null;
70
                }
71
            new URL(dbSystemId);
72
            return new InputSource(dbSystemId);
73
        } 
74
        /*else {
75
            // 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
        }*/  
87
     }
88
     // publicId is null => doctype is null => doctype = docname
89
     if ( systemId != null) {
90
        if (currentElementNo == 0) {
91
            doctype = DBSAXHandler.docname;
92
            dbSystemId = getDTDSystemID (conn, doctype);
93
            if (dbSystemId == "") {
94
                new URL(systemId);
95
                registerDTDSystemID (conn, doctype, doctype, systemId);
96
                return null;
97
            }    
98
            new URL(dbSystemId);
99
            return new InputSource(dbSystemId);
100
        }
101
     }
102
    
103
     // use the default behaviour
104
     return null;
105
   }
106

    
107
   /** Look at db XML Catalog to get System ID (if any) for that doctype.
108
     * Return empty string if there are not */
109
   private String getDTDSystemID (Connection conn, String doctype)  {
110
        String system_id = "";
111
        Statement stmt;
112
        try {
113
          stmt = conn.createStatement();
114
          System.out.println("DOCTYPE:" + doctype);
115
          stmt.execute("SELECT system_id FROM xml_catalog " + 
116
                       "WHERE entity_type = 'DTD' AND public_id = '" + doctype + "'");
117
          try {
118
            ResultSet rs = stmt.getResultSet();
119
            try {
120
              boolean tableHasRows = rs.next();
121
              if (tableHasRows) {
122
                try {
123
                  system_id = rs.getString(1);
124
                } catch (SQLException e) {
125
                  System.out.println("DBEntityResolver.getDTDSystemID() - Error with getString: " + e.getMessage());
126
                }
127
              }
128
            } catch (SQLException e) {
129
              System.out.println("DBEntityResolver.getDTDSystemID() - Error with next: " + e.getMessage());
130
            }
131
          } catch (SQLException e) {
132
            System.out.println("DBEntityResolver.getDTDSystemID() - Error with getrset: " + e.getMessage());
133
          }
134
          stmt.close();
135
        } catch (SQLException e) {
136
          System.out.println("DBEntityResolver.getDTDSystemID() - Error getting id: " + e.getMessage());
137
          System.exit(1);
138
        }
139

    
140
        // return the selected System ID
141
        return system_id;
142
   }
143

    
144
   /** Register DTD System ID in db XML Catalog */
145
   private void registerDTDSystemID (Connection conn, String doctype, String publicId, String systemId)
146
   {
147
        try {
148
            java.net.URLConnection urlConn = (new URL(systemId)).openConnection();
149
            urlConn.connect();
150
        } catch (java.io.IOException e) {
151
            System.out.println("IOException: " + e.getMessage());
152
            return;
153
        }    
154
        try {
155
          conn.setAutoCommit(false);
156
          PreparedStatement pstmt;
157
          pstmt = conn.prepareStatement(
158
                "INSERT INTO xml_catalog (entity_id, entity_type, source_doctype, public_id, system_id) " +
159
                "VALUES (null, 'DTD', ?, ?, ?)");
160
          // Bind the values to the query
161
          pstmt.setString(1, doctype);
162
          pstmt.setString(2, publicId);
163
          pstmt.setString(3, systemId);
164
          // Do the insertion
165
          pstmt.execute();
166
          pstmt.close();
167
          conn.commit();
168
          conn.setAutoCommit(true);
169
        } catch (SQLException e) {
170
          System.out.println(e.getMessage());
171
        }
172
   }
173
   
174
   /** Look at db XML Catalog to get System ID (if any) for that Public ID and doctype.
175
     * Return empty string if there are not */
176
   private String getEntitySystemID (Connection conn, String doctype, String publicId)
177
   {
178
        String system_id = "";
179
        Statement stmt;
180
        try {
181
          stmt = conn.createStatement();
182
          stmt.execute("SELECT system_id FROM xml_catalog " + 
183
                       "WHERE entity_type = 'ENTITY' AND source_doctype = '" + doctype + "' AND public_id = '" + publicId + "'");
184
          try {
185
            ResultSet rs = stmt.getResultSet();
186
            try {
187
              boolean tableHasRows = rs.next();
188
              if (tableHasRows) {
189
                try {
190
                  system_id = rs.getString(1);
191
                } catch (SQLException e) {
192
                  System.out.println("DBEntityResolver.getEntitySystemID() - Error with getString: " + e.getMessage());
193
                }
194
              }
195
            } catch (SQLException e) {
196
              System.out.println("DBEntityResolver.getEntitySystemID() - Error with next: " + e.getMessage());
197
            }
198
          } catch (SQLException e) {
199
            System.out.println("DBEntityResolver.getEntitySystemID() - Error with getrset: " + e.getMessage());
200
          }
201
          stmt.close();
202
        } catch (SQLException e) {
203
          System.out.println("DBEntityResolver.getEntitySystemID() - Error getting id: " + e.getMessage());
204
        }
205

    
206
        // return the selected System ID number
207
        return system_id;
208
   }
209

    
210
   /** Register Public ID in db XML Catalog */
211
   private void registerEntityPublicID (Connection conn, String doctype, String publicId, String systemId)
212
   {
213
        try {
214
          conn.setAutoCommit(false);
215
          PreparedStatement pstmt;
216
          pstmt = conn.prepareStatement(
217
                "INSERT INTO xml_catalog (entity_id, entity_name, entity_type, source_doctype, public_id, system_id) " +
218
                "VALUES (null, null, 'ENTITY', ?, ?, ?)");
219
          // Bind the values to the query
220
          pstmt.setString(1, doctype);
221
          pstmt.setString(2, publicId);
222
          pstmt.setString(3, systemId);
223
          // Do the insertion
224
          pstmt.execute();
225
          pstmt.close();
226
          conn.commit();
227
          conn.setAutoCommit(true);
228
        } catch (SQLException e) {
229
          System.out.println(e.getMessage());
230
        }
231
   }
232

    
233
}
(3-3/32)