Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class to asyncronously build the package relation index
4
 *             in the database table xml_relation.
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Chad Berkley
8
 *    Release: @release@
9
 *
10
 *   '$Author: jones $'
11
 *     '$Date: 2001-01-18 11:52:00 -0800 (Thu, 18 Jan 2001) $'
12
 * '$Revision: 669 $'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28
 
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.sql.*;
32
import java.util.*;
33
import java.lang.Thread; 
34
import java.net.*;
35

    
36
public class RelationHandler implements Runnable
37
{
38
  private Thread btThread = null;
39
  private Connection conn = null;
40
  private DocumentImpl xmldoc = null;
41
  MetaCatUtil util = new MetaCatUtil();
42
  
43
  /** 
44
   * Constructor for this class.  finds all of the relations to a single xml
45
   * document and writes them to the database.  This includes transitive
46
   * relations.
47
   * @param xmldoc the xml document to index.
48
   */
49
  public RelationHandler(DocumentImpl xmldoc, Connection conn)
50
  {
51
    //this.conn = conn;
52
    try
53
    {
54
      this.conn = util.openDBConnection();
55
    }
56
    catch(Exception e)
57
    {
58
      System.out.println("error opening connection in relationHandler");
59
    }
60
    
61
    this.xmldoc = xmldoc;
62
    if(xmldoc.getDoctype().equals(util.getOption("packagedoctype")))
63
    { //make sure this doctype is a package document then run the thread
64
      btThread = new Thread(this);
65
      btThread.setPriority(Thread.MIN_PRIORITY);
66
      btThread.start();
67
    }
68
  }
69
  
70
  /**
71
   * The thread handler
72
   */
73
  public void run()
74
  {
75
    String docid = xmldoc.getDocID();
76

    
77
    // deletes all of the relations with a docid of @docid.
78
    deleteRelations(docid);
79
    //pseudo-code algorithm
80
    //for each new relation r in xml_nodes
81
    //  put r into xml_relation
82
    //  compare r to each relation already in xml_relation
83
    //  if r isrelatedto a row in xml_relation
84
    //    add a new row to xml_relation that represents this new relation
85
    try
86
    {
87
      PreparedStatement pstmt = conn.prepareStatement(
88
                                QuerySpecification.printPackageSQL(docid));
89
      pstmt.execute();
90
      
91
      //get the new relations out of xml_nodes
92
      ResultSet rs = pstmt.getResultSet();
93
      boolean hasmorerows = rs.next();
94
      while(hasmorerows)
95
      {
96
        String subject = rs.getString(1);
97
        String subjectDoctype = null;
98
        String paramDocid = null;
99
        URL subjectMurl = null;
100

    
101
        try
102
        {
103
          subjectMurl = new URL(subject);
104
          subjectDoctype = null;
105
          Hashtable murlParams = util.parseQuery(subjectMurl.getQuery());
106
          paramDocid = (String)murlParams.get("docid"); 
107
        }
108
        catch(MalformedURLException murle)
109
        { //assume this is just a docid not a url
110
          paramDocid = subject;
111
        }
112
        
113
        DocumentImpl subDoc = new DocumentImpl(conn, paramDocid);
114
        subjectDoctype = subDoc.getDoctype();
115
        String relationship = rs.getString(2);
116
        String object = rs.getString(3);
117
      
118
        //compare r to each relation in xml_relation
119
        pstmt.close();
120
        pstmt = conn.prepareStatement("select subject, subdoctype, " +
121
                                      "relationship, object, objdoctype " +
122
                                      "from xml_relation");
123
        pstmt.execute();
124
        //get each relation in xml_relation for comparison
125
        ResultSet relations = pstmt.getResultSet();
126
        boolean hasmorerelations = relations.next();
127
        while(hasmorerelations)
128
        {
129
          String currentSub = relations.getString(1);
130
          String currentSubDoctype = relations.getString(2);
131
          String currentRelationship = relations.getString(3);
132
          String currentObj = relations.getString(4);
133
          String currentObjDoctype = relations.getString(5);
134
         
135
          if(object.equals(currentObj))
136
          {//there is a transitive relation so add a new relation to the table
137
            StringBuffer insertTransRelation = new StringBuffer();
138
            insertTransRelation.append("insert into xml_relation (docid, ");
139
            insertTransRelation.append(" subject, ");
140
            insertTransRelation.append("subdoctype, relationship, object, ");
141
            insertTransRelation.append("objdoctype) values ('");
142
            insertTransRelation.append(docid).append("', '");
143
            insertTransRelation.append(currentSub).append("', '");
144
            insertTransRelation.append(currentSubDoctype).append("', ");
145
            insertTransRelation.append("'hasTransitiveRelationTo', '");
146
            insertTransRelation.append(subject).append("', '");
147
            insertTransRelation.append(subjectDoctype).append("')");
148
            //System.out.println("sql1: " + insertTransRelation.toString());
149
            pstmt = conn.prepareStatement(insertTransRelation.toString());
150
            pstmt.execute(); 
151
            
152
            insertTransRelation = new StringBuffer();
153
            //put the same relation in with the subject and object switched
154
            insertTransRelation.append("insert into xml_relation (docid, ");
155
            insertTransRelation.append(" subject, ");
156
            insertTransRelation.append("subdoctype, relationship, object, ");
157
            insertTransRelation.append("objdoctype) values ('");
158
            insertTransRelation.append(docid).append("', '");
159
            insertTransRelation.append(subject).append("', '");
160
            insertTransRelation.append(subjectDoctype).append("', ");
161
            insertTransRelation.append("'hasTransitiveRelationTo', '");
162
            insertTransRelation.append(currentSub).append("', '");
163
            insertTransRelation.append(currentSubDoctype).append("')");
164
            //System.out.println("sql2: " + insertTransRelation.toString());
165
            pstmt = conn.prepareStatement(insertTransRelation.toString());
166
            pstmt.execute();
167
          }
168
          
169
          hasmorerelations = relations.next(); 
170
        }
171
        
172
        //get the current relations information
173
        String subDocid = null;
174
        String objDocid = null;
175
        String subDoctype = null;
176
        String objDoctype = null;
177
        
178
        try
179
        {
180
          URL subMurl = new URL(subject);
181
          Hashtable subMurlParams = util.parseQuery(subMurl.getQuery());
182
          subDocid = (String)subMurlParams.get("docid");
183
        }
184
        catch(MalformedURLException murle)
185
        { //assume this is just a docid not a url
186
          subDocid = subject;
187
        }
188
        
189
        try
190
        {
191
          URL objMurl = new URL(object); 
192
          Hashtable objMurlParams = util.parseQuery(objMurl.getQuery());
193
          objDocid = (String)objMurlParams.get("docid");
194
        }
195
        catch(MalformedURLException murle)
196
        { //assume this is just a docid
197
          objDocid = object;
198
        }
199
        
200
        subDoc = new DocumentImpl(conn, subDocid);
201
        subDoctype = subDoc.getDoctype();
202
        DocumentImpl objDoc = new DocumentImpl(conn, objDocid);
203
        objDoc.getDoctype();
204
        
205
        //now that the comparisons are done, the new relation can be put
206
        //into xml_relation
207
        StringBuffer insertStmt = new StringBuffer();
208
        insertStmt.append("insert into xml_relation (docid, subject, ");
209
        insertStmt.append("subdoctype, ");
210
        insertStmt.append("relationship, object, objdoctype) values ('");
211
        insertStmt.append(docid).append("', '");
212
        insertStmt.append(subject).append("', '");
213
        insertStmt.append(subDoctype).append("', '");
214
        insertStmt.append(relationship).append("', '");
215
        insertStmt.append(object).append("', '");
216
        insertStmt.append(objDoctype).append("')");
217
        pstmt = conn.prepareStatement(insertStmt.toString());
218
        pstmt.execute(); 
219
        
220
        hasmorerows = rs.next();
221
      }
222
      
223
      conn.commit();
224
      conn.close();
225
      btThread = null;
226

    
227
    } 
228
    catch(Exception e) 
229
    { 
230
      try 
231
      { 
232
        conn.rollback();
233
      } 
234
      catch (SQLException sqle) {}
235
      System.out.println("Error in relationHandler: " + e.getMessage());
236
      util.debugMessage("Error in relationHandler: " + e.getMessage());
237
      e.printStackTrace(System.out);
238
      btThread = null;
239
    }
240
  }
241
  
242
  /**
243
   * Deletes all of the relations with a docid of 'docid'.
244
   * @param docid the docid to delete.
245
   */
246
  public void deleteRelations(String docid)
247
  {
248
    try
249
    {
250
      PreparedStatement pstmt = conn.prepareStatement("delete from " +
251
                             "xml_relation where docid like '" + docid + "'");
252
      pstmt.execute();
253
      pstmt.close();
254
    }
255
    catch(Exception e)
256
    {
257
      try 
258
      { 
259
        conn.rollback();
260
      } 
261
      catch (SQLException sqle) {}
262
      System.out.println("error in deleteRelations(): " + e.getMessage());
263
      e.printStackTrace(System.out);
264
    }
265
    
266
  }
267
}
(40-40/43)