Project

General

Profile

1 523 berkley
/**
2
 *   '$Author$'
3
 *     '$Date$'
4
 * '$Revision$'
5 669 jones
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 523 berkley
 */
20
21
package edu.ucsb.nceas.metacat;
22
23
import java.sql.*;
24
import java.util.*;
25
import java.lang.Thread;
26 662 berkley
import java.net.*;
27 523 berkley
28
public class RelationHandler implements Runnable
29
{
30
  private Thread btThread = null;
31
  private Connection conn = null;
32
  private DocumentImpl xmldoc = null;
33
  MetaCatUtil util = new MetaCatUtil();
34
35
  /**
36
   * Constructor for this class.  finds all of the relations to a single xml
37
   * document and writes them to the database.  This includes transitive
38
   * relations.
39
   * @param xmldoc the xml document to index.
40
   */
41
  public RelationHandler(DocumentImpl xmldoc, Connection conn)
42
  {
43 601 berkley
    //this.conn = conn;
44
    try
45
    {
46 683 berkley
      conn = MetacatReplication.getDBConnection("RelationHandler." +
47
                                                "relationHandler");
48 601 berkley
    }
49
    catch(Exception e)
50
    {
51 683 berkley
      System.out.println("unable to get db connection in relationhandler." +
52
                         "relationhandler: " + e.getMessage());
53 601 berkley
    }
54 523 berkley
    this.xmldoc = xmldoc;
55
    if(xmldoc.getDoctype().equals(util.getOption("packagedoctype")))
56
    { //make sure this doctype is a package document then run the thread
57
      btThread = new Thread(this);
58
      btThread.setPriority(Thread.MIN_PRIORITY);
59
      btThread.start();
60
    }
61
  }
62
63
  /**
64
   * The thread handler
65 683 berkley
   */
66 523 berkley
  public void run()
67
  {
68 683 berkley
    Connection dbconn = null;
69 645 bojilova
    String docid = xmldoc.getDocID();
70
    // deletes all of the relations with a docid of @docid.
71
    deleteRelations(docid);
72 523 berkley
    //pseudo-code algorithm
73
    //for each new relation r in xml_nodes
74
    //  put r into xml_relation
75
    //  compare r to each relation already in xml_relation
76
    //  if r isrelatedto a row in xml_relation
77
    //    add a new row to xml_relation that represents this new relation
78
    try
79
    {
80 683 berkley
      dbconn = MetacatReplication.getDBConnection("RelationHandler." +
81
                                                  "run");
82
      PreparedStatement pstmt = dbconn.prepareStatement(
83 523 berkley
                                QuerySpecification.printPackageSQL(docid));
84
      pstmt.execute();
85 662 berkley
86 523 berkley
      //get the new relations out of xml_nodes
87
      ResultSet rs = pstmt.getResultSet();
88
      boolean hasmorerows = rs.next();
89
      while(hasmorerows)
90
      {
91
        String subject = rs.getString(1);
92
        String subjectDoctype = null;
93 662 berkley
        String paramDocid = null;
94
        URL subjectMurl = null;
95
96
        try
97 523 berkley
        {
98 662 berkley
          subjectMurl = new URL(subject);
99
          subjectDoctype = null;
100
          Hashtable murlParams = util.parseQuery(subjectMurl.getQuery());
101
          paramDocid = (String)murlParams.get("docid");
102 523 berkley
        }
103 662 berkley
        catch(MalformedURLException murle)
104
        { //assume this is just a docid not a url
105
          paramDocid = subject;
106
        }
107
108 683 berkley
        DocumentImpl subDoc = new DocumentImpl(dbconn, paramDocid);
109 662 berkley
        subjectDoctype = subDoc.getDoctype();
110 523 berkley
        String relationship = rs.getString(2);
111
        String object = rs.getString(3);
112
113
        //compare r to each relation in xml_relation
114 671 berkley
115 683 berkley
        pstmt = dbconn.prepareStatement("select subject, subdoctype, " +
116 523 berkley
                                      "relationship, object, objdoctype " +
117
                                      "from xml_relation");
118
        pstmt.execute();
119
        //get each relation in xml_relation for comparison
120
        ResultSet relations = pstmt.getResultSet();
121
        boolean hasmorerelations = relations.next();
122
        while(hasmorerelations)
123
        {
124
          String currentSub = relations.getString(1);
125
          String currentSubDoctype = relations.getString(2);
126
          String currentRelationship = relations.getString(3);
127
          String currentObj = relations.getString(4);
128
          String currentObjDoctype = relations.getString(5);
129
130
          if(object.equals(currentObj))
131
          {//there is a transitive relation so add a new relation to the table
132
            StringBuffer insertTransRelation = new StringBuffer();
133 634 berkley
            insertTransRelation.append("insert into xml_relation (docid, ");
134
            insertTransRelation.append(" subject, ");
135 523 berkley
            insertTransRelation.append("subdoctype, relationship, object, ");
136
            insertTransRelation.append("objdoctype) values ('");
137 634 berkley
            insertTransRelation.append(docid).append("', '");
138 523 berkley
            insertTransRelation.append(currentSub).append("', '");
139
            insertTransRelation.append(currentSubDoctype).append("', ");
140
            insertTransRelation.append("'hasTransitiveRelationTo', '");
141
            insertTransRelation.append(subject).append("', '");
142
            insertTransRelation.append(subjectDoctype).append("')");
143 634 berkley
            //System.out.println("sql1: " + insertTransRelation.toString());
144 683 berkley
            pstmt = dbconn.prepareStatement(insertTransRelation.toString());
145 601 berkley
            pstmt.execute();
146 523 berkley
147
            insertTransRelation = new StringBuffer();
148
            //put the same relation in with the subject and object switched
149 634 berkley
            insertTransRelation.append("insert into xml_relation (docid, ");
150
            insertTransRelation.append(" subject, ");
151 523 berkley
            insertTransRelation.append("subdoctype, relationship, object, ");
152
            insertTransRelation.append("objdoctype) values ('");
153 634 berkley
            insertTransRelation.append(docid).append("', '");
154 679 berkley
            insertTransRelation.append(subject).append("', '");
155 523 berkley
            insertTransRelation.append(subjectDoctype).append("', ");
156
            insertTransRelation.append("'hasTransitiveRelationTo', '");
157
            insertTransRelation.append(currentSub).append("', '");
158
            insertTransRelation.append(currentSubDoctype).append("')");
159 634 berkley
            //System.out.println("sql2: " + insertTransRelation.toString());
160 683 berkley
            pstmt = dbconn.prepareStatement(insertTransRelation.toString());
161 523 berkley
            pstmt.execute();
162
          }
163
164 662 berkley
          hasmorerelations = relations.next();
165 523 berkley
        }
166
167
        //get the current relations information
168 662 berkley
        String subDocid = null;
169
        String objDocid = null;
170 523 berkley
        String subDoctype = null;
171
        String objDoctype = null;
172 662 berkley
173
        try
174 523 berkley
        {
175 662 berkley
          URL subMurl = new URL(subject);
176 679 berkley
          if(subMurl.getQuery() != null)
177
          {
178
            Hashtable subMurlParams = util.parseQuery(subMurl.getQuery());
179
            subDocid = (String)subMurlParams.get("docid");
180
            if(subMurl.getProtocol().equals("metacat"))
181
            {
182 683 berkley
              subDoc = new DocumentImpl(dbconn, subDocid);
183 679 berkley
              subDoctype = subDoc.getDoctype();
184
            }
185
          }
186
          else
187
          {
188
            subDocid = subject;
189
          }
190 523 berkley
        }
191 662 berkley
        catch(MalformedURLException murle)
192
        { //assume this is just a docid not a url
193
          subDocid = subject;
194
        }
195
196
        try
197 523 berkley
        {
198 662 berkley
          URL objMurl = new URL(object);
199 679 berkley
          if(objMurl.getQuery() != null)
200
          {
201
            Hashtable objMurlParams = util.parseQuery(objMurl.getQuery());
202
            objDocid = (String)objMurlParams.get("docid");
203
            if(objMurl.getProtocol().equals("metacat"))
204
            {
205 683 berkley
              DocumentImpl objDoc = new DocumentImpl(dbconn, objDocid);
206 679 berkley
              objDoctype = objDoc.getDoctype();
207
            }
208
          }
209
          else
210
          {
211
            objDocid = object;
212
          }
213 523 berkley
        }
214 662 berkley
        catch(MalformedURLException murle)
215
        { //assume this is just a docid
216
          objDocid = object;
217
        }
218
219
220 523 berkley
        //now that the comparisons are done, the new relation can be put
221
        //into xml_relation
222
        StringBuffer insertStmt = new StringBuffer();
223 634 berkley
        insertStmt.append("insert into xml_relation (docid, subject, ");
224
        insertStmt.append("subdoctype, ");
225 523 berkley
        insertStmt.append("relationship, object, objdoctype) values ('");
226 634 berkley
        insertStmt.append(docid).append("', '");
227 523 berkley
        insertStmt.append(subject).append("', '");
228
        insertStmt.append(subDoctype).append("', '");
229
        insertStmt.append(relationship).append("', '");
230
        insertStmt.append(object).append("', '");
231
        insertStmt.append(objDoctype).append("')");
232 671 berkley
233 683 berkley
        pstmt = dbconn.prepareStatement(insertStmt.toString());
234 523 berkley
        pstmt.execute();
235
236
        hasmorerows = rs.next();
237
      }
238
239 683 berkley
      dbconn.commit();
240 671 berkley
      pstmt.close();
241 683 berkley
      dbconn.close();
242 523 berkley
      btThread = null;
243
244 601 berkley
    }
245
    catch(Exception e)
246
    {
247 683 berkley
      System.out.println("Error in relationHandler.run: " + e.getMessage());
248
      util.debugMessage("Error in relationHandler.run: " + e.getMessage());
249
      e.printStackTrace(System.out);
250
      btThread = null;
251 601 berkley
      try
252
      {
253 523 berkley
        conn.rollback();
254 601 berkley
      }
255
      catch (SQLException sqle) {}
256 523 berkley
    }
257
  }
258 634 berkley
259
  /**
260
   * Deletes all of the relations with a docid of 'docid'.
261
   * @param docid the docid to delete.
262
   */
263 645 bojilova
  public void deleteRelations(String docid)
264 634 berkley
  {
265 683 berkley
    Connection dbconn = null;
266 634 berkley
    try
267
    {
268 683 berkley
      dbconn = MetacatReplication.getDBConnection("RelationHandler."+
269
                                                  "deleteRelations");
270
    }
271
    catch(Exception ee)
272
    {
273
      System.out.println("error in relationHandler.deleteRelations: " +
274
                          ee.getMessage());
275
    }
276
277
    try
278
    {
279
      PreparedStatement pstmt = dbconn.prepareStatement("delete from " +
280 634 berkley
                             "xml_relation where docid like '" + docid + "'");
281
      pstmt.execute();
282 645 bojilova
      pstmt.close();
283 683 berkley
      dbconn.close();
284 634 berkley
    }
285
    catch(Exception e)
286
    {
287 683 berkley
      System.out.println("error in RelationHandler.deleteRelations(): " +
288
                          e.getMessage());
289
      e.printStackTrace(System.out);
290 645 bojilova
      try
291
      {
292 683 berkley
        dbconn.rollback();
293
        dbconn.close();
294 645 bojilova
      }
295
      catch (SQLException sqle) {}
296 634 berkley
    }
297
298
  }
299 523 berkley
}