Project

General

Profile

1 72 bojilova
/**
2 203 jones
 *  '$RCSfile$'
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 72 bojilova
 *
9 203 jones
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 72 bojilova
 */
13
14 75 jones
package edu.ucsb.nceas.metacat;
15 72 bojilova
16
import org.xml.sax.*;
17
18
import java.sql.*;
19
import java.net.URL;
20 151 bojilova
import java.net.URLConnection;
21 72 bojilova
import java.net.MalformedURLException;
22 151 bojilova
import java.io.IOException;
23 72 bojilova
import java.util.Stack;
24
import java.util.EmptyStackException;
25
26
/**
27 122 jones
 * A database aware Class implementing EntityResolver interface for the SAX
28
 * parser to call when processing the XML stream and intercepting any
29
 * external entities (including the external DTD subset and external
30
 * parameter entities, if any) before including them.
31 72 bojilova
 */
32
public class DBEntityResolver implements EntityResolver
33
{
34 92 bojilova
   private Connection conn = null;
35 204 jones
   private DBSAXHandler handler;
36 72 bojilova
37
   /** Construct an instance of the DBEntityResolver clas
38
    *
39
    * @param conn the JDBC connection to which information is written
40
    */
41 204 jones
   public DBEntityResolver(Connection conn, DBSAXHandler handler)
42 72 bojilova
   {
43
      this.conn = conn;
44 204 jones
      this.handler = handler;
45 72 bojilova
   }
46
47 122 jones
   /**
48
    * The Parser call this method before opening any external entity
49
    * except the top-level document entity (including the external DTD subset,
50
    * external entities referenced within the DTD, and external entities
51
    * referenced within the document element)
52
    */
53 72 bojilova
   public InputSource resolveEntity (String publicId, String systemId)
54 151 bojilova
                throws MalformedURLException, IOException
55 72 bojilova
   {
56
     String dbSystemId;
57 204 jones
     String doctype = null;
58 72 bojilova
59 204 jones
     // Only process entities if its the DTD
60
     if (handler.atFirstElement()) {
61
        if (publicId != null) {       // If we have a public ID, use it
62 72 bojilova
            doctype = publicId;
63 204 jones
            MetaCatUtil.debugMessage("DOCTYPE-c: " + doctype);
64
        } else if ( systemId != null) {  // Otherwise, use system id if we can
65
            doctype = handler.getDocname();
66
            MetaCatUtil.debugMessage("DOCTYPE-d: " + doctype);
67 151 bojilova
        }
68 204 jones
        // look at the db XML Catalog and get dbSystemId for this doctype
69 151 bojilova
        dbSystemId = getDTDSystemID (conn, doctype);
70
        if (dbSystemId == "") {
71 204 jones
            // if it is not found inthe database, then
72 151 bojilova
            // register publicId in db and use the provided systemId
73
            if (systemId != "") {
74
                checkURLConnection(systemId);
75 109 bojilova
                registerDTDSystemID (conn, doctype, doctype, systemId);
76
                return null;
77 151 bojilova
            }
78
        } else {
79 204 jones
            // If it is in the database, return the systemid fromthe database
80 151 bojilova
            checkURLConnection(dbSystemId);
81 109 bojilova
            return new InputSource(dbSystemId);
82 151 bojilova
        }
83 72 bojilova
     }
84
85 204 jones
     // use the default behaviour for other cases
86 151 bojilova
     checkURLConnection(systemId);
87 72 bojilova
     return null;
88
   }
89 109 bojilova
90 122 jones
   /**
91
    * Look at db XML Catalog to get System ID (if any) for that doctype.
92
    * Return empty string if there are not
93
    */
94 109 bojilova
   private String getDTDSystemID (Connection conn, String doctype)  {
95 72 bojilova
        String system_id = "";
96
        Statement stmt;
97
        try {
98
          stmt = conn.createStatement();
99 92 bojilova
          stmt.execute("SELECT system_id FROM xml_catalog " +
100 122 jones
                       "WHERE entry_type = 'DTD' AND public_id = '" +
101
                       doctype + "'");
102 72 bojilova
          try {
103
            ResultSet rs = stmt.getResultSet();
104
            try {
105
              boolean tableHasRows = rs.next();
106
              if (tableHasRows) {
107
                try {
108
                  system_id = rs.getString(1);
109
                } catch (SQLException e) {
110 122 jones
                  System.out.println("DBEntityResolver.getDTDSystemID() " +
111
                             "- Error with getString: " + e.getMessage());
112 72 bojilova
                }
113
              }
114
            } catch (SQLException e) {
115 122 jones
              System.out.println("DBEntityResolver.getDTDSystemID() " +
116
                             "- Error with next: " + e.getMessage());
117 72 bojilova
            }
118
          } catch (SQLException e) {
119 122 jones
            System.out.println("DBEntityResolver.getDTDSystemID() " +
120
                             "- Error with getrset: " + e.getMessage());
121 72 bojilova
          }
122
          stmt.close();
123
        } catch (SQLException e) {
124 122 jones
          System.out.println("DBEntityResolver.getDTDSystemID() " +
125
                             "- Error getting id: " + e.getMessage());
126 92 bojilova
          System.exit(1);
127 72 bojilova
        }
128
129
        // return the selected System ID
130
        return system_id;
131
   }
132
133 122 jones
   /**
134
    * Register DTD System ID in db XML Catalog
135
    */
136
   private void registerDTDSystemID (Connection conn, String doctype,
137
                                     String publicId, String systemId)
138 72 bojilova
   {
139
        try {
140
          PreparedStatement pstmt;
141
          pstmt = conn.prepareStatement(
142 122 jones
                "INSERT INTO xml_catalog " +
143
                "(catalog_id, entry_type, source_doctype, " +
144
                "public_id, system_id) " +
145 92 bojilova
                "VALUES (null, 'DTD', ?, ?, ?)");
146 72 bojilova
          // Bind the values to the query
147 92 bojilova
          pstmt.setString(1, doctype);
148
          pstmt.setString(2, publicId);
149
          pstmt.setString(3, systemId);
150 72 bojilova
          // Do the insertion
151
          pstmt.execute();
152
          pstmt.close();
153
        } catch (SQLException e) {
154
          System.out.println(e.getMessage());
155
        }
156
   }
157 122 jones
   /**
158 151 bojilova
    * Check URL Connection for systemId
159 122 jones
    */
160 151 bojilova
   private void checkURLConnection (String systemId)
161
                throws MalformedURLException, IOException
162 72 bojilova
   {
163
        try {
164 151 bojilova
            URLConnection urlConn = (new URL(systemId)).openConnection();
165
            urlConn.connect();
166
        } catch (MalformedURLException e) {
167
            System.out.println("from checkURLConnection(): " + e.getMessage());
168
            throw e;
169
        } catch (IOException e) {
170
            System.out.println("from checkURLConnection(): " + e.getMessage());
171
            throw e;
172
        }
173
   }
174 72 bojilova
}
175 203 jones
176
/**
177
 * '$Log$
178 204 jones
 * 'Revision 1.11  2000/06/26 10:35:04  jones
179
 * 'Merged in substantial changes to DBWriter and associated classes and to
180
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
181
 * 'functions.  The command line tools and the parameters for the
182
 * 'servlet have changed substantially.
183
 * '
184 203 jones
 * 'Revision 1.10.2.2  2000/06/25 23:38:16  jones
185
 * 'Added RCSfile keyword
186
 * '
187
 * 'Revision 1.10.2.1  2000/06/25 23:34:17  jones
188
 * 'Changed documentation formatting, added log entries at bottom of source files
189
 * ''
190
 */