Project

General

Profile

1 72 bojilova
/**
2 122 jones
 *      Name: DBEntityResolver.java
3
 *   Purpose: A Class that implements org.xml.sax.EntityResolver interface
4 72 bojilova
 *              for resolving external entities
5 122 jones
 * Copyright: 2000 Regents of the University of California and the
6 72 bojilova
 *              National Center for Ecological Analysis and Synthesis
7 122 jones
 *   Authors: Jivka Bojilova
8 72 bojilova
 *
9 122 jones
 *   Version: '$Id$'
10 72 bojilova
 */
11
12 75 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 151 bojilova
import java.net.URLConnection;
19 72 bojilova
import java.net.MalformedURLException;
20 151 bojilova
import java.io.IOException;
21 72 bojilova
import java.util.Stack;
22
import java.util.EmptyStackException;
23
24
/**
25 122 jones
 * A database aware Class implementing EntityResolver interface for the SAX
26
 * parser to call when processing the XML stream and intercepting any
27
 * external entities (including the external DTD subset and external
28
 * parameter entities, if any) before including them.
29 72 bojilova
 */
30
public class DBEntityResolver implements EntityResolver
31
{
32
33
   static String doctype = null;
34 92 bojilova
   private Connection conn = null;
35 72 bojilova
   private int pIdCounter = 0;
36
   private long currentElementNo;
37
38
   /** Construct an instance of the DBEntityResolver clas
39
    *
40
    * @param conn the JDBC connection to which information is written
41
    */
42
   public DBEntityResolver(Connection conn)
43
   {
44
      this.conn = conn;
45
   }
46
47
48 122 jones
   /**
49
    * The Parser call this method before opening any external entity
50
    * except the top-level document entity (including the external DTD subset,
51
    * external entities referenced within the DTD, and external entities
52
    * referenced within the document element)
53
    */
54 72 bojilova
   public InputSource resolveEntity (String publicId, String systemId)
55 151 bojilova
                throws MalformedURLException, IOException
56 72 bojilova
   {
57
     String dbSystemId;
58
59 92 bojilova
     currentElementNo = DBSAXHandler.elementNo;
60
61 151 bojilova
     if (currentElementNo == 0) {
62
        if (publicId != null) {
63
            pIdCounter += 1;
64 72 bojilova
            doctype = publicId;
65 151 bojilova
        } else if ( systemId != null) {
66 92 bojilova
            doctype = DBSAXHandler.docname;
67 151 bojilova
        }
68
        // look at the db XML Catalog and get dbSystemId by this doctype
69
        dbSystemId = getDTDSystemID (conn, doctype);
70
        if (dbSystemId == "") {
71
            // register publicId in db and use the provided systemId
72
            if (systemId != "") {
73
                checkURLConnection(systemId);
74 109 bojilova
                registerDTDSystemID (conn, doctype, doctype, systemId);
75
                return null;
76 151 bojilova
            }
77
        } else {
78
            checkURLConnection(dbSystemId);
79 109 bojilova
            return new InputSource(dbSystemId);
80 151 bojilova
        }
81 72 bojilova
     }
82
83
     // use the default behaviour
84 151 bojilova
     checkURLConnection(systemId);
85 72 bojilova
     return null;
86
   }
87 109 bojilova
88 122 jones
   /**
89
    * Look at db XML Catalog to get System ID (if any) for that doctype.
90
    * Return empty string if there are not
91
    */
92 109 bojilova
   private String getDTDSystemID (Connection conn, String doctype)  {
93 72 bojilova
        String system_id = "";
94
        Statement stmt;
95
        try {
96
          stmt = conn.createStatement();
97 92 bojilova
          stmt.execute("SELECT system_id FROM xml_catalog " +
98 122 jones
                       "WHERE entry_type = 'DTD' AND public_id = '" +
99
                       doctype + "'");
100 72 bojilova
          try {
101
            ResultSet rs = stmt.getResultSet();
102
            try {
103
              boolean tableHasRows = rs.next();
104
              if (tableHasRows) {
105
                try {
106
                  system_id = rs.getString(1);
107
                } catch (SQLException e) {
108 122 jones
                  System.out.println("DBEntityResolver.getDTDSystemID() " +
109
                             "- Error with getString: " + e.getMessage());
110 72 bojilova
                }
111
              }
112
            } catch (SQLException e) {
113 122 jones
              System.out.println("DBEntityResolver.getDTDSystemID() " +
114
                             "- Error with next: " + e.getMessage());
115 72 bojilova
            }
116
          } catch (SQLException e) {
117 122 jones
            System.out.println("DBEntityResolver.getDTDSystemID() " +
118
                             "- Error with getrset: " + e.getMessage());
119 72 bojilova
          }
120
          stmt.close();
121
        } catch (SQLException e) {
122 122 jones
          System.out.println("DBEntityResolver.getDTDSystemID() " +
123
                             "- Error getting id: " + e.getMessage());
124 92 bojilova
          System.exit(1);
125 72 bojilova
        }
126
127
        // return the selected System ID
128
        return system_id;
129
   }
130
131 122 jones
   /**
132
    * Register DTD System ID in db XML Catalog
133
    */
134
   private void registerDTDSystemID (Connection conn, String doctype,
135
                                     String publicId, String systemId)
136 72 bojilova
   {
137
        try {
138
          PreparedStatement pstmt;
139
          pstmt = conn.prepareStatement(
140 122 jones
                "INSERT INTO xml_catalog " +
141
                "(catalog_id, entry_type, source_doctype, " +
142
                "public_id, system_id) " +
143 92 bojilova
                "VALUES (null, 'DTD', ?, ?, ?)");
144 72 bojilova
          // Bind the values to the query
145 92 bojilova
          pstmt.setString(1, doctype);
146
          pstmt.setString(2, publicId);
147
          pstmt.setString(3, systemId);
148 72 bojilova
          // Do the insertion
149
          pstmt.execute();
150
          pstmt.close();
151
        } catch (SQLException e) {
152
          System.out.println(e.getMessage());
153
        }
154
   }
155 122 jones
   /**
156 151 bojilova
    * Check URL Connection for systemId
157 122 jones
    */
158 151 bojilova
   private void checkURLConnection (String systemId)
159
                throws MalformedURLException, IOException
160 72 bojilova
   {
161
        try {
162 151 bojilova
            URLConnection urlConn = (new URL(systemId)).openConnection();
163
            urlConn.connect();
164
        } catch (MalformedURLException e) {
165
            System.out.println("from checkURLConnection(): " + e.getMessage());
166
            throw e;
167
        } catch (IOException e) {
168
            System.out.println("from checkURLConnection(): " + e.getMessage());
169
            throw e;
170
        }
171
   }
172 72 bojilova
}