Project

General

Profile

1 522 berkley
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class to asyncronously do delta-T replication checking
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Chad Berkley
7
 *    Release: @release@
8
 *
9
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 669 jones
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 522 berkley
 */
27
28
package edu.ucsb.nceas.metacat;
29
30
import java.sql.*;
31
import java.util.*;
32
import java.lang.Thread;
33
import java.io.*;
34
import java.net.*;
35 543 berkley
import java.text.*;
36 522 berkley
import org.xml.sax.AttributeList;
37
import org.xml.sax.ContentHandler;
38
import org.xml.sax.DTDHandler;
39
import org.xml.sax.EntityResolver;
40
import org.xml.sax.ErrorHandler;
41
import org.xml.sax.InputSource;
42
import org.xml.sax.XMLReader;
43
import org.xml.sax.SAXException;
44
import org.xml.sax.SAXParseException;
45
import org.xml.sax.helpers.XMLReaderFactory;
46 561 berkley
import org.xml.sax.helpers.DefaultHandler;
47 522 berkley
48 561 berkley
49
50 522 berkley
/**
51
 * This class handles deltaT replication checking.  Whenever this TimerTask
52
 * is fired it checks each server in xml_replication for updates and updates
53
 * the local db as needed.
54
 */
55
public class ReplicationHandler extends TimerTask
56
{
57 573 berkley
  int serverCheckCode = 1;
58 522 berkley
  MetaCatUtil util = new MetaCatUtil();
59
  Hashtable serverList = new Hashtable();
60 1217 tao
  //Connection conn;
61 522 berkley
  PrintWriter out;
62
63
  public ReplicationHandler(PrintWriter o)
64
  {
65
    this.out = o;
66
  }
67
68 573 berkley
  public ReplicationHandler(PrintWriter o, int serverCheckCode)
69
  {
70
    this.out = o;
71
    this.serverCheckCode = serverCheckCode;
72
  }
73
74 522 berkley
  /**
75
   * Method that implements TimerTask.run().  It runs whenever the timer is
76
   * fired.
77
   */
78
  public void run()
79
  {
80
    //find out the last_checked time of each server in the server list and
81
    //send a query to each server to see if there are any documents in
82
    //xml_documents with an update_date > last_checked
83
    try
84
    {
85 1217 tao
      //try
86
      //{ //this connection is prone to error for some reason so we
87 683 berkley
        //try to connect it three times before quiting.
88 1217 tao
        //conn = util.openDBConnection();
89
      //}
90
      //catch(SQLException sqle)
91
      //{
92 1071 tao
        /*try
93 683 berkley
        {
94
          conn = util.openDBConnection();
95
        }
96
        catch(SQLException sqlee)
97
        {
98
          try
99
          {
100
            conn = util.openDBConnection();
101
          }
102
          catch(SQLException sqleee)
103 1071 tao
          {*/
104 1217 tao
            //System.out.println("error getting db connection in " +
105
                               //"ReplicationHandler.run: " +
106
                               //sqle.getMessage());
107 1071 tao
          //}
108
        //}
109 1217 tao
      //}
110
      serverList = buildServerList();
111 1032 tao
      //if serverList is null, metacat don't need to replication
112
      if (serverList==null||serverList.isEmpty())
113
      {
114
        return;
115
      }
116 697 bojilova
      updateCatalog(serverList);
117 683 berkley
      update(serverList);
118 1217 tao
      //conn.close();
119
    }//try
120 522 berkley
    catch (Exception e)
121
    {
122 1217 tao
      MetaCatUtil.debugMessage("Error in replicationHandler.run():"
123
                                                    +e.getMessage(), 30);
124
    }//catch
125 522 berkley
  }
126
127
  /**
128 577 berkley
   * Method that uses revision taging for replication instead of update_date.
129
   */
130 683 berkley
  private void update(Hashtable serverList)
131 577 berkley
  {
132
    /*
133
     Pseudo-algorithm
134
     - request a doc list from each server in xml_replication
135
     - check the rev number of each of those documents agains the
136
       documents in the local database
137
     - pull any documents that have a lesser rev number on the local server
138
       from the remote server
139
     - delete any documents that still exist in the local xml_documents but
140
       are in the deletedDocuments tag of the remote host response.
141
     - update last_checked to keep track of the last time it was checked.
142
       (this info is theoretically not needed using this system but probably
143
       should be kept anyway)
144
    */
145 683 berkley
146 1217 tao
    DBConnection dbConn = null;
147
    int serialNumber = -1;
148
    /*try
149 683 berkley
    {
150 1037 tao
      conn = util.getConnection();
151 683 berkley
    }
152 1037 tao
    catch (Exception e)
153 683 berkley
    {
154 1037 tao
      util.debugMessage("There is problem to get conncetion: "+e.getMessage());
155 1217 tao
    }*/
156 683 berkley
157 577 berkley
    Enumeration keys;
158
    String server;
159
    String update;
160
    ReplMessageHandler message = new ReplMessageHandler();
161
    Vector responses = new Vector();
162 667 berkley
    PreparedStatement pstmt = null;
163 577 berkley
    ResultSet rs;
164
    boolean tablehasrows;
165
    boolean flag=false;
166 1037 tao
    boolean dataFile=false;
167 577 berkley
    String action = new String();
168
    XMLReader parser;
169
    URL u;
170
171
    try
172
    {
173 1217 tao
      dbConn=DBConnectionPool.
174
                  getDBConnection("ReplicationHandler.update");
175
      serialNumber=dbConn.getCheckOutSerialNumber();
176 590 berkley
      MetaCatUtil.debugMessage("init parser");
177 577 berkley
      parser = initParser(message);
178
      keys = serverList.keys();
179
      while(keys.hasMoreElements())
180
      {
181
        server = (String)(keys.nextElement());
182 584 berkley
        MetacatReplication.replLog("full update started to: " + server);
183 1011 tao
        u = new URL("https://" + server + "?server="
184 1015 tao
        +util.getLocalReplicationServerName()+"&action=update");
185 1011 tao
        //System.out.println("Sending Message: " + u.toString());
186 577 berkley
        String result = MetacatReplication.getURLContent(u);
187 1102 tao
        //check if result have error or not
188
        if (result.indexOf("error")!=-1)
189
        {
190
          continue;
191
        }
192 577 berkley
        responses.add(result);
193
      }
194
195 1032 tao
      //make sure that there is updated file list
196
      //If response is null, mecat don't need do anything
197
       if (responses==null||responses.isEmpty())
198
      {
199
        return;
200
      }
201
202 675 berkley
      //String srvr = util.getOption("servletpath");
203 577 berkley
204 675 berkley
      //System.out.println("responses (from srvr): " + responses.toString());
205
206 577 berkley
      for(int i=0; i<responses.size(); i++)
207
      { //check each server for updated files
208
        //System.out.println("parsing responses");
209
        parser.parse(new InputSource(
210
                     new StringReader(
211
                     (String)(responses.elementAt(i)))));
212 1037 tao
        //v is the list of updated documents
213 577 berkley
        Vector v = new Vector(message.getUpdatesVect());
214
        //System.out.println("v: " + v.toString());
215 1037 tao
        //d is the list of deleted documents
216 577 berkley
        Vector d = new Vector(message.getDeletesVect());
217 1037 tao
        //System.out.println("d: " + d.toString());
218 577 berkley
        //check the revs in u to see if there are any newer ones than
219
        //in the local DB.
220 1071 tao
        MetaCatUtil.debugMessage("Update vector size: "+ v.size(), 20);
221
        MetaCatUtil.debugMessage("Delete vector size: "+ d.size(),20);
222 577 berkley
        for(int j=0; j<v.size(); j++)
223
        {
224 1037 tao
          //initial dataFile is false
225
          dataFile=false;
226
          //w is information for one document, information contain
227
          //docid, rev, server or datafile.
228 577 berkley
          Vector w = new Vector((Vector)(v.elementAt(j)));
229 1037 tao
          //Check if the vector w contain "datafile"
230
          //If it has, this document is data file
231
          if (w.contains((String)util.getOption("datafileflag")))
232
          {
233
            dataFile=true;
234
          }
235 577 berkley
          //System.out.println("w: " + w.toString());
236
          String docid = (String)w.elementAt(0);
237 1071 tao
          MetaCatUtil.debugMessage("docid: " + docid, 40);
238 577 berkley
          int rev = Integer.parseInt((String)w.elementAt(1));
239 1071 tao
          MetaCatUtil.debugMessage("rev: " + rev, 40);
240 577 berkley
          String docServer = (String)w.elementAt(2);
241 1071 tao
242 577 berkley
243 1217 tao
         pstmt = dbConn.prepareStatement("select rev from xml_documents where "+
244 577 berkley
                                        "docid like '" + docid + "'");
245
          pstmt.execute();
246
          rs = pstmt.getResultSet();
247
          tablehasrows = rs.next();
248
          if(tablehasrows)
249
          { //check the revs for an update because this document is in the
250
            //local DB, it just might be out of date.
251
            int localrev = rs.getInt(1);
252
            if(localrev == rev)
253
            {
254
              flag = false;
255
            }
256
            else if(localrev < rev)
257
            {//this document needs to be updated so send an read request
258
              action = "UPDATE";
259
              flag = true;
260
            }
261
          }
262
          else
263
          { //insert this document as new because it is not in the local DB
264
            action = "INSERT";
265
            flag = true;
266
          }
267
268 1037 tao
          // this is non-data file
269
          if(flag && !dataFile)
270 577 berkley
          { //if the document needs to be updated or inserted, this is executed
271 1011 tao
            u = new URL("https://" + docServer + "?server="+
272 1015 tao
              util.getLocalReplicationServerName()+"&action=read&docid="+docid);
273 1011 tao
            //System.out.println("Sending message: " + u.toString());
274 577 berkley
            String newxmldoc = MetacatReplication.getURLContent(u);
275 1098 tao
            if ( newxmldoc.indexOf("error")!= -1)
276
            {
277 1100 tao
              continue;
278 1098 tao
            }
279 1071 tao
            MetaCatUtil.debugMessage("xml documnet:", 50);
280
            MetaCatUtil.debugMessage(newxmldoc, 50);
281 577 berkley
            DocInfoHandler dih = new DocInfoHandler();
282
            XMLReader docinfoParser = initParser(dih);
283 837 bojilova
            URL docinfoUrl = new URL("https://" + docServer +
284 1015 tao
                  "?server="+util.getLocalReplicationServerName()+
285 1011 tao
                  "&action=getdocumentinfo&docid="+docid);
286
            //System.out.println("Sending message: " + docinfoUrl.toString());
287 577 berkley
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
288
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
289
            Hashtable docinfoHash = dih.getDocInfo();
290 1068 tao
            String docHomeServer = (String)docinfoHash.get("home_server");
291
            //int serverCode = MetacatReplication.getServerCode(docServer);
292 1011 tao
            //System.out.println("updating doc: " + docid +" action: "+ action);
293
            //docid should include rev number too
294
            String accnum=docid+util.getOption("accNumSeparator")+
295
                                              (String)docinfoHash.get("rev");
296
            //System.out.println("accnum: "+accnum);
297 625 berkley
            try
298
            {
299 1068 tao
300 1217 tao
              String newDocid = DocumentImpl.writeReplication(dbConn,
301 577 berkley
                              new StringReader(newxmldoc),
302 697 bojilova
                              (String)docinfoHash.get("public_access"),
303
                              null,  /* the dtd text */
304 577 berkley
                              action,
305 1011 tao
                              accnum,
306 577 berkley
                              (String)docinfoHash.get("user_owner"),
307 804 bojilova
                              null, /* null for groups[] */
308 1068 tao
                              docHomeServer,
309 697 bojilova
                              false /* validate */);
310 1217 tao
              //increase usage
311
              dbConn.increaseUsageCount(1);
312 625 berkley
              MetacatReplication.replLog("wrote doc " + docid + " from " +
313
                                         docServer);
314 1011 tao
              /*System.out.println("wrote doc " + docid + " from " +
315
                                 docServer);*/
316 625 berkley
            }
317
            catch(Exception e)
318
            {
319 675 berkley
              System.out.println("error writing document in " +
320
                                 "ReplicationHandler.update: " + docid +
321
                                 ": " + e.getMessage());
322 625 berkley
            }
323 1037 tao
          }//if for non-data file
324
325 1078 tao
           // this is for data file and metacat is configured to accetp datafile
326
          if(flag && dataFile
327
                   && (util.getOption("replicationacceptdata")).equals("on"))
328 1037 tao
          {
329
            //if the document needs to be updated or inserted, this is executed
330
            //String newxmldoc = MetacatReplication.getURLContent(u);
331
            DocInfoHandler dih = new DocInfoHandler();
332
            XMLReader docinfoParser = initParser(dih);
333
            URL docinfoUrl = new URL("https://" + docServer +
334
                  "?server="+util.getLocalReplicationServerName()+
335
                  "&action=getdocumentinfo&docid="+docid);
336
            //System.out.println("Sending message: " + docinfoUrl.toString());
337
            String docInfoStr = MetacatReplication.getURLContent(docinfoUrl);
338
            docinfoParser.parse(new InputSource(new StringReader(docInfoStr)));
339
            Hashtable docinfoHash = dih.getDocInfo();
340
            String user = (String)docinfoHash.get("user_owner");
341
            String docName = (String)docinfoHash.get("docname");
342
            String docType = (String)docinfoHash.get("doctype");
343 1066 tao
            String docHomeServer = (String)docinfoHash.get("home_server");
344 1068 tao
345 1066 tao
            //int serverCode = MetacatReplication.getServerCode(docServer);
346 1037 tao
            //System.out.println("updating doc: " + docid +" action: "+ action);
347
            //docid should include rev number too
348
            String accnum=docid+util.getOption("accNumSeparator")+
349
                                              (String)docinfoHash.get("rev");
350
            String datafilePath = util.getOption("datafilepath");
351
            u = new URL("https://" + docServer + "?server="+
352
                                        util.getLocalReplicationServerName()+
353
                                            "&action=readdata&docid="+accnum);
354
            //System.out.println("accnum: "+accnum);
355
            try
356
            {
357
358
              //register data file into xml_documents table and wite data file
359
              //into file system
360 1098 tao
              if (u.openStream() != null)
361
              {
362 1037 tao
              DocumentImpl.writeDataFile(u.openStream(), datafilePath,
363 1066 tao
                                  docName,docType, accnum, user,docHomeServer);
364 1037 tao
365
              MetacatReplication.replLog("wrote doc " + docid + " from " +
366
                                         docServer);
367 1098 tao
              }
368
              else
369
              {
370 1100 tao
                continue;
371 1098 tao
              }
372 1037 tao
              /*System.out.println("wrote doc " + docid + " from " +
373
                                 docServer);*/
374
            }
375
            catch(Exception e)
376
            {
377
              System.out.println("error writing document in " +
378
                                 "ReplicationHandler.update: " + docid +
379
                                 ": " + e.getMessage());
380
            }
381
          }//for datafile
382
        }//for update docs
383 577 berkley
384 1037 tao
        //handle deleted docs
385 577 berkley
        for(int k=0; k<d.size(); k++)
386
        { //delete the deleted documents;
387
          Vector w = new Vector((Vector)d.elementAt(k));
388
          String docid = (String)w.elementAt(0);
389 1217 tao
          if(!alreadyDeleted(docid))
390 579 berkley
          {
391 1037 tao
392
            //because delete method docid should have rev number
393
            //so we just add one for it. This rev number is no sence.
394
            String accnum=docid+util.getOption("accNumSeparator")+"1";
395
            //System.out.println("accnum: "+accnum);
396 1217 tao
            DocumentImpl.delete(accnum, null, null);
397 584 berkley
            MetacatReplication.replLog("doc " + docid + " deleted");
398 579 berkley
          }
399 1037 tao
        }//for delete docs
400 577 berkley
401 1037 tao
        //updated last_checked
402 577 berkley
        keys = serverList.keys();
403
        while(keys.hasMoreElements())
404
        {
405
          server = (String)(keys.nextElement());
406 1011 tao
          URL dateurl = new URL("https://" + server + "?server="+
407 1015 tao
          util.getLocalReplicationServerName()+"&action=gettime");
408 577 berkley
          String datexml = MetacatReplication.getURLContent(dateurl);
409 1071 tao
          MetaCatUtil.debugMessage("datexml: "+datexml, 40);
410
          if (datexml!=null && !datexml.equals(""))
411
          {
412
            String datestr = datexml.substring(11, datexml.indexOf('<', 11));
413
            StringBuffer sql = new StringBuffer();
414
            sql.append("update xml_replication set last_checked = to_date('");
415
            sql.append(datestr).append("', 'YY-MM-DD HH24:MI:SS') where ");
416
            sql.append("server like '").append(server).append("'");
417
            //System.out.println("sql: " + sql.toString());
418
            pstmt.close();
419 1217 tao
            pstmt = dbConn.prepareStatement(sql.toString());
420
            //increase usage count
421
            dbConn.increaseUsageCount(1);
422 1071 tao
            pstmt.executeUpdate();
423 1217 tao
            dbConn.commit();
424 1071 tao
            System.out.println("last_checked updated to " + datestr + " on " +
425 590 berkley
                            server);
426 1071 tao
          }
427 1037 tao
        }//wile
428
      }//for
429
    }//try
430 577 berkley
    catch(Exception e)
431
    {
432 1011 tao
      /*System.out.println("error in ReplicationHandler.update: " +
433
                          e.getMessage());*/
434 577 berkley
      e.printStackTrace(System.out);
435
    }
436 667 berkley
    finally
437
    {
438
      try
439
      {
440
        pstmt.close();
441 1217 tao
      }//try
442
      catch(Exception ee)
443
      {
444
        MetaCatUtil.debugMessage("Error in ReplicationHandler.update to close"+
445
                                " pstmt: "+ee.getMessage(), 30);
446
      }//catch
447
      finally
448
      {
449
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
450
      }//finally
451 1037 tao
    }//finally
452
  }//update
453 577 berkley
454
  /**
455 590 berkley
   * updates xml_catalog with entries from other servers.
456
   */
457 683 berkley
  private void updateCatalog(Hashtable serverList)
458 590 berkley
  {
459 1217 tao
    DBConnection dbConn = null;
460
    int serialNumber = -1;
461
    PreparedStatement pstmt = null;
462 590 berkley
    try
463
    {
464 1217 tao
      /*try
465
      {
466 683 berkley
        conn = util.openDBConnection();
467
      }
468
      catch(SQLException sqle)
469
      {
470
        try
471
        {
472
          conn = util.openDBConnection();
473
        }
474
        catch(SQLException sqlee)
475
        {
476
          try
477
          {
478
            conn = util.openDBConnection();
479
          }
480
          catch(SQLException sqleee)
481
          {
482
            System.out.println("error getting db connection in " +
483
                               "ReplicationHandler.update: " +
484
                               sqleee.getMessage());
485
          }
486
        }
487 1217 tao
      }*/
488
489
      dbConn=DBConnectionPool.
490
                  getDBConnection("ReplicationHandler.updateCatalog");
491
      serialNumber=dbConn.getCheckOutSerialNumber();
492 590 berkley
      String server;
493
      Enumeration keys = serverList.keys();
494
      while(keys.hasMoreElements())
495
      { //go through each server
496
        server = (String)(keys.nextElement());
497 1011 tao
        URL u = new URL("https://" + server + "?server="+
498 1015 tao
        util.getLocalReplicationServerName()+"&action=getcatalog");
499
        //System.out.println("sending message " + u.toString());
500 590 berkley
        String catxml = MetacatReplication.getURLContent(u);
501 595 berkley
        //System.out.println("catxml: " + catxml);
502 590 berkley
        CatalogMessageHandler cmh = new CatalogMessageHandler();
503
        XMLReader catparser = initParser(cmh);
504
        catparser.parse(new InputSource(new StringReader(catxml)));
505
        //parse the returned catalog xml and put it into a vector
506
        Vector remoteCatalog = cmh.getCatalogVect();
507
508
        String localcatxml = MetacatReplication.getCatalogXML();
509 595 berkley
        //System.out.println("localcatxml: " + localcatxml);
510 590 berkley
        cmh = new CatalogMessageHandler();
511
        catparser = initParser(cmh);
512
        catparser.parse(new InputSource(new StringReader(localcatxml)));
513
        Vector localCatalog = cmh.getCatalogVect();
514
515
        //now we have the catalog from the remote server and this local server
516
        //we now need to compare the two and merge the differences.
517
        //the comparison is base on the public_id fields which is the 4th
518
        //entry in each row vector.
519
        Vector publicId = new Vector();
520
        for(int i=0; i<localCatalog.size(); i++)
521
        {
522
          Vector v = new Vector((Vector)localCatalog.elementAt(i));
523 595 berkley
          //System.out.println("v1: " + v.toString());
524 590 berkley
          publicId.add(new String((String)v.elementAt(3)));
525 595 berkley
          //System.out.println("adding " + (String)v.elementAt(3));
526 590 berkley
        }
527
528
        for(int i=0; i<remoteCatalog.size(); i++)
529
        {
530
          Vector v = (Vector)remoteCatalog.elementAt(i);
531 595 berkley
          //System.out.println("v2: " + v.toString());
532 590 berkley
          //System.out.println("i: " + i);
533
          //System.out.println("remoteCatalog.size(): " + remoteCatalog.size());
534 595 berkley
          //System.out.println("publicID: " + publicId.toString());
535
          //System.out.println("v.elementAt(3): " + (String)v.elementAt(3));
536 590 berkley
          if(!publicId.contains(v.elementAt(3)))
537
          { //so we don't have this public id in our local table so we need to
538
            //add it.
539 595 berkley
            //System.out.println("in if");
540 590 berkley
            StringBuffer sql = new StringBuffer();
541
            sql.append("insert into xml_catalog (entry_type, source_doctype, ");
542
            sql.append("target_doctype, public_id, system_id) values (?,?,?,");
543
            sql.append("?,?)");
544 595 berkley
            //System.out.println("sql: " + sql.toString());
545 1217 tao
            pstmt = dbConn.prepareStatement(sql.toString());
546
            //increase usage count 1
547
            dbConn.increaseUsageCount(1);
548 590 berkley
            pstmt.setString(1, (String)v.elementAt(0));
549
            pstmt.setString(2, (String)v.elementAt(1));
550
            pstmt.setString(3, (String)v.elementAt(2));
551
            pstmt.setString(4, (String)v.elementAt(3));
552
            pstmt.setString(5, (String)v.elementAt(4));
553
            pstmt.execute();
554 667 berkley
            pstmt.close();
555 590 berkley
          }
556
        }
557
      }
558 1217 tao
      //conn.close();
559 590 berkley
    }
560
    catch(Exception e)
561
    {
562 675 berkley
      System.out.println("error in ReplicationHandler.updateCatalog: " +
563
                          e.getMessage());
564 590 berkley
      e.printStackTrace(System.out);
565 1217 tao
    }//catch
566
    finally
567
    {
568 1037 tao
      try
569
      {
570 1217 tao
        pstmt.close();
571
      }//try
572
      catch (SQLException ee)
573 1037 tao
      {
574 1217 tao
        MetaCatUtil.debugMessage("Error in ReplicationHandler.updateCatalog "+
575
                      "to close pstmt: "+ee.getMessage(), 30);
576
      }//catch
577
      finally
578
      {
579
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
580
      }//finally
581
    }//finall
582 590 berkley
  }
583
584
  /**
585 579 berkley
   * Method that returns true if docid has already been "deleted" from metacat.
586 582 berkley
   * This method really implements a truth table for deleted documents
587 590 berkley
   * The table is (a docid in one of the tables is represented by the X):
588 582 berkley
   * xml_docs      xml_revs      deleted?
589
   * ------------------------------------
590
   *   X             X             FALSE
591
   *   X             _             FALSE
592
   *   _             X             TRUE
593
   *   _             _             TRUE
594 579 berkley
   */
595 1217 tao
  private static boolean alreadyDeleted(String docid)
596 579 berkley
  {
597 1217 tao
    DBConnection dbConn = null;
598
    int serialNumber = -1;
599
    PreparedStatement pstmt = null;
600 579 berkley
    try
601
    {
602 1217 tao
      dbConn=DBConnectionPool.
603
                  getDBConnection("ReplicationHandler.alreadyDeleted");
604
      serialNumber=dbConn.getCheckOutSerialNumber();
605 582 berkley
      boolean xml_docs = false;
606
      boolean xml_revs = false;
607
608 579 berkley
      StringBuffer sb = new StringBuffer();
609 582 berkley
      sb.append("select docid from xml_revisions where docid like '");
610 579 berkley
      sb.append(docid).append("'");
611 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
612 579 berkley
      pstmt.execute();
613
      ResultSet rs = pstmt.getResultSet();
614
      boolean tablehasrows = rs.next();
615
      if(tablehasrows)
616
      {
617 582 berkley
        xml_revs = true;
618
      }
619
620
      sb = new StringBuffer();
621
      sb.append("select docid from xml_documents where docid like '");
622
      sb.append(docid).append("'");
623 667 berkley
      pstmt.close();
624 1217 tao
      pstmt = dbConn.prepareStatement(sb.toString());
625
      //increase usage count
626
      dbConn.increaseUsageCount(1);
627 582 berkley
      pstmt.execute();
628
      rs = pstmt.getResultSet();
629
      tablehasrows = rs.next();
630 667 berkley
      pstmt.close();
631 582 berkley
      if(tablehasrows)
632
      {
633
        xml_docs = true;
634
      }
635
636
      if(xml_docs && xml_revs)
637
      {
638
        return false;
639
      }
640
      else if(xml_docs && !xml_revs)
641
      {
642
        return false;
643
      }
644
      else if(!xml_docs && xml_revs)
645
      {
646 579 berkley
        return true;
647
      }
648 582 berkley
      else if(!xml_docs && !xml_revs)
649
      {
650
        return true;
651
      }
652 579 berkley
    }
653
    catch(Exception e)
654
    {
655 675 berkley
      System.out.println("error in ReplicationHandler.alreadyDeleted: " +
656
                          e.getMessage());
657 579 berkley
      e.printStackTrace(System.out);
658
    }
659 667 berkley
    finally
660
    {
661 1217 tao
      try
662
      {
663
        pstmt.close();
664
      }//try
665
      catch (SQLException ee)
666
      {
667
        MetaCatUtil.debugMessage("Error in replicationHandler.alreadyDeleted "+
668
                          "to close pstmt: "+ee.getMessage(), 30);
669
      }//catch
670
      finally
671
      {
672
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
673
      }//finally
674
    }//finally
675 579 berkley
    return false;
676
  }
677
678
  /**
679 533 berkley
   * Checks to see if a document is already in the DB.  Returns
680
   * "UPDATE" if it is, "INSERT" if it isn't
681
   */
682
  private static String getAction(String docid)
683
  {
684 1217 tao
    DBConnection dbConn = null;
685
    int serialNumber = -1;
686
    PreparedStatement pstmt = null;
687 533 berkley
    try
688
    {
689 1217 tao
      dbConn=DBConnectionPool.
690
                  getDBConnection("ReplicationHandler.getAction");
691
      serialNumber=dbConn.getCheckOutSerialNumber();
692
      //MetaCatUtil util = new MetaCatUtil();
693 533 berkley
      StringBuffer sql = new StringBuffer();
694
      sql.append("select docid from xml_documents where docid like '");
695
      sql.append(docid).append("'");
696 1217 tao
      //Connection conn = util.openDBConnection();
697
      pstmt = dbConn.prepareStatement(sql.toString());
698 533 berkley
      pstmt.execute();
699
      ResultSet rs = pstmt.getResultSet();
700
701
      if(rs.next())
702
      {
703 667 berkley
        pstmt.close();
704 1217 tao
        //conn.close();
705 533 berkley
        return "UPDATE";
706
      }
707
      else
708
      {
709 667 berkley
        pstmt.close();
710 1217 tao
        //conn.close();
711 533 berkley
        return "INSERT";
712
      }
713
    }
714
    catch(Exception e)
715
    {
716
      System.out.println("error in replicationHandler.getAction: " +
717
                          e.getMessage());
718
    }
719 1217 tao
    finally
720
    {
721
      try
722
      {
723
        pstmt.close();
724
      }
725
      catch (SQLException sqlE)
726
      {
727
        MetaCatUtil.debugMessage("error in replicationHandler.getAction: " +
728
                     "to close pstmt: "+ sqlE.getMessage(), 30);
729
      }
730
      finally
731
      {
732
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
733
      }
734
    }//finally
735 533 berkley
    return "";
736
  }
737
738
  /**
739 522 berkley
   * Method to query xml_replication and build a hashtable of each server
740
   * and it's last update time.
741
   * @param conn a connection to the database
742
   */
743 1217 tao
  public static Hashtable buildServerList()
744 522 berkley
  {
745 1217 tao
    DBConnection dbConn = null;
746
    int serialNumber = -1;
747 522 berkley
    Hashtable sl = new Hashtable();
748 1217 tao
    PreparedStatement pstmt = null;
749 522 berkley
    try
750
    {
751 1217 tao
      dbConn=DBConnectionPool.
752
                  getDBConnection("ReplicationHandler.buildServerList");
753
      serialNumber=dbConn.getCheckOutSerialNumber();
754
      pstmt = dbConn.prepareStatement("select server, last_checked, replicate "+
755 629 berkley
                                    "from xml_replication");
756 522 berkley
      pstmt.execute();
757
      ResultSet rs = pstmt.getResultSet();
758
      boolean tableHasRows = rs.next();
759
      while(tableHasRows)
760
      {
761 629 berkley
        if(rs.getInt(3) == 1)
762
        {//only put the server in the list if the replicate flag is true
763
          String server = rs.getString(1);
764
          String last_checked = rs.getString(2);
765
          if(!server.equals("localhost"))
766
          {
767
            sl.put(server, last_checked);
768
          }
769 549 berkley
        }
770 629 berkley
        tableHasRows = rs.next();
771 522 berkley
      }
772 667 berkley
      pstmt.close();
773 522 berkley
    }
774
    catch(Exception e)
775
    {
776
      System.out.println("error in replicationHandler.buildServerList(): " +
777
                         e.getMessage());
778
    }
779 1217 tao
    finally
780
    {
781
      try
782
      {
783
        pstmt.close();
784
      }//try
785
      catch (SQLException sqlE)
786
      {
787
        MetaCatUtil.debugMessage("Error in ReplicationHandler.buildServerList: "
788
                                +sqlE.getMessage());
789
      }//catch
790
      finally
791
      {
792
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
793
      }//finally
794
    }//finally
795
796 522 berkley
    return sl;
797
  }
798 1043 tao
   /**
799
   * Method to get a host server information for given docid
800
   * @param conn a connection to the database
801
   */
802
  public static Hashtable getHomeServer(String docId)
803
  {
804
    Hashtable sl = new Hashtable();
805 1217 tao
    DBConnection dbConn = null;
806
    int serialNumber = -1;
807
    //MetaCatUtil ut=new MetaCatUtil();
808
    docId=MetaCatUtil.getDocIdFromString(docId);
809 1043 tao
    PreparedStatement pstmt=null;
810
    int serverLocation;
811
    try
812
    {
813 1217 tao
      //get conection
814
      dbConn=DBConnectionPool.
815
                  getDBConnection("ReplicationHandler.getHomeServer");
816
      serialNumber=dbConn.getCheckOutSerialNumber();
817 1043 tao
      //get a server location from xml_document table
818 1217 tao
      pstmt=dbConn.prepareStatement("select server_location from xml_documents "
819 1058 tao
                                            +"where docid = ?");
820 1043 tao
      pstmt.setString(1, docId);
821
      pstmt.execute();
822
      ResultSet serverName = pstmt.getResultSet();
823
      //get a server location
824
      if(serverName.next())
825
      {
826
        serverLocation=serverName.getInt(1);
827
        pstmt.close();
828
      }
829
      else
830
      {
831
        pstmt.close();
832 1217 tao
        //ut.returnConnection(conn);
833 1043 tao
        return null;
834
      }
835 1217 tao
      pstmt=dbConn.prepareStatement("select server, last_checked, replicate " +
836 1043 tao
                        "from xml_replication where serverid = ?");
837 1217 tao
      //increase usage count
838
      dbConn.increaseUsageCount(1);
839 1043 tao
      pstmt.setInt(1, serverLocation);
840
      pstmt.execute();
841
      ResultSet rs = pstmt.getResultSet();
842
      boolean tableHasRows = rs.next();
843
      if (tableHasRows)
844
      {
845
846
          String server = rs.getString(1);
847
          String last_checked = rs.getString(2);
848
          if(!server.equals("localhost"))
849
          {
850
            sl.put(server, last_checked);
851
          }
852
853
      }
854
      else
855
      {
856
        pstmt.close();
857 1217 tao
        //ut.returnConnection(conn);
858 1043 tao
        return null;
859
      }
860
      pstmt.close();
861
    }
862
    catch(Exception e)
863
    {
864 1217 tao
      System.out.println("error in replicationHandler.getHomeServer(): " +
865 1043 tao
                         e.getMessage());
866
    }
867
    finally
868
    {
869
      try
870
      {
871
        pstmt.close();
872 1217 tao
        //ut.returnConnection(conn);
873 1043 tao
      }
874
      catch (Exception ee)
875
      {
876 1217 tao
        MetaCatUtil.debugMessage("Eror irn rplicationHandler.getHomeServer() "+
877
                          "to close pstmt: "+ee.getMessage(), 30);
878 1043 tao
      }
879 1217 tao
      finally
880
      {
881
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
882
      }
883
884
    }//finally
885 1043 tao
    return sl;
886
  }
887 574 berkley
888
  /**
889 1043 tao
   * Returns a server location  given a accnum
890
   * @param accNum , given accNum for a document
891
   *
892
   */
893
  public static int getServerLocation(String accNum) throws Exception
894
  {
895 1217 tao
    DBConnection dbConn = null;
896
    int serialNumber = -1;
897 1043 tao
    PreparedStatement pstmt = null;
898
    int serverCode = 1;
899 1217 tao
    //MetaCatUtil ut = new MetaCatUtil();
900
    String docId=MetaCatUtil.getDocIdFromString(accNum);
901 1043 tao
902
    try
903
    {
904
905 1217 tao
      //conn = ut.openDBConnection();
906
      //get conection
907
      dbConn=DBConnectionPool.
908
                  getDBConnection("ReplicationHandler.getServerLocation");
909
      serialNumber=dbConn.getCheckOutSerialNumber();
910
      pstmt=dbConn.prepareStatement("SELECT server_location FROM xml_documents "
911 1043 tao
                              + "WHERE docid LIKE '" + docId + "'");
912
      pstmt.execute();
913
      ResultSet rs = pstmt.getResultSet();
914
      boolean tablehasrows = rs.next();
915
      //If a document is find, return the server location for it
916
      if ( tablehasrows )
917
      {
918
        serverCode = rs.getInt(1);
919
        pstmt.close();
920 1217 tao
        //conn.close();
921 1043 tao
        return serverCode;
922
      }
923
      //if couldn't find in xml_documents table, we think server code is 1
924
      //(this is new document)
925
      else
926
      {
927
        pstmt.close();
928 1217 tao
        //conn.close();
929 1043 tao
        return serverCode;
930
      }
931
932
    }
933
    catch(Exception e)
934
    {
935
936
      throw e;
937
938
    }
939
    finally
940
    {
941
      try
942
      {
943
        pstmt.close();
944 1217 tao
        //conn.close();
945
946 1043 tao
      }
947
      catch(Exception ee)
948
      {
949 1217 tao
        MetaCatUtil.debugMessage("Erorr in Replication.getServerLocation "+
950
                     "to close pstmt"+ee.getMessage(), 30);
951 1043 tao
      }
952 1217 tao
      finally
953
      {
954
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
955
      }//finally
956 1043 tao
    }//finally
957 1217 tao
   //return serverCode;
958 1043 tao
  }
959
960
961
962
  /**
963 574 berkley
   * Method to initialize the message parser
964
   */
965
  public static XMLReader initParser(DefaultHandler dh)
966
          throws Exception
967
  {
968
    XMLReader parser = null;
969
970
    try {
971
      ContentHandler chandler = dh;
972
973
      // Get an instance of the parser
974
      MetaCatUtil util = new MetaCatUtil();
975
      String parserName = util.getOption("saxparser");
976
      parser = XMLReaderFactory.createXMLReader(parserName);
977
978
      // Turn off validation
979
      parser.setFeature("http://xml.org/sax/features/validation", false);
980
981
      parser.setContentHandler((ContentHandler)chandler);
982
      parser.setErrorHandler((ErrorHandler)chandler);
983
984
    } catch (Exception e) {
985
      throw e;
986
    }
987
988
    return parser;
989
  }
990 1011 tao
991 1015 tao
992 522 berkley
}