Project

General

Profile

1 393 jones
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that represents an XML document
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones
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 393 jones
 */
27
28
package edu.ucsb.nceas.metacat;
29
30
import java.sql.*;
31 429 jones
import java.io.File;
32
import java.io.FileReader;
33
import java.io.IOException;
34 393 jones
import java.io.PrintWriter;
35 429 jones
import java.io.Reader;
36
import java.io.StringWriter;
37
import java.io.Writer;
38 561 berkley
import java.io.InputStreamReader;
39 1029 tao
import java.io.*;
40 798 jones
import java.text.SimpleDateFormat;
41
42
import java.util.Date;
43 1432 tao
import java.util.Hashtable;
44 429 jones
import java.util.Iterator;
45 407 jones
import java.util.Stack;
46 429 jones
import java.util.TreeSet;
47 1432 tao
import java.util.Vector;
48 577 berkley
import java.util.Enumeration;
49 407 jones
50
import org.xml.sax.AttributeList;
51
import org.xml.sax.ContentHandler;
52
import org.xml.sax.DTDHandler;
53
import org.xml.sax.EntityResolver;
54
import org.xml.sax.ErrorHandler;
55
import org.xml.sax.InputSource;
56
import org.xml.sax.XMLReader;
57
import org.xml.sax.SAXException;
58
import org.xml.sax.SAXParseException;
59
import org.xml.sax.helpers.XMLReaderFactory;
60
61 561 berkley
import java.net.URL;
62
63 777 bojilova
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
64 747 bojilova
65 393 jones
/**
66
 * A class that represents an XML document. It can be created with a simple
67 407 jones
 * document identifier from a database connection.  It also will write an
68
 * XML text document to a database connection using SAX.
69 393 jones
 */
70
public class DocumentImpl {
71
72 1407 tao
   /* Constants */
73 1383 tao
   public static final String SCHEMA                 = "schema";
74
   public static final String DTD                    = "dtd";
75 1407 tao
   public static final String EML2                   = "eml2";
76 1383 tao
   public static final String EXTERNALSCHEMALOCATIONPROPERTY =
77
              "http://apache.org/xml/properties/schema/external-schemaLocation";
78 1407 tao
   /*public static final String EXTERNALSCHEMALOCATION =
79 1390 tao
     "eml://ecoinformatics.org/eml-2.0.0 http://dev.nceas.ucsb.edu/tao/schema/eml.xsd"+
80 1407 tao
      " http://www.xml-cml.org/schema/stmml http://dev.nceas.ucsb.edu/tao/schema/stmml.xsd";*/
81 1383 tao
   public static final String DECLARATIONHANDLERPROPERTY =
82
                            "http://xml.org/sax/properties/declaration-handler";
83
   public static final String LEXICALPROPERTY =
84
                             "http://xml.org/sax/properties/lexical-handler";
85
   public static final String VALIDATIONFEATURE =
86
                             "http://xml.org/sax/features/validation";
87
   public static final String SCHEMAVALIDATIONFEATURE =
88
                             "http://apache.org/xml/features/validation/schema";
89
   public static final String NAMESPACEFEATURE =
90
                              "http://xml.org/sax/features/namespaces";
91
   public static final String NAMESPACEPREFIXESFEATURE =
92
                              "http://xml.org/sax/features/namespace-prefixes";
93
94
95 425 bojilova
  static final int ALL = 1;
96
  static final int WRITE = 2;
97
  static final int READ = 4;
98 777 bojilova
  private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
99 425 bojilova
100 1217 tao
  private DBConnection connection = null;
101 393 jones
  private String docid = null;
102 956 tao
  private String updatedVersion=null;
103 393 jones
  private String docname = null;
104
  private String doctype = null;
105 691 bojilova
// DOCTITLE attr cleared from the db
106
//  private String doctitle = null;
107 465 berkley
  private String createdate = null;
108
  private String updatedate = null;
109 393 jones
  private String system_id = null;
110 561 berkley
  private String userowner = null;
111
  private String userupdated = null;
112 575 berkley
  private int rev;
113 561 berkley
  private int serverlocation;
114 1059 tao
  private String docHomeServer;
115 697 bojilova
  private String publicaccess;
116 393 jones
  private long rootnodeid;
117
  private ElementNode rootNode = null;
118 429 jones
  private TreeSet nodeRecordList = null;
119 1292 tao
  //private static
120
  //ReplicationServerList serverList = new ReplicationServerList();
121 790 bojilova
122
  /**
123 800 jones
   * Constructor used to create a document and read the document information
124
   * from the database.  If readNodes is false, then the node data is not
125
   * read at this time, but is deferred until it is needed (such as when a
126
   * call to toXml() is made).
127 790 bojilova
   *
128
   * @param conn the database connection from which to read the document
129 800 jones
   * @param docid the identifier of the document to be created
130
   * @param readNodes flag indicating whether the xmlnodes should be read
131 790 bojilova
   */
132 1217 tao
  public DocumentImpl(String docid, boolean readNodes)
133 802 bojilova
         throws McdbException
134 790 bojilova
  {
135 801 jones
    try {
136 1217 tao
      //this.conn = conn;
137 801 jones
      this.docid = docid;
138
139
      // Look up the document information
140
      getDocumentInfo(docid);
141 1217 tao
142 801 jones
      if (readNodes) {
143 800 jones
        // Download all of the document nodes using a single SQL query
144
        // The sort order of the records is determined by the NodeComparator
145
        // class, and needs to represent a depth-first traversal for the
146
        // toXml() method to work properly
147
        nodeRecordList = getNodeRecordList(rootnodeid);
148 1217 tao
149 801 jones
      }
150 800 jones
151 801 jones
    } catch (McdbException ex) {
152
      throw ex;
153
    } catch (Throwable t) {
154
      throw new McdbException("Error reading document from " +
155
                              "DocumentImpl.DocumentImpl: " + docid);
156 800 jones
    }
157 790 bojilova
  }
158 393 jones
159
  /**
160 396 jones
   * Constructor, creates document from database connection, used
161
   * for reading the document
162 393 jones
   *
163
   * @param conn the database connection from which to read the document
164
   * @param docid the identifier of the document to be created
165
   */
166 1217 tao
  public DocumentImpl(String docid) throws McdbException
167 393 jones
  {
168 1217 tao
    this(docid, true);
169 393 jones
  }
170
171 396 jones
  /**
172 415 jones
   * Construct a new document instance, writing the contents to the database.
173
   * This method is called from DBSAXHandler because we need to know the
174
   * root element name for documents without a DOCTYPE before creating it.
175 396 jones
   *
176
   * @param conn the JDBC Connection to which all information is written
177
   * @param rootnodeid - sequence id of the root node in the document
178
   * @param docname - the name of DTD, i.e. the name immediately following
179
   *        the DOCTYPE keyword ( should be the root element name ) or
180
   *        the root element name if no DOCTYPE declaration provided
181
   *        (Oracle's and IBM parsers are not aware if it is not the
182
   *        root element name)
183
   * @param doctype - Public ID of the DTD, i.e. the name immediately
184
   *                  following the PUBLIC keyword in DOCTYPE declaration or
185
   *                  the docname if no Public ID provided or
186
   *                  null if no DOCTYPE declaration provided
187 680 bojilova
   * @param docid the docid to use for the INSERT OR UPDATE
188
   * @param action the action to be performed (INSERT OR UPDATE)
189
   * @param user the user that owns the document
190
   * @param pub flag for public "read" access on document
191
   * @param serverCode the serverid from xml_replication on which this document
192
   *        resides.
193 396 jones
   *
194
   */
195 1217 tao
  /*public DocumentImpl(Connection conn, long rootnodeid, String docname,
196 549 berkley
                      String doctype, String docid, String action, String user,
197 697 bojilova
                      String pub, String catalogid, int serverCode)
198 549 berkley
                      throws SQLException, Exception
199
  {
200
    this.conn = conn;
201
    this.rootnodeid = rootnodeid;
202
    this.docname = docname;
203
    this.doctype = doctype;
204
    this.docid = docid;
205 697 bojilova
    writeDocumentToDB(action, user, pub, catalogid, serverCode);
206 1217 tao
  }*/
207 549 berkley
208 956 tao
  /**
209
   * Construct a new document instance, writing the contents to the database.
210
   * This method is called from DBSAXHandler because we need to know the
211
   * root element name for documents without a DOCTYPE before creating it.
212
   *
213
   * In this constructor, the docid is without rev. There is a string rev to
214
   * specify the revision user want to upadate. The revion is only need to be
215
   * greater than current one. It is not need to be sequent number just after
216
   * current one. So it is only used in update action
217
   * @param conn the JDBC Connection to which all information is written
218
   * @param rootnodeid - sequence id of the root node in the document
219
   * @param docname - the name of DTD, i.e. the name immediately following
220
   *        the DOCTYPE keyword ( should be the root element name ) or
221
   *        the root element name if no DOCTYPE declaration provided
222
   *        (Oracle's and IBM parsers are not aware if it is not the
223
   *        root element name)
224
   * @param doctype - Public ID of the DTD, i.e. the name immediately
225
   *                  following the PUBLIC keyword in DOCTYPE declaration or
226
   *                  the docname if no Public ID provided or
227
   *                  null if no DOCTYPE declaration provided
228
   * @param docid the docid to use for the UPDATE, no version number
229
   * @param version, need to be update
230
   * @param action the action to be performed (INSERT OR UPDATE)
231
   * @param user the user that owns the document
232
   * @param pub flag for public "read" access on document
233
   * @param serverCode the serverid from xml_replication on which this document
234
   *        resides.
235
   *
236
   */
237 1217 tao
  public DocumentImpl(DBConnection conn, long rootNodeId, String docName,
238 956 tao
                      String docType, String docId, String newRevision,
239
                      String action, String user,
240
                      String pub, String catalogId, int serverCode)
241
                      throws SQLException, Exception
242
  {
243 1217 tao
    this.connection = conn;
244 956 tao
    this.rootnodeid = rootNodeId;
245
    this.docname = docName;
246
    this.doctype = docType;
247
    this.docid = docId;
248
    this.updatedVersion = newRevision;
249
    writeDocumentToDB(action, user, pub, catalogId, serverCode);
250
  }
251
252 798 jones
  /**
253 1026 tao
   * This method will be call in handleUploadRequest in MetacatServlet class
254
   */
255
  public static void registerDocument(
256
                     String docname, String doctype, String accnum, String user)
257
                     throws SQLException, AccessionNumberException, Exception
258
  {
259 1217 tao
260 1063 tao
    try
261
    {
262 1217 tao
       // get server location for this doc
263
      int serverLocation=getServerLocationNumber(accnum);
264 1063 tao
      registerDocument(docname, doctype,accnum, user, serverLocation);
265
    }
266
    catch (Exception e)
267
    {
268
      throw e;
269
    }
270 1217 tao
271 1026 tao
272
  }
273
  /**
274 798 jones
   * Register a document that resides on the filesystem with the database.
275
   * (ie, just an entry in xml_documents, nothing in xml_nodes).
276
   * Creates a reference to a filesystem document (used for non-xml data files).
277 1055 tao
   * This class only be called in MetaCatServerlet.
278 798 jones
   * @param conn the JDBC Connection to which all information is written
279
   * @param docname - the name of DTD, i.e. the name immediately following
280
   *        the DOCTYPE keyword ( should be the root element name ) or
281
   *        the root element name if no DOCTYPE declaration provided
282
   *        (Oracle's and IBM parsers are not aware if it is not the
283
   *        root element name)
284
   * @param doctype - Public ID of the DTD, i.e. the name immediately
285
   *                  following the PUBLIC keyword in DOCTYPE declaration or
286
   *                  the docname if no Public ID provided or
287
   *                  null if no DOCTYPE declaration provided
288
   * @param accnum the accession number to use for the INSERT OR UPDATE, which
289
   *               includes a revision number for this revision of the document
290
   *               (e.g., knb.1.1)
291
   * @param user the user that owns the document
292
   * @param serverCode the serverid from xml_replication on which this document
293
   *        resides.
294
   */
295
  public static void registerDocument(
296
                     String docname, String doctype, String accnum,
297
                     String user, int serverCode)
298
                     throws SQLException, AccessionNumberException, Exception
299
  {
300 1217 tao
    DBConnection dbconn = null;
301
    int serialNumber = -1;
302
    PreparedStatement pstmt = null;
303
    //MetaCatUtil util = new MetaCatUtil();
304 965 tao
    AccessionNumber ac;
305 798 jones
    try {
306 1217 tao
      //dbconn = util.openDBConnection();
307
      //check out DBConnection
308
      dbconn=DBConnectionPool.
309
                    getDBConnection("DocumentImpl.registerDocument");
310
      serialNumber=dbconn.getCheckOutSerialNumber();
311 965 tao
      String docIdWithoutRev=MetaCatUtil.getDocIdFromString(accnum);
312
      int userSpecifyRev=MetaCatUtil.getVersionFromString(accnum);
313 1217 tao
      int revInDataBase=getLatestRevisionNumber(docIdWithoutRev);
314 965 tao
      //revIndataBase=-1, there is no record in xml_documents table
315
      //the data file is a new one, inert it into table
316
      //user specified rev should be great than 0
317
      if (revInDataBase==-1 && userSpecifyRev>0 )
318
      {
319 1217 tao
        ac = new AccessionNumber(accnum, "insert");
320 965 tao
      }
321
      //rev is greater the last revsion number and revInDataBase isn't -1
322
      // it is a updated data file
323
      else if (userSpecifyRev>revInDataBase && revInDataBase>0)
324
      {
325
326
        //archive the old entry
327 1217 tao
        archiveDocRevision(docIdWithoutRev, user);
328 965 tao
        //delete the old entry in xml_documents
329 1217 tao
        deleteXMLDocuments(docIdWithoutRev);
330
        ac = new AccessionNumber(accnum, "update");
331 965 tao
      }
332
      //other situation
333
      else
334
      {
335
336
        throw new Exception("Revision number couldn't be "
337
                    +userSpecifyRev);
338
      }
339 798 jones
      String docid = ac.getDocid();
340
      String rev = ac.getRev();
341
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
342
      Date localtime = new Date();
343
      String dateString = formatter.format(localtime);
344
345 946 tao
      String sqlDateString = "to_date('" + dateString +
346
                                          "', 'YY-MM-DD HH24:MI:SS')";
347 798 jones
348
      StringBuffer sql = new StringBuffer();
349
      sql.append("insert into xml_documents (docid, docname, doctype, ");
350 946 tao
      sql.append("user_owner, user_updated, server_location, rev,date_created");
351 798 jones
      sql.append(", date_updated, public_access) values ('");
352
      sql.append(docid).append("','");
353
      sql.append(docname).append("','");
354
      sql.append(doctype).append("','");
355
      sql.append(user).append("','");
356
      sql.append(user).append("','");
357
      sql.append(serverCode).append("','");
358
      sql.append(rev).append("',");
359
      sql.append(sqlDateString).append(",");
360
      sql.append(sqlDateString).append(",");
361
      sql.append("'0')");
362 1217 tao
      pstmt = dbconn.prepareStatement(sql.toString());
363 798 jones
      pstmt.execute();
364
      pstmt.close();
365 1217 tao
      //dbconn.close();
366 1063 tao
    }
367
    finally
368
    {
369
      try
370
      {
371 1217 tao
        pstmt.close();
372 1063 tao
      }
373 1217 tao
      finally
374 1063 tao
      {
375 1217 tao
        DBConnectionPool.returnDBConnection(dbconn, serialNumber);
376 1063 tao
      }
377 798 jones
    }
378
  }
379 1029 tao
380 1055 tao
    /**
381
   * Register a document that resides on the filesystem with the database.
382
   * (ie, just an entry in xml_documents, nothing in xml_nodes).
383
   * Creates a reference to a filesystem document (used for non-xml data files)
384
   * This method will be called for register data file in xml_documents in
385
   * Replication.
386
   * This method is revised from registerDocument.
387
   *
388
   * @param conn the JDBC Connection to which all information is written
389
   * @param docname - the name of DTD, i.e. the name immediately following
390
   *        the DOCTYPE keyword ( should be the root element name ) or
391
   *        the root element name if no DOCTYPE declaration provided
392
   *        (Oracle's and IBM parsers are not aware if it is not the
393
   *        root element name)
394
   * @param doctype - Public ID of the DTD, i.e. the name immediately
395
   *                  following the PUBLIC keyword in DOCTYPE declaration or
396
   *                  the docname if no Public ID provided or
397
   *                  null if no DOCTYPE declaration provided
398
   * @param accnum the accession number to use for the INSERT OR UPDATE, which
399
   *               includes a revision number for this revision of the document
400
   *               (e.g., knb.1.1)
401
   * @param user the user that owns the document
402
   * @param serverCode the serverid from xml_replication on which this document
403
   *        resides.
404
   */
405
  public static void registerDocumentInReplication(
406
                     String docname, String doctype, String accnum,
407
                     String user, int serverCode)
408
                     throws SQLException, AccessionNumberException, Exception
409
  {
410 1217 tao
    DBConnection dbconn = null;
411
    int serialNumber = -1;
412
    //MetaCatUtil util = new MetaCatUtil();
413 1055 tao
    AccessionNumber ac;
414 1217 tao
    PreparedStatement pstmt = null;
415 1055 tao
    try {
416 1217 tao
      //dbconn = util.openDBConnection();
417
       dbconn=DBConnectionPool.
418
                  getDBConnection("DocumentImpl.registerDocumentInReplication");
419
      serialNumber=dbconn.getCheckOutSerialNumber();
420 1055 tao
      String docIdWithoutRev=MetaCatUtil.getDocIdFromString(accnum);
421
      int userSpecifyRev=MetaCatUtil.getVersionFromString(accnum);
422 1217 tao
      int revInDataBase=getLatestRevisionNumber(docIdWithoutRev);
423 1055 tao
      //revIndataBase=-1, there is no record in xml_documents table
424
      //the data file is a new one, inert it into table
425
      //user specified rev should be great than 0
426
      if (revInDataBase==-1 && userSpecifyRev>0 )
427
      {
428 1063 tao
429 1217 tao
        ac = new AccessionNumber(accnum, "insert");
430 1055 tao
      }
431
      //rev is greater the last revsion number and revInDataBase isn't -1
432
      // it is a updated data file
433
      else if (userSpecifyRev>revInDataBase && revInDataBase>0)
434
      {
435
436
        //archive the old entry
437 1217 tao
        archiveDocRevision(docIdWithoutRev, user);
438 1055 tao
        //delete the old entry in xml_documents
439 1217 tao
        deleteXMLDocuments(docIdWithoutRev);
440
        ac = new AccessionNumber(accnum, "update");
441 1055 tao
      }
442 1292 tao
      // local server has newer version, then notify the remote server
443
      else if ( userSpecifyRev < revInDataBase && revInDataBase > 0)
444
      {
445
        throw new Exception("Local server: "+MetaCatUtil.getOption("server")+
446
                 " has newer revision of doc: "+docIdWithoutRev+"."
447
                  +revInDataBase+". Please notify it.");
448
      }
449 1055 tao
      //other situation
450
      else
451
      {
452
453
        throw new Exception("Revision number couldn't be "
454
                    +userSpecifyRev);
455
      }
456
      String docid = ac.getDocid();
457
      String rev = ac.getRev();
458
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
459
      Date localtime = new Date();
460
      String dateString = formatter.format(localtime);
461
462
      String sqlDateString = "to_date('" + dateString +
463
                                          "', 'YY-MM-DD HH24:MI:SS')";
464
465
      StringBuffer sql = new StringBuffer();
466
      sql.append("insert into xml_documents (docid, docname, doctype, ");
467
      sql.append("user_owner, user_updated, server_location, rev,date_created");
468
      sql.append(", date_updated, public_access) values ('");
469
      sql.append(docid).append("','");
470
      sql.append(docname).append("','");
471
      sql.append(doctype).append("','");
472
      sql.append(user).append("','");
473
      sql.append(user).append("','");
474
      sql.append(serverCode).append("','");
475
      sql.append(rev).append("',");
476
      sql.append(sqlDateString).append(",");
477
      sql.append(sqlDateString).append(",");
478
      sql.append("'0')");
479 1292 tao
      // Set auto commit fasle
480
      dbconn.setAutoCommit(false);
481 1217 tao
      pstmt = dbconn.prepareStatement(sql.toString());
482 1055 tao
      pstmt.execute();
483 1292 tao
      // Commit the insert
484
      dbconn.commit();
485 1055 tao
      pstmt.close();
486 1217 tao
      //dbconn.close();
487 1063 tao
    }
488
    finally
489
    {
490 1292 tao
      // Set DBConnection auto commit true
491
      dbconn.setAutoCommit(true);
492 1217 tao
      pstmt.close();
493
      DBConnectionPool.returnDBConnection(dbconn, serialNumber);
494 1055 tao
    }
495
  }
496
497 1021 tao
 /**
498 1029 tao
   * This method will register a data file entry in xml_documents and save a
499 1292 tao
   * data file input Stream into file system.. It is only used in replication
500 1029 tao
   *
501
   * @param  input, the input stream which contain the file content.
502
   * @param  , the input stream which contain the file content
503
   * @param docname - the name of DTD, for data file, it is a docid number.
504
   * @param doctype - "BIN" for data file
505
   * @param accnum the accession number to use for the INSERT OR UPDATE, which
506
   *               includes a revision number for this revision of the document
507
   *               (e.g., knb.1.1)
508
   * @param user the user that owns the document
509 1292 tao
   * @param docHomeServer, the home server of the docid
510
   * @param notificationServer, the server to notify force replication info to
511
   *                            local metacat
512 1029 tao
   */
513 1292 tao
 public static void writeDataFileInReplication(InputStream input,
514
                 String filePath, String docname, String doctype, String accnum,
515
                   String user, String docHomeServer, String notificationServer)
516 1029 tao
                     throws SQLException, AccessionNumberException, Exception
517
 {
518 1292 tao
    int serverCode=-2;
519
520
521 1029 tao
    if (filePath==null||filePath.equals(""))
522
    {
523
      throw new
524
            Exception("Please specify the directory where file will be store");
525
    }
526
    if (accnum==null||accnum.equals(""))
527
    {
528
      throw new Exception("Please specify the stored file name");
529
    }
530 1063 tao
531 1292 tao
532 1063 tao
533 1292 tao
    // If server is not int the xml replication talbe, insert it into
534
    // xml_replication table
535
    //serverList.addToServerListIfItIsNot(docHomeServer);
536
    insertServerIntoReplicationTable(docHomeServer);
537
538
    // Get server code again
539
    serverCode = getServerCode(docHomeServer);
540
541
542
    //register data file into xml_documents table
543
    registerDocumentInReplication(docname, doctype, accnum, user, serverCode);
544
    //write inputstream into file system.
545
    File dataDirectory = new File(filePath);
546
    File newFile = new File(dataDirectory, accnum);
547 1029 tao
548 1292 tao
    // create a buffered byte output stream
549
    // that uses a default-sized output buffer
550
    FileOutputStream fos = new FileOutputStream(newFile);
551
    BufferedOutputStream outPut = new BufferedOutputStream(fos);
552 1029 tao
553 1292 tao
    BufferedInputStream bis = null;
554
    bis = new BufferedInputStream(input);
555
    byte[] buf = new byte[4 * 1024]; // 4K buffer
556
    int b = bis.read(buf);
557 1029 tao
558 1292 tao
    while (b != -1)
559
    {
560 1029 tao
        outPut.write(buf, 0, b);
561
        b = bis.read(buf);
562 1292 tao
    }
563
    bis.close();
564
	  outPut.close();
565
	  fos.close();
566
567
    // Force replicate data file
568
    ForceReplicationHandler forceReplication = new ForceReplicationHandler
569
                                    (accnum, false, notificationServer);
570
571 1029 tao
 }
572
573 798 jones
574 1026 tao
575
  public static boolean getDataFileLockGrant(String accnum)
576
                                                  throws Exception
577
  {
578 1217 tao
579 1063 tao
    try
580
    {
581 1217 tao
582
      int serverLocation=getServerLocationNumber(accnum);
583
584 1063 tao
      return getDataFileLockGrant(accnum,serverLocation);
585
    }
586
    catch (Exception e)
587
    {
588 1217 tao
589 1063 tao
      throw e;
590
    }
591 1026 tao
  }
592
593 393 jones
  /**
594 1026 tao
   * The method will check if metacat can get data file lock grant
595
   * If server code is 1, it get.
596
   * If server code is not 1 but call replication getlock successfully,
597
   * it get
598
   * else, it didn't get
599
   * @param accnum, the ID of the document
600
   * @param action, the action to the document
601
   * @param serverCode, the server location code
602
   */
603
  public static boolean getDataFileLockGrant(String accnum, int serverCode)
604
                                          throws Exception
605
  {
606
    boolean flag=true;
607 1217 tao
    //MetaCatUtil util = new MetaCatUtil();
608
    String docid = MetaCatUtil.getDocIdFromString(accnum);
609
    int rev = MetaCatUtil.getVersionFromString(accnum);
610 1026 tao
611
    if (serverCode == 1)
612
    {
613
      flag=true;
614
      return flag;
615
    }
616
617
    //if((serverCode != 1 && action.equals("UPDATE")) )
618
    if (serverCode != 1)
619
    { //if this document being written is not a resident of this server then
620
      //we need to try to get a lock from it's resident server.  If the
621
      //resident server will not give a lock then we send the user a message
622
      //saying that he/she needs to download a new copy of the file and
623
      //merge the differences manually.
624
625 1292 tao
      String server=MetacatReplication.getServerNameForServerCode(serverCode);
626 1026 tao
      MetacatReplication.replLog("attempting to lock " + accnum);
627 1217 tao
      URL u = new URL("https://" + server + "?server=" +
628
        MetaCatUtil.getLocalReplicationServerName()+"&action=getlock&updaterev="
629 1026 tao
           +rev + "&docid=" + docid);
630
      //System.out.println("sending message: " + u.toString());
631
      String serverResStr = MetacatReplication.getURLContent(u);
632
      String openingtag =serverResStr.substring(0, serverResStr.indexOf(">")+1);
633
      if(openingtag.equals("<lockgranted>"))
634
      {
635
        //the lock was granted go ahead with the insert
636
        //System.out.println("In lockgranted");
637
        MetacatReplication.replLog("lock granted for " + accnum + " from " +
638
                                      server);
639
        flag=true;
640
        return flag;
641
      }//if
642
643
      else if(openingtag.equals("<filelocked>"))
644
      {//the file is currently locked by another user
645
       //notify our user to wait a few minutes, check out a new copy and try
646
       //again.
647
        //System.out.println("file locked");
648
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
649
                                   server + " reason: file already locked");
650
        throw new Exception("The file specified is already locked by another " +
651
                            "user.  Please wait 30 seconds, checkout the " +
652
                            "newer document, merge your changes and try " +
653
                            "again.");
654
      }
655
      else if(openingtag.equals("<outdatedfile>"))
656
      {//our file is outdated.  notify our user to check out a new copy of the
657
       //file and merge his version with the new version.
658
        //System.out.println("outdated file");
659
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
660
                                    server + " reason: local file outdated");
661
        throw new Exception("The file you are trying to update is an outdated" +
662
                            " version.  Please checkout the newest document, " +
663
                            "merge your changes and try again.");
664
      }//else if
665
    }//if
666
667
   return flag;
668
669
  }//getDataFileLockGrant
670
671
  /**
672 393 jones
   * get the document name
673
   */
674
  public String getDocname() {
675
    return docname;
676
  }
677
678
  /**
679
   * get the document type (which is the PublicID)
680
   */
681
  public String getDoctype() {
682
    return doctype;
683
  }
684
685
  /**
686
   * get the system identifier
687
   */
688
  public String getSystemID() {
689
    return system_id;
690
  }
691
692
  /**
693
   * get the root node identifier
694
   */
695
  public long getRootNodeID() {
696
    return rootnodeid;
697
  }
698 465 berkley
699
  /**
700
   * get the creation date
701
   */
702
  public String getCreateDate() {
703
    return createdate;
704
  }
705
706
  /**
707
   * get the update date
708
   */
709
  public String getUpdateDate() {
710
    return updatedate;
711
  }
712 393 jones
713 396 jones
  /**
714
   * Get the document identifier (docid)
715
   */
716
  public String getDocID() {
717
    return docid;
718
  }
719 465 berkley
720 691 bojilova
// DOCTITLE attr cleared from the db
721
//  /**
722
//   *get the document title
723
//   */
724
//  public String getDocTitle() {
725
//    return doctitle;
726
//  }
727 561 berkley
728
  public String getUserowner() {
729
    return userowner;
730
  }
731
732
  public String getUserupdated() {
733
    return userupdated;
734
  }
735
736
  public int getServerlocation() {
737
    return serverlocation;
738
  }
739
740 1059 tao
  public String getDocHomeServer() {
741
    return docHomeServer;
742 1055 tao
  }
743 1059 tao
744 1055 tao
745 1059 tao
746 697 bojilova
  public String getPublicaccess() {
747 561 berkley
    return publicaccess;
748
  }
749 575 berkley
750
  public int getRev() {
751
    return rev;
752
  }
753 956 tao
754
   /**
755 429 jones
   * Print a string representation of the XML document
756 393 jones
   */
757 1432 tao
  public String toString(String user, String[] groups)
758 393 jones
  {
759 429 jones
    StringWriter docwriter = new StringWriter();
760 800 jones
    try {
761 1432 tao
      this.toXml(docwriter, user, groups);
762 800 jones
    } catch (McdbException mcdbe) {
763
      return null;
764
    }
765 429 jones
    String document = docwriter.toString();
766
    return document;
767
  }
768
769
  /**
770
   * Get a text representation of the XML document as a string
771
   * This older algorithm uses a recursive tree of Objects to represent the
772
   * nodes of the tree.  Each object is passed the data for the document
773
   * and searches all of the document data to find its children nodes and
774
   * recursively build.  Thus, because each node reads the whole document,
775
   * this algorithm is extremely slow for larger documents, and the time
776
   * to completion is O(N^N) wrt the number of nodes.  See toXml() for a
777
   * better algorithm.
778
   */
779 800 jones
  public String readUsingSlowAlgorithm() throws McdbException
780 429 jones
  {
781 393 jones
    StringBuffer doc = new StringBuffer();
782
783 800 jones
    // First, check that we have the needed node data, and get it if not
784
    if (nodeRecordList == null) {
785
      nodeRecordList = getNodeRecordList(rootnodeid);
786
    }
787
788 429 jones
    // Create the elements from the downloaded data in the TreeSet
789
    rootNode = new ElementNode(nodeRecordList, rootnodeid);
790
791 393 jones
    // Append the resulting document to the StringBuffer and return it
792
    doc.append("<?xml version=\"1.0\"?>\n");
793
794
    if (docname != null) {
795
      if ((doctype != null) && (system_id != null)) {
796
        doc.append("<!DOCTYPE " + docname + " PUBLIC \"" + doctype +
797
                   "\" \"" + system_id + "\">\n");
798
      } else {
799
        doc.append("<!DOCTYPE " + docname + ">\n");
800
      }
801
    }
802
    doc.append(rootNode.toString());
803
804
    return (doc.toString());
805
  }
806
807
  /**
808 429 jones
   * Print a text representation of the XML document to a Writer
809
   *
810
   * @param pw the Writer to which we print the document
811
   */
812 1432 tao
  public void toXml(Writer pw, String user, String[] groups)
813
                                                          throws McdbException
814 429 jones
  {
815
    PrintWriter out = null;
816
    if (pw instanceof PrintWriter) {
817
      out = (PrintWriter)pw;
818
    } else {
819
      out = new PrintWriter(pw);
820
    }
821
822
    MetaCatUtil util = new MetaCatUtil();
823
824 1432 tao
    // Here add code to handle subtree access control
825
    PermissionController control = new PermissionController(docid);
826
    Hashtable unaccessableSubTree =control.hasUnaccessableSubTree(user, groups,
827
                                             AccessControlInterface.READSTRING);
828
829
    if (!unaccessableSubTree.isEmpty())
830
    {
831
       Enumeration en = unaccessableSubTree.elements();
832
       while (en.hasMoreElements())
833
       {
834
         SubTree tree = (SubTree)en.nextElement();
835
         //System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
836
         //System.out.println("subtree id pull out: "+tree.getSubTreeId());
837
         //System.out.println("start node id: "+tree.getStartNodeId());
838
         //System.out.println("end node id: "+tree.getEndNodeId());
839
       }
840
    }
841
842 800 jones
    // First, check that we have the needed node data, and get it if not
843 1432 tao
    if (nodeRecordList == null)
844
    {
845 800 jones
      nodeRecordList = getNodeRecordList(rootnodeid);
846
    }
847
848 429 jones
    Stack openElements = new Stack();
849
    boolean atRootElement = true;
850
    boolean previousNodeWasElement = false;
851
852
    // Step through all of the node records we were given
853
    Iterator it = nodeRecordList.iterator();
854
    while (it.hasNext()) {
855
      NodeRecord currentNode = (NodeRecord)it.next();
856
      //util.debugMessage("[Got Node ID: " + currentNode.nodeid +
857
                          //" (" + currentNode.parentnodeid +
858
                          //", " + currentNode.nodeindex +
859
                          //", " + currentNode.nodetype +
860
                          //", " + currentNode.nodename +
861
                          //", " + currentNode.nodedata + ")]");
862
      // Print the end tag for the previous node if needed
863
      //
864
      // This is determined by inspecting the parent nodeid for the
865
      // currentNode.  If it is the same as the nodeid of the last element
866
      // that was pushed onto the stack, then we are still in that previous
867
      // parent element, and we do nothing.  However, if it differs, then we
868
      // have returned to a level above the previous parent, so we go into
869
      // a loop and pop off nodes and print out their end tags until we get
870
      // the node on the stack to match the currentNode parentnodeid
871
      //
872
      // So, this of course means that we rely on the list of elements
873
      // having been sorted in a depth first traversal of the nodes, which
874
      // is handled by the NodeComparator class used by the TreeSet
875
      if (!atRootElement) {
876
        NodeRecord currentElement = (NodeRecord)openElements.peek();
877
        if ( currentNode.parentnodeid != currentElement.nodeid ) {
878
          while ( currentNode.parentnodeid != currentElement.nodeid ) {
879
            currentElement = (NodeRecord)openElements.pop();
880 1427 tao
            util.debugMessage("\n POPPED: " + currentElement.nodename, 50);
881 451 bojilova
            if (previousNodeWasElement) {
882
              out.print(">");
883
              previousNodeWasElement = false;
884
            }
885 826 bojilova
            if ( currentElement.nodeprefix != null ) {
886
              out.print("</" + currentElement.nodeprefix + ":" +
887
                        currentElement.nodename + ">" );
888
            } else {
889
              out.print("</" + currentElement.nodename + ">" );
890
            }
891 429 jones
            currentElement = (NodeRecord)openElements.peek();
892
          }
893
        }
894
      }
895
896
      // Handle the DOCUMENT node
897
      if (currentNode.nodetype.equals("DOCUMENT")) {
898
        out.println("<?xml version=\"1.0\"?>");
899
900
        if (docname != null) {
901
          if ((doctype != null) && (system_id != null)) {
902
            out.println("<!DOCTYPE " + docname + " PUBLIC \"" + doctype +
903
                       "\" \"" + system_id + "\">");
904
          } else {
905
            out.println("<!DOCTYPE " + docname + ">");
906
          }
907
        }
908
909
      // Handle the ELEMENT nodes
910
      } else if (currentNode.nodetype.equals("ELEMENT")) {
911
        if (atRootElement) {
912
          atRootElement = false;
913
        } else {
914
          if (previousNodeWasElement) {
915
            out.print(">");
916
          }
917
        }
918
        openElements.push(currentNode);
919 1427 tao
        util.debugMessage("\n PUSHED: " + currentNode.nodename, 50);
920 429 jones
        previousNodeWasElement = true;
921 826 bojilova
        if ( currentNode.nodeprefix != null ) {
922
          out.print("<" + currentNode.nodeprefix + ":" + currentNode.nodename);
923
        } else {
924
          out.print("<" + currentNode.nodename);
925
        }
926 429 jones
927
      // Handle the ATTRIBUTE nodes
928
      } else if (currentNode.nodetype.equals("ATTRIBUTE")) {
929 826 bojilova
        if ( currentNode.nodeprefix != null ) {
930
          out.print(" " + currentNode.nodeprefix + ":" + currentNode.nodename +
931
                    "=\"" + currentNode.nodedata + "\"");
932
        } else {
933
          out.print(" " + currentNode.nodename + "=\"" +
934
                    currentNode.nodedata + "\"");
935
        }
936 821 bojilova
937
      // Handle the NAMESPACE nodes
938
      } else if (currentNode.nodetype.equals("NAMESPACE")) {
939
        out.print(" xmlns:" + currentNode.nodename + "=\""
940
                 + currentNode.nodedata + "\"");
941
942
      // Handle the TEXT nodes
943 429 jones
      } else if (currentNode.nodetype.equals("TEXT")) {
944
        if (previousNodeWasElement) {
945
          out.print(">");
946
        }
947
        out.print(currentNode.nodedata);
948
        previousNodeWasElement = false;
949
950
      // Handle the COMMENT nodes
951
      } else if (currentNode.nodetype.equals("COMMENT")) {
952
        if (previousNodeWasElement) {
953
          out.print(">");
954
        }
955
        out.print("<!--" + currentNode.nodedata + "-->");
956
        previousNodeWasElement = false;
957
958
      // Handle the PI nodes
959
      } else if (currentNode.nodetype.equals("PI")) {
960
        if (previousNodeWasElement) {
961
          out.print(">");
962
        }
963
        out.print("<?" + currentNode.nodename + " " +
964
                        currentNode.nodedata + "?>");
965
        previousNodeWasElement = false;
966
967
      // Handle any other node type (do nothing)
968
      } else {
969
        // Any other types of nodes are not handled.
970
        // Probably should throw an exception here to indicate this
971
      }
972
      out.flush();
973
    }
974
975
    // Print the final end tag for the root element
976 686 berkley
    while(!openElements.empty())
977
    {
978
      NodeRecord currentElement = (NodeRecord)openElements.pop();
979 1427 tao
      util.debugMessage("\n POPPED: " + currentElement.nodename, 50);
980 826 bojilova
      if ( currentElement.nodeprefix != null ) {
981
        out.print("</" + currentElement.nodeprefix + ":" +
982
                  currentElement.nodename + ">" );
983
      } else {
984
        out.print("</" + currentElement.nodename + ">" );
985
      }
986 686 berkley
    }
987 429 jones
    out.flush();
988
  }
989 622 berkley
990
  private boolean isRevisionOnly(DocumentIdentifier docid) throws Exception
991
  {
992
    //System.out.println("inRevisionOnly");
993 1217 tao
    DBConnection dbconn = null;
994
    int serialNumber = -1;
995
    PreparedStatement pstmt =null;
996 622 berkley
    String rev = docid.getRev();
997
    String newid = docid.getIdentifier();
998 1217 tao
    try
999
    {
1000
      dbconn=DBConnectionPool.
1001
                    getDBConnection("DocumentImpl.isRevisionOnly");
1002
      serialNumber=dbconn.getCheckOutSerialNumber();
1003
      pstmt = dbconn.prepareStatement("select rev from xml_documents " +
1004 622 berkley
                                  "where docid like '" + newid + "'");
1005 1217 tao
      pstmt.execute();
1006
      ResultSet rs = pstmt.getResultSet();
1007
      boolean tablehasrows = rs.next();
1008
      if(rev.equals("newest") || rev.equals("all"))
1009
      {
1010 622 berkley
        return false;
1011
      }
1012 1217 tao
1013
      if(tablehasrows)
1014
      {
1015
        int r = rs.getInt(1);
1016
        pstmt.close();
1017
        if(new Integer(rev).intValue() == r)
1018
        { //the current revision in in xml_documents
1019
          //System.out.println("returning false");
1020
          return false;
1021
        }
1022
        else if(new Integer(rev).intValue() < r)
1023
        { //the current revision is in xml_revisions.
1024
          //System.out.println("returning true");
1025
          return true;
1026
        }
1027
        else if(new Integer(rev).intValue() > r)
1028
        { //error, rev cannot be greater than r
1029
          throw new Exception("requested revision cannot be greater than " +
1030 622 berkley
                            "the latest revision number.");
1031 1217 tao
        }
1032 622 berkley
      }
1033 1292 tao
      // Get miss docid and rev, throw to McdDocNotFoundException
1034
      String missDocId = MetaCatUtil.getDocIdFromString(docid.toString());
1035
      String missRevision =
1036
                  MetaCatUtil.getRevisionStringFromString(docid.toString());
1037
      throw new McdbDocNotFoundException("the requested docid '" +
1038
                docid.toString() + "' does not exist", missDocId, missRevision);
1039 1217 tao
    }//try
1040
    finally
1041
    {
1042
      pstmt.close();
1043
      DBConnectionPool.returnDBConnection(dbconn, serialNumber);
1044
    }//finally
1045 622 berkley
  }
1046 429 jones
1047 800 jones
  private void getDocumentInfo(String docid) throws McdbException,
1048 1292 tao
                                        AccessionNumberException, Exception
1049 622 berkley
  {
1050
    getDocumentInfo(new DocumentIdentifier(docid));
1051
  }
1052
1053 429 jones
  /**
1054 393 jones
   * Look up the document type information from the database
1055
   *
1056
   * @param docid the id of the document to look up
1057
   */
1058 1292 tao
  private void getDocumentInfo(DocumentIdentifier docid) throws McdbException
1059
                                                          , Exception
1060 393 jones
  {
1061 1217 tao
    DBConnection dbconn = null;
1062
    int serialNumber = -1;
1063
    PreparedStatement pstmt = null;
1064 622 berkley
    String table = "xml_documents";
1065 1059 tao
1066 622 berkley
    try
1067
    {
1068
      if(isRevisionOnly(docid))
1069
      { //pull the document from xml_revisions instead of from xml_documents;
1070
        table = "xml_revisions";
1071
      }
1072
    }
1073 1292 tao
    // catch a McdbDocNotFoundException throw it
1074
    catch (McdbDocNotFoundException notFound)
1075 622 berkley
    {
1076 1292 tao
      throw notFound;
1077 622 berkley
    }
1078 1292 tao
    catch(Exception e)
1079 622 berkley
    {
1080
1081 1292 tao
      MetaCatUtil.debugMessage("error in DocumentImpl.getDocumentInfo: " +
1082
                          e.getMessage(), 30);
1083
      throw e;
1084 622 berkley
    }
1085
1086 1292 tao
1087
1088 1217 tao
    try
1089
    {
1090
      dbconn=DBConnectionPool.getDBConnection("DocumentImpl.getDocumentInfo");
1091
      serialNumber=dbconn.getCheckOutSerialNumber();
1092 622 berkley
      StringBuffer sql = new StringBuffer();
1093 691 bojilova
// DOCTITLE attr cleared from the db
1094
//      sql.append("SELECT docname, doctype, rootnodeid, doctitle, ");
1095
      sql.append("SELECT docname, doctype, rootnodeid, ");
1096 697 bojilova
      sql.append("date_created, date_updated, user_owner, user_updated, ");
1097
      sql.append("server_location, public_access, rev");
1098
      sql.append(" FROM ").append(table);
1099 622 berkley
      sql.append(" WHERE docid LIKE '").append(docid.getIdentifier());
1100
      sql.append("' and rev like '").append(docid.getRev()).append("'");
1101
      //System.out.println(sql.toString());
1102 393 jones
      pstmt =
1103 1217 tao
        dbconn.prepareStatement(sql.toString());
1104 393 jones
      // Bind the values to the query
1105 622 berkley
      //pstmt.setString(1, docid.getIdentifier());
1106
      //pstmt.setString(2, docid.getRev());
1107 393 jones
1108
      pstmt.execute();
1109
      ResultSet rs = pstmt.getResultSet();
1110
      boolean tableHasRows = rs.next();
1111
      if (tableHasRows) {
1112 561 berkley
        this.docname        = rs.getString(1);
1113
        this.doctype        = rs.getString(2);
1114
        this.rootnodeid     = rs.getLong(3);
1115 691 bojilova
// DOCTITLE attr cleared from the db
1116
//        this.doctitle       = rs.getString(4);
1117 692 bojilova
        this.createdate     = rs.getString(4);
1118
        this.updatedate     = rs.getString(5);
1119
        this.userowner      = rs.getString(6);
1120
        this.userupdated    = rs.getString(7);
1121
        this.serverlocation = rs.getInt(8);
1122 697 bojilova
        this.publicaccess   = rs.getString(9);
1123
        this.rev            = rs.getInt(10);
1124 393 jones
      }
1125 818 berkley
      pstmt.close();
1126 1059 tao
1127
      //get doc  home server name
1128
1129 1217 tao
      pstmt = dbconn.prepareStatement("select server " +
1130 1059 tao
                        "from xml_replication where serverid = ?");
1131 1217 tao
      //because connection use twise here, so we need to increase one
1132
      dbconn.increaseUsageCount(1);
1133 1059 tao
      pstmt.setInt(1, serverlocation);
1134
      pstmt.execute();
1135
      rs = pstmt.getResultSet();
1136
      tableHasRows = rs.next();
1137
      if (tableHasRows)
1138
      {
1139
1140
          String server = rs.getString(1);
1141
          //get homeserver name
1142
          if(!server.equals("localhost"))
1143
          {
1144
            this.docHomeServer=server;
1145
          }
1146
          else
1147
          {
1148
            this.docHomeServer=MetaCatUtil.getLocalReplicationServerName();
1149
          }
1150
          MetaCatUtil.debugMessage("server: "+docHomeServer, 50);
1151
1152
      }
1153
      pstmt.close();
1154 393 jones
      if (this.doctype != null) {
1155
        pstmt =
1156 1217 tao
          dbconn.prepareStatement("SELECT system_id " +
1157 393 jones
                                  "FROM xml_catalog " +
1158 769 bojilova
                                 "WHERE public_id = ?");
1159 1217 tao
        //should increase usage count again
1160
        dbconn.increaseUsageCount(1);
1161 393 jones
        // Bind the values to the query
1162
        pstmt.setString(1, doctype);
1163
1164
        pstmt.execute();
1165
        rs = pstmt.getResultSet();
1166
        tableHasRows = rs.next();
1167
        if (tableHasRows) {
1168
          this.system_id  = rs.getString(1);
1169
        }
1170 818 berkley
        pstmt.close();
1171 393 jones
      }
1172
    } catch (SQLException e) {
1173 675 berkley
      System.out.println("error in DocumentImpl.getDocumentInfo: " +
1174
                          e.getMessage());
1175 622 berkley
      e.printStackTrace(System.out);
1176 675 berkley
      throw new McdbException("Error accessing database connection in " +
1177
                              "DocumentImpl.getDocumentInfo: ", e);
1178 393 jones
    }
1179 1217 tao
    finally
1180
    {
1181
      try
1182
      {
1183
        pstmt.close();
1184
      }
1185
      catch (SQLException ee)
1186
      {
1187
        MetaCatUtil.debugMessage("error in DocumentImple.getDocumentInfo: "
1188
                                    +ee.getMessage(), 30);
1189
      }//catch
1190
      finally
1191
      {
1192
        DBConnectionPool.returnDBConnection(dbconn, serialNumber);
1193
      }
1194
    }
1195 393 jones
1196
    if (this.docname == null) {
1197 1292 tao
      throw new McdbDocNotFoundException("Document not found: " + docid,
1198
                                 docid.getIdentifier(), docid.getRev());
1199 393 jones
    }
1200
  }
1201
1202
  /**
1203
   * Look up the node data from the database
1204
   *
1205 396 jones
   * @param rootnodeid the id of the root node of the node tree to look up
1206 393 jones
   */
1207 1217 tao
  private TreeSet getNodeRecordList(long rootnodeid) throws McdbException
1208 393 jones
  {
1209 1217 tao
    PreparedStatement pstmt = null;
1210
    DBConnection dbconn = null;
1211
    int serialNumber = -1;
1212 393 jones
    TreeSet nodeRecordList = new TreeSet(new NodeComparator());
1213
    long nodeid = 0;
1214
    long parentnodeid = 0;
1215
    long nodeindex = 0;
1216
    String nodetype = null;
1217
    String nodename = null;
1218 826 bojilova
    String nodeprefix = null;
1219 393 jones
    String nodedata = null;
1220 899 berkley
    String quotechar = dbAdapter.getStringDelimiter();
1221 393 jones
1222
    try {
1223 1217 tao
      dbconn=DBConnectionPool.
1224
                    getDBConnection("DocumentImpl.getNodeRecordList");
1225
      serialNumber=dbconn.getCheckOutSerialNumber();
1226 393 jones
      pstmt =
1227 1217 tao
      dbconn.prepareStatement("SELECT nodeid,parentnodeid,nodeindex, " +
1228 899 berkley
           "nodetype,nodename,nodeprefix,nodedata " +
1229 396 jones
           "FROM xml_nodes WHERE rootnodeid = ?");
1230 393 jones
1231
      // Bind the values to the query
1232 396 jones
      pstmt.setLong(1, rootnodeid);
1233 393 jones
1234
      pstmt.execute();
1235
      ResultSet rs = pstmt.getResultSet();
1236
      boolean tableHasRows = rs.next();
1237
      while (tableHasRows) {
1238
        nodeid = rs.getLong(1);
1239
        parentnodeid = rs.getLong(2);
1240
        nodeindex = rs.getLong(3);
1241
        nodetype = rs.getString(4);
1242
        nodename = rs.getString(5);
1243 826 bojilova
        nodeprefix = rs.getString(6);
1244
        nodedata = rs.getString(7);
1245 899 berkley
        nodedata = MetaCatUtil.normalize(nodedata);
1246 393 jones
        // add the data to the node record list hashtable
1247 826 bojilova
        NodeRecord currentRecord = new NodeRecord(nodeid,parentnodeid,nodeindex,
1248 946 tao
                                      nodetype, nodename, nodeprefix, nodedata);
1249 393 jones
        nodeRecordList.add(currentRecord);
1250
1251
        // Advance to the next node
1252
        tableHasRows = rs.next();
1253
      }
1254
      pstmt.close();
1255
1256
    } catch (SQLException e) {
1257 826 bojilova
      throw new McdbException("Error in DocumentImpl.getNodeRecordList " +
1258
                              e.getMessage());
1259 393 jones
    }
1260 1217 tao
    finally
1261
    {
1262
      try
1263
      {
1264
        pstmt.close();
1265
      }
1266
      catch (SQLException ee)
1267
      {
1268
        MetaCatUtil.debugMessage("error in DocumentImpl.getNodeRecordList: "
1269
                                    +ee.getMessage(), 30);
1270
      }
1271
      finally
1272
      {
1273
        DBConnectionPool.returnDBConnection(dbconn, serialNumber);
1274
      }
1275
    }
1276
1277 393 jones
1278
    if (nodeRecordList != null) {
1279
      return nodeRecordList;
1280
    } else {
1281
      throw new McdbException("Error getting node data: " + docid);
1282
    }
1283
  }
1284 549 berkley
1285 697 bojilova
// NOT USED ANY MORE
1286
//  /** creates SQL code and inserts new document into DB connection
1287
//   default serverCode of 1*/
1288
//  private void writeDocumentToDB(String action, String user)
1289
//               throws SQLException, Exception
1290
//  {
1291
//    writeDocumentToDB(action, user, null, 1);
1292
//  }
1293 393 jones
1294 459 bojilova
 /** creates SQL code and inserts new document into DB connection */
1295 680 bojilova
  private void writeDocumentToDB(String action, String user, String pub,
1296 697 bojilova
                                 String catalogid, int serverCode)
1297 459 bojilova
               throws SQLException, Exception {
1298 754 bojilova
    String sysdate = dbAdapter.getDateTimeFunction();
1299 747 bojilova
1300 459 bojilova
    try {
1301
      PreparedStatement pstmt = null;
1302
1303
      if (action.equals("INSERT")) {
1304
        //AccessionNumber ac = new AccessionNumber();
1305
        //this.docid = ac.generate(docid, "INSERT");
1306 1217 tao
1307
        pstmt = connection.prepareStatement(
1308 697 bojilova
                "INSERT INTO xml_documents " +
1309
                "(docid, rootnodeid, docname, doctype, " +
1310
                "user_owner, user_updated, date_created, date_updated, " +
1311 1072 tao
                "public_access, catalog_id, server_location, rev) " +
1312 747 bojilova
                "VALUES (?, ?, ?, ?, ?, ?, " + sysdate + ", " + sysdate +
1313 1072 tao
                ", ?, ?, ?, ?)");
1314 1217 tao
        // Increase dbconnection usage count
1315
        connection.increaseUsageCount(1);
1316
1317 549 berkley
        //note that the server_location is set to 1.
1318
        //this means that "localhost" in the xml_replication table must
1319
        //always be the first entry!!!!!
1320
1321 459 bojilova
        // Bind the values to the query
1322
        pstmt.setString(1, this.docid);
1323
        pstmt.setLong(2, rootnodeid);
1324
        pstmt.setString(3, docname);
1325
        pstmt.setString(4, doctype);
1326
        pstmt.setString(5, user);
1327
        pstmt.setString(6, user);
1328 1069 tao
        //public access is usefulless, so set it to null
1329
        pstmt.setString(7, null);
1330
        /*if ( pub == null ) {
1331 680 bojilova
          pstmt.setString(7, null);
1332 697 bojilova
        } else if ( pub.toUpperCase().equals("YES") || pub.equals("1") ) {
1333 680 bojilova
          pstmt.setInt(7, 1);
1334 697 bojilova
        } else if ( pub.toUpperCase().equals("NO") || pub.equals("0") ) {
1335 680 bojilova
          pstmt.setInt(7, 0);
1336 1069 tao
        }*/
1337 697 bojilova
        pstmt.setString(8, catalogid);
1338
        pstmt.setInt(9, serverCode);
1339 1072 tao
        pstmt.setInt(10, Integer.parseInt(updatedVersion));
1340 459 bojilova
      } else if (action.equals("UPDATE")) {
1341
1342 1072 tao
        // Save the old document publicaccessentry in a backup table
1343 1217 tao
        DocumentImpl.archiveDocRevision(connection, docid, user );
1344 1292 tao
        DocumentImpl thisdoc = new DocumentImpl(docid, false);
1345 575 berkley
        int thisrev = thisdoc.getRev();
1346 956 tao
1347
        //if the updated vesion is not greater than current one,
1348
        //throw it into a exception
1349
        if (Integer.parseInt(updatedVersion)<=thisrev)
1350
        {
1351
          throw new Exception("Next revision number couldn't be less"
1352
                               +" than or equal "+ thisrev);
1353
        }
1354
        else
1355
        {
1356
          //set the user specified revision
1357
          thisrev=Integer.parseInt(updatedVersion);
1358
        }
1359
1360 459 bojilova
        // Delete index for the old version of docid
1361
        // The new index is inserting on the next calls to DBSAXNode
1362 1217 tao
        pstmt = connection.prepareStatement(
1363 459 bojilova
                "DELETE FROM xml_index WHERE docid='" + this.docid + "'");
1364 1217 tao
        // Increase dbconnection usage count
1365
        connection.increaseUsageCount(1);
1366
1367 459 bojilova
        pstmt.execute();
1368 818 berkley
        pstmt.close();
1369 459 bojilova
1370
        // Update the new document to reflect the new node tree
1371 1217 tao
        pstmt = connection.prepareStatement(
1372 459 bojilova
            "UPDATE xml_documents " +
1373
            "SET rootnodeid = ?, docname = ?, doctype = ?, " +
1374 747 bojilova
            "user_updated = ?, date_updated = " + sysdate + ", " +
1375 697 bojilova
            "server_location = ?, rev = ?, public_access = ?, catalog_id = ? " +
1376 769 bojilova
            "WHERE docid = ?");
1377 1217 tao
        // Increase dbconnection usage count
1378
        connection.increaseUsageCount(1);
1379 459 bojilova
        // Bind the values to the query
1380
        pstmt.setLong(1, rootnodeid);
1381
        pstmt.setString(2, docname);
1382
        pstmt.setString(3, doctype);
1383
        pstmt.setString(4, user);
1384 549 berkley
        pstmt.setInt(5, serverCode);
1385 575 berkley
        pstmt.setInt(6, thisrev);
1386 1069 tao
        pstmt.setString(7, null);
1387
        /*if ( pub == null ) {
1388 680 bojilova
          pstmt.setString(7, null);
1389 697 bojilova
        } else if ( pub.toUpperCase().equals("YES") || pub.equals("1") ) {
1390 680 bojilova
          pstmt .setInt(7, 1);
1391 697 bojilova
        } else if ( pub.toUpperCase().equals("NO") || pub.equals("0") ) {
1392 680 bojilova
          pstmt.setInt(7, 0);
1393 1069 tao
        }*/
1394 697 bojilova
        pstmt.setString(8, catalogid);
1395
        pstmt.setString(9, this.docid);
1396 575 berkley
1397 459 bojilova
      } else {
1398
        System.err.println("Action not supported: " + action);
1399
      }
1400
1401
      // Do the insertion
1402
      pstmt.execute();
1403 1217 tao
1404 459 bojilova
      pstmt.close();
1405
1406
    } catch (SQLException sqle) {
1407
      throw sqle;
1408
    } catch (Exception e) {
1409
      throw e;
1410
    }
1411
  }
1412
1413
  /**
1414 407 jones
   * Write an XML file to the database, given a filename
1415 393 jones
   *
1416 408 jones
   * @param conn the JDBC connection to the database
1417 407 jones
   * @param filename the filename to be loaded into the database
1418 680 bojilova
   * @param pub flag for public "read" access on document
1419
   * @param dtdfilename the dtd to be uploaded on server's file system
1420 407 jones
   * @param action the action to be performed (INSERT OR UPDATE)
1421
   * @param docid the docid to use for the INSERT OR UPDATE
1422 680 bojilova
   * @param user the user that owns the document
1423 802 bojilova
   * @param groups the groups to which user belongs
1424 393 jones
   */
1425 1383 tao
  /*public static String write(DBConnection conn,String filename,
1426 680 bojilova
                             String pub, String dtdfilename,
1427 598 bojilova
                             String action, String docid, String user,
1428 802 bojilova
                             String[] groups )
1429 457 bojilova
                throws Exception {
1430 598 bojilova
1431
    Reader dtd = null;
1432
    if ( dtdfilename != null ) {
1433
      dtd = new FileReader(new File(dtdfilename).toString());
1434
    }
1435 555 bojilova
    return write ( conn, new FileReader(new File(filename).toString()),
1436 802 bojilova
                   pub, dtd, action, docid, user, groups, false);
1437 1383 tao
  }*/
1438 598 bojilova
1439 1217 tao
  public static String write(DBConnection conn,Reader xml,String pub,Reader dtd,
1440 598 bojilova
                             String action, String docid, String user,
1441 1383 tao
                             String[] groups, String ruleBase,
1442
                             boolean needValidation)
1443 549 berkley
                throws Exception {
1444 1012 tao
    //this method will be called in handleUpdateOrInsert method
1445 1383 tao
    //in MetacatServlet class and now is wrapper into documentImple
1446 1012 tao
    // get server location for this doc
1447 1217 tao
    int serverLocation=getServerLocationNumber(docid);
1448 1012 tao
    return write(conn,xml,pub,dtd,action,docid,user,groups,serverLocation,false,
1449 1383 tao
                 ruleBase, needValidation);
1450 598 bojilova
  }
1451
1452 1383 tao
1453 549 berkley
1454 407 jones
  /**
1455
   * Write an XML file to the database, given a Reader
1456
   *
1457 408 jones
   * @param conn the JDBC connection to the database
1458 407 jones
   * @param xml the xml stream to be loaded into the database
1459 680 bojilova
   * @param pub flag for public "read" access on xml document
1460
   * @param dtd the dtd to be uploaded on server's file system
1461 734 bojilova
   * @param action the action to be performed (INSERT or UPDATE)
1462
   * @param accnum the docid + rev# to use on INSERT or UPDATE
1463 580 berkley
   * @param user the user that owns the document
1464 802 bojilova
   * @param groups the groups to which user belongs
1465 580 berkley
   * @param serverCode the serverid from xml_replication on which this document
1466
   *        resides.
1467
   * @param override flag to stop insert replication checking.
1468
   *        if override = true then a document not belonging to the local server
1469
   *        will not be checked upon update for a file lock.
1470
   *        if override = false then a document not from this server, upon
1471
   *        update will be locked and version checked.
1472 407 jones
   */
1473 559 berkley
1474 1217 tao
  public static String write(DBConnection conn, Reader xml,String pub,
1475
                         Reader dtd, String action, String accnum, String user,
1476
                         String[] groups, int serverCode, boolean override,
1477 1383 tao
                         String ruleBase, boolean needValidation)
1478 598 bojilova
                throws Exception
1479 573 berkley
  {
1480 779 bojilova
    // NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
1481 1217 tao
    //MetaCatUtil util = new MetaCatUtil();
1482
    MetaCatUtil.debugMessage("conn usage count before writting: "
1483
                                      +conn.getUsageCount(), 50);
1484
    AccessionNumber ac = new AccessionNumber(accnum, action);
1485 779 bojilova
    String docid = ac.getDocid();
1486
    String rev = ac.getRev();
1487 590 berkley
    MetaCatUtil.debugMessage("action: " + action + " servercode: " +
1488 1055 tao
                             serverCode + " override: " + override, 10);
1489 1383 tao
1490 577 berkley
    if((serverCode != 1 && action.equals("UPDATE")) && !override)
1491 559 berkley
    { //if this document being written is not a resident of this server then
1492
      //we need to try to get a lock from it's resident server.  If the
1493
      //resident server will not give a lock then we send the user a message
1494
      //saying that he/she needs to download a new copy of the file and
1495
      //merge the differences manually.
1496 567 berkley
      int istreamInt;
1497 561 berkley
      char istreamChar;
1498 1081 tao
1499
      // check for 'write' permission for 'user' to update this document
1500 1427 tao
      if ( !hasWritePermission(user, groups, docid) ) {
1501 1081 tao
        throw new Exception("User " + user +
1502
              " does not have permission to update XML Document #" + accnum);
1503
      }
1504
1505 779 bojilova
      DocumentIdentifier id = new DocumentIdentifier(accnum);
1506
      String updaterev = id.getRev();
1507 1292 tao
      String server=MetacatReplication.getServerNameForServerCode(serverCode);
1508 734 bojilova
      MetacatReplication.replLog("attempting to lock " + accnum);
1509 1217 tao
      URL u = new URL("https://" + server + "?server="+
1510
        MetaCatUtil.getLocalReplicationServerName()+"&action=getlock&updaterev="
1511 1012 tao
           +updaterev + "&docid=" + docid);
1512
      //System.out.println("sending message: " + u.toString());
1513 569 berkley
      String serverResStr = MetacatReplication.getURLContent(u);
1514 946 tao
      String openingtag =serverResStr.substring(0, serverResStr.indexOf(">")+1);
1515 561 berkley
      if(openingtag.equals("<lockgranted>"))
1516
      {//the lock was granted go ahead with the insert
1517 571 berkley
        try
1518
        {
1519 1012 tao
          //System.out.println("In lockgranted");
1520 734 bojilova
          MetacatReplication.replLog("lock granted for " + accnum + " from " +
1521 584 berkley
                                      server);
1522 1383 tao
          /*XMLReader parser = initializeParser(conn, action, docid, updaterev,
1523
                               validate, user, groups, pub, serverCode, dtd);*/
1524 956 tao
          XMLReader parser = initializeParser(conn, action, docid, updaterev,
1525 1383 tao
                                        user, groups, pub, serverCode,
1526
                                        dtd,ruleBase, needValidation);
1527 571 berkley
          conn.setAutoCommit(false);
1528 695 bojilova
          parser.parse(new InputSource(xml));
1529 571 berkley
          conn.commit();
1530
          conn.setAutoCommit(true);
1531
        }
1532
        catch (Exception e)
1533
        {
1534
          conn.rollback();
1535
          conn.setAutoCommit(true);
1536
          throw e;
1537
        }
1538
1539 590 berkley
1540 1039 tao
1541 1292 tao
        // Force replication the docid
1542
        ForceReplicationHandler frh = new ForceReplicationHandler
1543
                                                          (accnum, true, null);
1544
        return(accnum);
1545
1546 561 berkley
      }
1547 734 bojilova
1548 561 berkley
      else if(openingtag.equals("<filelocked>"))
1549
      {//the file is currently locked by another user
1550
       //notify our user to wait a few minutes, check out a new copy and try
1551
       //again.
1552 584 berkley
        //System.out.println("file locked");
1553 734 bojilova
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
1554 584 berkley
                                   server + " reason: file already locked");
1555 571 berkley
        throw new Exception("The file specified is already locked by another " +
1556
                            "user.  Please wait 30 seconds, checkout the " +
1557
                            "newer document, merge your changes and try " +
1558
                            "again.");
1559 561 berkley
      }
1560
      else if(openingtag.equals("<outdatedfile>"))
1561
      {//our file is outdated.  notify our user to check out a new copy of the
1562
       //file and merge his version with the new version.
1563 584 berkley
        //System.out.println("outdated file");
1564 734 bojilova
        MetacatReplication.replLog("lock denied for " + accnum + " on " +
1565 584 berkley
                                    server + " reason: local file outdated");
1566 571 berkley
        throw new Exception("The file you are trying to update is an outdated" +
1567
                            " version.  Please checkout the newest document, " +
1568
                            "merge your changes and try again.");
1569 561 berkley
      }
1570 559 berkley
    }
1571 571 berkley
1572 425 bojilova
    if ( action.equals("UPDATE") ) {
1573 441 bojilova
      // check for 'write' permission for 'user' to update this document
1574 628 berkley
1575 1427 tao
      if ( !hasWritePermission(user, groups, docid) ) {
1576 441 bojilova
        throw new Exception("User " + user +
1577 734 bojilova
              " does not have permission to update XML Document #" + accnum);
1578 425 bojilova
      }
1579
    }
1580
1581 571 berkley
    try
1582 638 bojilova
    {
1583 956 tao
1584 1383 tao
      XMLReader parser = initializeParser(conn, action, docid, rev,
1585
                                          user, groups, pub, serverCode,
1586
                                          dtd, ruleBase, needValidation);
1587 1217 tao
1588 555 bojilova
      conn.setAutoCommit(false);
1589
      parser.parse(new InputSource(xml));
1590
      conn.commit();
1591
      conn.setAutoCommit(true);
1592 571 berkley
    }
1593
    catch (Exception e)
1594
    {
1595 555 bojilova
      conn.rollback();
1596
      conn.setAutoCommit(true);
1597
      throw e;
1598
    }
1599 577 berkley
1600 1292 tao
    // Force replicate out the new document to each server in our server list.
1601
    // Start the thread to replicate this new document out to the other servers
1602
    // true mean it is xml document
1603
    // null is because no metacat notify the force replication.
1604
    ForceReplicationHandler frh = new ForceReplicationHandler
1605
                                                  (accnum, action, true, null);
1606 1012 tao
1607 1292 tao
1608 1217 tao
    MetaCatUtil.debugMessage("Conn Usage count after writting: "
1609
                                                      +conn.getUsageCount(),50);
1610 779 bojilova
    return(accnum);
1611 393 jones
  }
1612 396 jones
1613 407 jones
  /**
1614 1055 tao
   * Write an XML file to the database during replication
1615
   *
1616
   * @param conn the JDBC connection to the database
1617
   * @param xml the xml stream to be loaded into the database
1618
   * @param pub flag for public "read" access on xml document
1619
   * @param dtd the dtd to be uploaded on server's file system
1620
   * @param action the action to be performed (INSERT or UPDATE)
1621
   * @param accnum the docid + rev# to use on INSERT or UPDATE
1622
   * @param user the user that owns the document
1623
   * @param groups the groups to which user belongs
1624
   * @param homeServer the name of server which the document origanlly create
1625
   * @param validate, if the xml document is valid or not
1626 1292 tao
   * @param notifyServer, the server which notify local server the force
1627
   *                       replication command
1628 1055 tao
   */
1629
1630 1217 tao
  public static String writeReplication(DBConnection conn, Reader xml,
1631 1383 tao
                                        String pub, Reader dtd, String action,
1632
                                        String accnum, String user,
1633
                                        String[] groups,String homeServer,
1634
                                        String notifyServer,
1635
                                        String ruleBase, boolean needValidation)
1636
                                        throws Exception
1637 1055 tao
  {
1638 1292 tao
    // Docid without revision
1639
    String docid=MetaCatUtil.getDocIdFromString(accnum);
1640
    // Revision specified by user (int)
1641
    int userSpecifyRev=MetaCatUtil.getVersionFromString(accnum);
1642
    // Revision for this docid in current database
1643
    int revInDataBase=getLatestRevisionNumber(docid);
1644
    // String to store the revision
1645
    String rev = null;
1646 1217 tao
1647 1069 tao
1648 1292 tao
    //revIndataBase=-1, there is no record in xml_documents table
1649
    //the document is a new one for local server, inert it into table
1650
    //user specified rev should be great than 0
1651
    if (revInDataBase==-1 && userSpecifyRev>0 )
1652 1069 tao
    {
1653 1292 tao
        // rev equals user specified
1654
        rev=(new Integer(userSpecifyRev)).toString();
1655
        // action should be INSERT
1656
        action = "INSERT";
1657 1069 tao
    }
1658 1292 tao
    //rev is greater the last revsion number and revInDataBase isn't -1
1659
    // it is a updated  file
1660
    else if (userSpecifyRev>revInDataBase && revInDataBase>0)
1661 1055 tao
    {
1662 1292 tao
       // rev equals user specified
1663
       rev=(new Integer(userSpecifyRev)).toString();
1664
       // action should be update
1665
       action = "UPDATE";
1666 1055 tao
    }
1667 1292 tao
    // local server has newer version, then notify the remote server
1668
    else if ( userSpecifyRev < revInDataBase && revInDataBase > 0)
1669
    {
1670
      throw new Exception("Local server: "+MetaCatUtil.getOption("server")+
1671
                " has newer revision of doc: "+docid+"."+revInDataBase
1672
                 +". Please notify it.");
1673
    }
1674
    //other situation
1675
    else
1676
    {
1677
1678
        throw new Exception("The docid"+docid+"'s revision number couldn't be "
1679
                    +userSpecifyRev);
1680
    }
1681
    // Variable to store homeserver code
1682
    int serverCode=-2;
1683
1684
     // If server is not int the xml replication talbe, insert it into
1685
    // xml_replication table
1686
    //serverList.addToServerListIfItIsNot(homeServer);
1687
    insertServerIntoReplicationTable(homeServer);
1688
    // Get server code again
1689
    serverCode = getServerCode(homeServer);
1690
1691
1692
    MetaCatUtil.debugMessage("Document "+docid+"."+rev+" "+action+ " into local"
1693
                               +" metacat with servercode: "+ serverCode, 10);
1694 1055 tao
1695 1217 tao
1696 1292 tao
    // insert into xml_nodes and xml_index table
1697 1055 tao
    try
1698
    {
1699
1700 1383 tao
      XMLReader parser = initializeParser(conn, action, docid, rev,
1701
                                          user, groups, pub, serverCode, dtd,
1702
                                          ruleBase, needValidation);
1703 1055 tao
      conn.setAutoCommit(false);
1704
      parser.parse(new InputSource(xml));
1705
      conn.commit();
1706
      conn.setAutoCommit(true);
1707
    }
1708
    catch (Exception e)
1709
    {
1710
      conn.rollback();
1711
      conn.setAutoCommit(true);
1712
      throw e;
1713
    }
1714 1292 tao
1715
    //Force replication to other server
1716
    ForceReplicationHandler forceReplication = new ForceReplicationHandler
1717
                                  (accnum, action, true, notifyServer);
1718
1719 1055 tao
1720
    return(accnum);
1721
  }
1722
1723
1724
  /**
1725 407 jones
   * Delete an XML file from the database (actually, just make it a revision
1726
   * in the xml_revisions table)
1727
   *
1728
   * @param docid the ID of the document to be deleted from the database
1729
   */
1730 1217 tao
  public static void delete(String accnum,
1731 802 bojilova
                                 String user, String[] groups )
1732 734 bojilova
                throws Exception
1733
  {
1734 779 bojilova
    // OLD
1735
    //DocumentIdentifier id = new DocumentIdentifier(accnum);
1736
    //String docid = id.getIdentifier();
1737
    //String rev = id.getRev();
1738 628 berkley
1739 779 bojilova
    // OLD
1740 734 bojilova
    // Determine if the docid,rev are OK for DELETE
1741 779 bojilova
    //AccessionNumber ac = new AccessionNumber(conn);
1742
    //docid = ac.generate(docid, rev, "DELETE");
1743 1217 tao
    DBConnection conn = null;
1744
    int serialNumber = -1;
1745
    PreparedStatement pstmt =null;
1746
    try
1747
    {
1748
      //check out DBConnection
1749
      conn=DBConnectionPool.
1750
                    getDBConnection("DocumentImpl.delete");
1751
      serialNumber=conn.getCheckOutSerialNumber();
1752 396 jones
1753 1217 tao
      // NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
1754
      AccessionNumber ac = new AccessionNumber(accnum, "DELETE");
1755
      String docid = ac.getDocid();
1756
      String rev = ac.getRev();
1757 779 bojilova
1758
1759 441 bojilova
    // check for 'write' permission for 'user' to delete this document
1760 1427 tao
      if ( !hasWritePermission(user, groups, docid) ) {
1761 1217 tao
        throw new Exception("User " + user +
1762 734 bojilova
              " does not have permission to delete XML Document #" + accnum);
1763 1217 tao
      }
1764 425 bojilova
1765 1217 tao
      conn.setAutoCommit(false);
1766
      // Copy the record to the xml_revisions table
1767
      DocumentImpl.archiveDocRevision(conn, docid, user );
1768 396 jones
1769 1217 tao
      // Now delete it from the xml_index table
1770
      pstmt = conn.prepareStatement("DELETE FROM xml_index WHERE docid = ?");
1771
      pstmt.setString(1,docid);
1772
      pstmt.execute();
1773
      pstmt.close();
1774
      conn.increaseUsageCount(1);
1775
1776
      //stmt.execute("DELETE FROM xml_access WHERE docid = '" + docid + "'");
1777
      // Now delete it from xml_access table
1778
      pstmt = conn.
1779
              prepareStatement("DELETE FROM xml_access WHERE accessfileid = ?");
1780
      pstmt.setString(1, docid);
1781
      pstmt.execute();
1782
      pstmt.close();
1783
      conn.increaseUsageCount(1);
1784
1785
      // Delete it from relation table
1786
      pstmt = conn.
1787
               prepareStatement("DELETE FROM xml_relation WHERE docid = ?");
1788
      //increase usage count
1789
      conn.increaseUsageCount(1);
1790
      pstmt.setString(1, docid);
1791
      pstmt.execute();
1792
      pstmt.close();
1793
1794
      // Delete it from xml_doucments table
1795
      pstmt =conn.prepareStatement("DELETE FROM xml_documents WHERE docid = ?");
1796
      pstmt.setString(1, docid);
1797
      pstmt.execute();
1798
      pstmt.close();
1799
      //Usaga count increase 1
1800
      conn.increaseUsageCount(1);
1801
1802
      conn.commit();
1803
      conn.setAutoCommit(true);
1804
    }//try
1805
    finally
1806
    {
1807
1808
      try
1809
      {
1810
        // close preparedStatement
1811
        pstmt.close();
1812
      }//try
1813
      finally
1814
      {
1815
        //check in DBonnection
1816
        DBConnectionPool.returnDBConnection(conn, serialNumber);
1817
      }//finally
1818
    }//finally
1819 634 berkley
    //IF this is a package document:
1820
    //delete all of the relations that this document created.
1821
    //if the deleted document is a package document its relations should
1822
    //no longer be active if it has been deleted from the system.
1823 645 bojilova
1824 407 jones
  }
1825 638 bojilova
1826 570 bojilova
  /**
1827 802 bojilova
    * Check for "WRITE" permission on @docid for @user and/or @groups
1828 570 bojilova
    * from DB connection
1829
    */
1830 1427 tao
  private static boolean hasWritePermission (String user,
1831 802 bojilova
                                  String[] groups, String docid )
1832 958 tao
                  throws SQLException, Exception
1833 570 bojilova
  {
1834 802 bojilova
    // Check for WRITE permission on @docid for @user and/or @groups
1835 1427 tao
    PermissionController controller = new PermissionController(docid);
1836
    return controller.hasPermission(user,groups,
1837
                                    AccessControlInterface.WRITESTRING);
1838 425 bojilova
  }
1839
1840 946 tao
  /**
1841
    * Check for "READ" permission base on docid, user and group
1842
    *@docid, the document
1843
    *@user, user name
1844
    *@group, user's group
1845
    *
1846
    */
1847 1217 tao
  public static boolean hasReadPermission (String user,
1848 946 tao
                                  String[] groups, String docId )
1849 958 tao
                  throws SQLException, Exception
1850 946 tao
  {
1851
    // Check for READ permission on @docid for @user and/or @groups
1852 1427 tao
    PermissionController controller =
1853
                        new PermissionController(docId);
1854
    return controller.hasPermission(user,groups,
1855
                                            AccessControlInterface.READSTRING);
1856 946 tao
  }
1857
1858 1383 tao
1859
   /**
1860
   * Set up the parser handlers for writing the document to the database
1861
   */
1862
  private static XMLReader initializeParser(DBConnection dbconn, String action,
1863
                                            String docid, String rev,
1864
                                            String user,
1865
                                            String[] groups, String pub,
1866
                                            int serverCode, Reader dtd,
1867
                                            String ruleBase,
1868
                                            boolean needValidation)
1869
                                            throws Exception
1870
  {
1871
    XMLReader parser = null;
1872
    try
1873
    {
1874 1407 tao
      // handler
1875
      ContentHandler chandler;
1876 1383 tao
      EntityResolver eresolver;
1877
      DTDHandler dtdhandler;
1878
      // Get an instance of the parser
1879
      String parserName = MetaCatUtil.getOption("saxparser");
1880
      parser = XMLReaderFactory.createXMLReader(parserName);
1881 1407 tao
      if (ruleBase != null && ruleBase.equals(EML2))
1882 1383 tao
      {
1883 1407 tao
        MetaCatUtil.debugMessage("eml 2 parser", 20);
1884
        chandler = new EmlSAXHandler(dbconn, action,
1885
                                    docid, rev, user, groups, pub, serverCode);
1886
        parser.setContentHandler((ContentHandler)chandler);
1887
        parser.setErrorHandler((ErrorHandler)chandler);
1888
        parser.setProperty(DECLARATIONHANDLERPROPERTY, chandler);
1889
        parser.setProperty(LEXICALPROPERTY, chandler);
1890 1383 tao
        // turn on schema validation feature
1891
        parser.setFeature(VALIDATIONFEATURE, true);
1892
        parser.setFeature(NAMESPACEFEATURE, true);
1893 1431 tao
        //parser.setFeature(NAMESPACEPREFIXESFEATURE, true);
1894 1383 tao
        parser.setFeature(SCHEMAVALIDATIONFEATURE, true);
1895 1396 tao
        // From DB to find the register external schema location
1896
        String externalSchemaLocation = null;
1897
        SchemaLocationResolver resolver = new SchemaLocationResolver();
1898
        externalSchemaLocation = resolver.getNameSpaceAndLocationString();
1899
        // Set external schemalocation.
1900
        if (externalSchemaLocation != null &&
1901
            !(externalSchemaLocation.trim()).equals(""))
1902
        {
1903 1407 tao
            parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
1904 1396 tao
                             externalSchemaLocation);
1905
        }
1906 1383 tao
      }
1907
      else
1908
      {
1909 1407 tao
        //create a DBSAXHandler object which has the revision specification
1910
        chandler = new DBSAXHandler(dbconn, action,
1911
                                    docid, rev, user, groups, pub, serverCode);
1912
        parser.setContentHandler((ContentHandler)chandler);
1913
        parser.setErrorHandler((ErrorHandler)chandler);
1914
        parser.setProperty(DECLARATIONHANDLERPROPERTY, chandler);
1915
        parser.setProperty(LEXICALPROPERTY, chandler);
1916
1917
        if (ruleBase != null && ruleBase.equals(SCHEMA) && needValidation)
1918
        {
1919
          MetaCatUtil.debugMessage("General schema parser", 20);
1920
          // turn on schema validation feature
1921
          parser.setFeature(VALIDATIONFEATURE, true);
1922
          parser.setFeature(NAMESPACEFEATURE, true);
1923 1431 tao
          //parser.setFeature(NAMESPACEPREFIXESFEATURE, true);
1924 1407 tao
          parser.setFeature(SCHEMAVALIDATIONFEATURE, true);
1925
          // From DB to find the register external schema location
1926
          String externalSchemaLocation = null;
1927
          SchemaLocationResolver resolver = new SchemaLocationResolver();
1928
          externalSchemaLocation = resolver.getNameSpaceAndLocationString();
1929
          // Set external schemalocation.
1930
          if (externalSchemaLocation != null &&
1931
            !(externalSchemaLocation.trim()).equals(""))
1932
          {
1933
            parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
1934
                             externalSchemaLocation);
1935
          }
1936
1937
        }
1938
        else if (ruleBase != null && ruleBase.equals(DTD) && needValidation)
1939
        {
1940
          MetaCatUtil.debugMessage("dtd parser", 20);
1941
          // turn on dtd validaton feature
1942
          parser.setFeature(VALIDATIONFEATURE, true);
1943
          eresolver= new DBEntityResolver(dbconn, (DBSAXHandler)chandler, dtd);
1944
          dtdhandler = new DBDTDHandler(dbconn);
1945
          parser.setEntityResolver((EntityResolver)eresolver);
1946
          parser.setDTDHandler((DTDHandler)dtdhandler);
1947
        }
1948
        else
1949
        {
1950
          MetaCatUtil.debugMessage("other parser", 20);
1951
          // non validation
1952
          parser.setFeature(VALIDATIONFEATURE, false);
1953
          eresolver= new DBEntityResolver(dbconn, (DBSAXHandler)chandler, dtd);
1954
          dtdhandler = new DBDTDHandler(dbconn);
1955
          parser.setEntityResolver((EntityResolver)eresolver);
1956
          parser.setDTDHandler((DTDHandler)dtdhandler);
1957
        }
1958
      }//else
1959 1383 tao
    }
1960
    catch (Exception e)
1961
    {
1962
      throw e;
1963
    }
1964
    return parser;
1965
  }
1966
1967
1968 396 jones
  /**
1969 407 jones
   * Set up the parser handlers for writing the document to the database
1970
   */
1971 1383 tao
  /*private static XMLReader initializeParser(DBConnection dbconn, String action,
1972 956 tao
                               String docid, String rev, boolean validate,
1973 802 bojilova
                                   String user, String[] groups, String pub,
1974 695 bojilova
                                   int serverCode, Reader dtd)
1975 598 bojilova
                           throws Exception
1976
  {
1977 407 jones
    XMLReader parser = null;
1978 1217 tao
    //DBConnection conn = null;
1979
    //int serialNumber = -1;
1980 407 jones
    //
1981
    // Set up the SAX document handlers for parsing
1982
    //
1983
    try {
1984 1217 tao
       //check out DBConnection
1985 1383 tao
1986 956 tao
      //create a DBSAXHandler object which has the revision specification
1987 1217 tao
      ContentHandler chandler = new DBSAXHandler(dbconn, action,
1988
                                    docid, rev, user, groups, pub, serverCode);
1989
      EntityResolver eresolver= new DBEntityResolver(dbconn,
1990 645 bojilova
                                                 (DBSAXHandler)chandler, dtd);
1991 1217 tao
      DTDHandler dtdhandler   = new DBDTDHandler(dbconn);
1992 407 jones
1993
      // Get an instance of the parser
1994 802 bojilova
      String parserName = MetaCatUtil.getOption("saxparser");
1995 407 jones
      parser = XMLReaderFactory.createXMLReader(parserName);
1996
1997 660 bojilova
      // Turn on validation
1998 695 bojilova
      parser.setFeature("http://xml.org/sax/features/validation", validate);
1999 660 bojilova
      // Turn off Including all external parameter entities
2000
      // (the external DTD subset also)
2001
      // Doesn't work well, probably the feature name is not correct
2002
      // parser.setFeature(
2003
      //  "http://xml.org/sax/features/external-parameter-entities", false);
2004 407 jones
2005
      // Set Handlers in the parser
2006
      parser.setProperty("http://xml.org/sax/properties/declaration-handler",
2007
                         chandler);
2008
      parser.setProperty("http://xml.org/sax/properties/lexical-handler",
2009
                         chandler);
2010
      parser.setContentHandler((ContentHandler)chandler);
2011 598 bojilova
      parser.setEntityResolver((EntityResolver)eresolver);
2012 407 jones
      parser.setDTDHandler((DTDHandler)dtdhandler);
2013
      parser.setErrorHandler((ErrorHandler)chandler);
2014
2015
    } catch (Exception e) {
2016 457 bojilova
      throw e;
2017 407 jones
    }
2018 1217 tao
    //finally
2019
    //{
2020
      //DBConnectionPool.returnDBConnection(conn, serialNumber);
2021
    //}
2022 407 jones
2023
    return parser;
2024 1383 tao
  }*/
2025 407 jones
2026 1217 tao
  /**
2027
   * Save a document entry in the xml_revisions table
2028
   * Connection use as a paramter is in order to rollback feature
2029
   */
2030
  private static void archiveDocRevision(DBConnection dbconn, String docid,
2031
                                                    String user)
2032
 {
2033
    String sysdate = dbAdapter.getDateTimeFunction();
2034
    //DBConnection conn = null;
2035
    //int serialNumber = -1;
2036
    PreparedStatement pstmt = null;
2037
2038
    // create a record in xml_revisions table
2039
    // for that document as selected from xml_documents
2040
2041
   try
2042
   {
2043
     //check out DBConnection
2044
     /*conn=DBConnectionPool.
2045
                    getDBConnection("DocumentImpl.archiveDocRevision");
2046
     serialNumber=conn.getCheckOutSerialNumber();*/
2047
     pstmt = dbconn.prepareStatement(
2048
      "INSERT INTO xml_revisions " +
2049
        "(docid, rootnodeid, docname, doctype, " +
2050
        "user_owner, user_updated, date_created, date_updated, " +
2051
        "server_location, rev, public_access, catalog_id) " +
2052
      "SELECT ?, rootnodeid, docname, doctype, " +
2053
        "user_owner, ?, " + sysdate + ", " + sysdate + ", "+
2054
        "server_location, rev, public_access, catalog_id " +
2055
      "FROM xml_documents " +
2056
      "WHERE docid = ?");
2057
      // Increase dbconnection usage count
2058
      dbconn.increaseUsageCount(1);
2059
      // Bind the values to the query and execute it
2060
      pstmt.setString(1, docid);
2061
      pstmt.setString(2, user);
2062
      pstmt.setString(3, docid);
2063
      pstmt.execute();
2064
      pstmt.close();
2065
   }//try
2066
   catch (SQLException e)
2067
   {
2068
     MetaCatUtil.debugMessage("Error in DocumentImpl.archiveDocRevision : "+
2069
                                e.getMessage(), 30);
2070
   }//catch
2071
   finally
2072
   {
2073
     try
2074
     {
2075
       pstmt.close();
2076
     }//try
2077
     catch (SQLException ee)
2078
     {
2079
       MetaCatUtil.debugMessage("Error in DocumnetImpl.archiveDocRevision: "+
2080
                                  ee.getMessage(), 50);
2081
     }//catch
2082
     //finally
2083
     //{
2084
2085
       //check in DBConnection
2086
       //DBConnectionPool.returnDBConnection(conn, serialNumber);
2087
     //}//finally
2088
   }//finnally
2089
2090
2091
  }//achiveDocRevision
2092
2093 459 bojilova
  /** Save a document entry in the xml_revisions table */
2094 1217 tao
  private static void archiveDocRevision(String docid, String user)
2095 1063 tao
 {
2096 754 bojilova
    String sysdate = dbAdapter.getDateTimeFunction();
2097 1217 tao
    DBConnection conn = null;
2098
    int serialNumber = -1;
2099
    PreparedStatement pstmt = null;
2100
2101 459 bojilova
    // create a record in xml_revisions table
2102
    // for that document as selected from xml_documents
2103 1063 tao
2104
   try
2105
   {
2106 1217 tao
     //check out DBConnection
2107
     conn=DBConnectionPool.
2108
                    getDBConnection("DocumentImpl.archiveDocRevision");
2109
     serialNumber=conn.getCheckOutSerialNumber();
2110
     pstmt = conn.prepareStatement(
2111 459 bojilova
      "INSERT INTO xml_revisions " +
2112 771 bojilova
        "(docid, rootnodeid, docname, doctype, " +
2113 697 bojilova
        "user_owner, user_updated, date_created, date_updated, " +
2114
        "server_location, rev, public_access, catalog_id) " +
2115 771 bojilova
      "SELECT ?, rootnodeid, docname, doctype, " +
2116 747 bojilova
        "user_owner, ?, " + sysdate + ", " + sysdate + ", "+
2117
        "server_location, rev, public_access, catalog_id " +
2118 459 bojilova
      "FROM xml_documents " +
2119
      "WHERE docid = ?");
2120 1063 tao
      // Bind the values to the query and execute it
2121
      pstmt.setString(1, docid);
2122
      pstmt.setString(2, user);
2123
      pstmt.setString(3, docid);
2124
      pstmt.execute();
2125
      pstmt.close();
2126 1217 tao
   }//try
2127 1063 tao
   catch (SQLException e)
2128
   {
2129 1217 tao
     MetaCatUtil.debugMessage("Error in DocumentImpl.archiveDocRevision : "+
2130
                                e.getMessage(), 30);
2131
   }//catch
2132
   finally
2133
   {
2134
     try
2135
     {
2136
       pstmt.close();
2137
     }//try
2138
     catch (SQLException ee)
2139
     {
2140
       MetaCatUtil.debugMessage("Error in DocumnetImpl.archiveDocRevision: "+
2141
                                  ee.getMessage(), 50);
2142
     }//catch
2143
     finally
2144
     {
2145
       //check in DBConnection
2146
       DBConnectionPool.returnDBConnection(conn, serialNumber);
2147
     }//finally
2148
   }//finnally
2149
2150 459 bojilova
2151 1217 tao
  }//achiveDocRevision
2152 965 tao
2153
  /**
2154
    * delete a entry in xml_table for given docid
2155
    * @param docId, the id of the document need to be delete
2156
    */
2157 1217 tao
  private static void deleteXMLDocuments(String docId)
2158 965 tao
                                         throws SQLException
2159
  {
2160 1217 tao
    DBConnection conn = null;
2161
    int serialNumber = -1;
2162
    PreparedStatement pStmt = null;
2163
    try
2164
    {
2165
      //check out DBConnection
2166
      conn=DBConnectionPool.
2167
                    getDBConnection("DocumentImpl.deleteXMLDocuments");
2168
      serialNumber=conn.getCheckOutSerialNumber();
2169
      //delete a record
2170
      pStmt =
2171 965 tao
             conn.prepareStatement("DELETE FROM xml_documents WHERE docid = '"
2172
                                              + docId + "'");
2173
    pStmt.execute();
2174 1217 tao
    }//try
2175
    finally
2176
    {
2177
      try
2178
      {
2179
        pStmt.close();
2180
      }//try
2181
      catch (SQLException e)
2182
      {
2183
        MetaCatUtil.debugMessage("error in DocumentImpl.deleteXMLDocuments: "+
2184
                                  e.getMessage(), 50);
2185
      }//catch
2186
      finally
2187
      {
2188
        //return back DBconnection
2189
        DBConnectionPool.returnDBConnection(conn, serialNumber);
2190
      }//finally
2191
    }//finally
2192
2193 459 bojilova
2194 965 tao
  }//deleteXMLDocuments
2195
2196 407 jones
  /**
2197 965 tao
    * Get last revision number from database for a docid
2198
    * If couldn't find an entry,  -1 will return
2199
    * The return value is integer because we want compare it to there new one
2200
    * @param docid <sitecode>.<uniqueid> part of Accession Number
2201
    */
2202 1217 tao
  private static int getLatestRevisionNumber(String docId)
2203 965 tao
                                      throws SQLException
2204
  {
2205
    int rev = 1;
2206 1217 tao
    PreparedStatement pStmt = null;
2207
    DBConnection dbConn = null;
2208
    int serialNumber = -1;
2209
2210
    try
2211
    {
2212
      //check out DBConnection
2213
      dbConn=DBConnectionPool.
2214
                    getDBConnection("DocumentImpl.getLatestRevisionNumber");
2215
      serialNumber=dbConn.getCheckOutSerialNumber();
2216 965 tao
2217 1217 tao
      pStmt = dbConn.prepareStatement
2218 965 tao
              ("SELECT rev FROM xml_documents WHERE docid='" + docId + "'");
2219 1217 tao
      pStmt.execute();
2220 965 tao
2221 1217 tao
      ResultSet rs = pStmt.getResultSet();
2222
      boolean hasRow = rs.next();
2223
      if (hasRow)
2224
      {
2225
        rev = rs.getInt(1);
2226
        pStmt.close();
2227
      }
2228
      else
2229
      {
2230
        rev=-1;
2231
        pStmt.close();
2232
      }
2233
    }//try
2234
    finally
2235 965 tao
    {
2236 1217 tao
      try
2237
      {
2238
        pStmt.close();
2239
      }
2240
      catch (Exception ee)
2241
      {
2242
        MetaCatUtil.debugMessage("Error in DocumentImpl."+
2243
                        "getLatestRevisionNumber: "+ee.getMessage(), 50);
2244
      }
2245
      finally
2246
      {
2247
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2248
      }
2249
    }//finally
2250 965 tao
2251
    return rev;
2252
  }//getLatestRevisionNumber
2253
2254
  /**
2255 1012 tao
   * Get server location form database for a accNum
2256
   *
2257
   * @param accum <sitecode>.<uniqueid>.<rev>
2258
   */
2259 1217 tao
  private static int getServerLocationNumber(String accNum)
2260 1012 tao
                                            throws SQLException
2261
  {
2262
    //get rid of revNum part
2263
    String docId=MetaCatUtil.getDocIdFromString(accNum);
2264 1217 tao
    PreparedStatement pStmt = null;
2265
    int serverLocation = 1;
2266
    DBConnection conn = null;
2267
    int serialNumber = -1;
2268
2269
    try
2270
    {
2271
      //check out DBConnection
2272
      conn=DBConnectionPool.
2273
                    getDBConnection("DocumentImpl.getServerLocationNumber");
2274
      serialNumber=conn.getCheckOutSerialNumber();
2275 1012 tao
2276 1217 tao
      pStmt = conn.prepareStatement
2277 1012 tao
      ("SELECT server_location FROM xml_documents WHERE docid='" + docId + "'");
2278 1217 tao
      pStmt.execute();
2279 1012 tao
2280 1217 tao
      ResultSet rs = pStmt.getResultSet();
2281
      boolean hasRow = rs.next();
2282
      //if there is entry in xml_documents, get the serverlocation
2283
      if (hasRow)
2284
      {
2285
        serverLocation = rs.getInt(1);
2286
        pStmt.close();
2287
      }
2288
      else
2289
      {
2290
        //if htere is no entry in xml_documents, we consider it is new document
2291
        //the server location is local host and value is 1
2292
        serverLocation=1;
2293
        pStmt.close();
2294
      }
2295
    }//try
2296
    finally
2297 1012 tao
    {
2298 1217 tao
      try
2299
      {
2300
        pStmt.close();
2301
      }//try
2302
      catch (Exception ee)
2303
      {
2304
        MetaCatUtil.debugMessage("Error in DocumentImpl.getServerLocationNu(): "
2305
                                    +ee.getMessage(), 50);
2306
      }//catch
2307
      finally
2308
      {
2309
        DBConnectionPool.returnDBConnection(conn, serialNumber);
2310
      }//finally
2311
    }//finally
2312 1012 tao
2313
    return serverLocation;
2314
  }
2315 1055 tao
2316 1012 tao
  /**
2317 1055 tao
   * Given a server name, return its servercode in xml_replication table.
2318
   * If no server is found, -1 will return
2319
   * @param serverName,
2320
   */
2321
  private static int getServerCode(String serverName)
2322
  {
2323
    PreparedStatement pStmt=null;
2324
    int serverLocation=-2;
2325 1217 tao
    DBConnection dbConn = null;
2326
    int serialNumber = -1;
2327
    //MetaCatUtil util = new MetaCatUtil();
2328 1055 tao
2329
2330
    //we should consider about local host too
2331 1217 tao
    if (serverName.equals(MetaCatUtil.getLocalReplicationServerName()))
2332 1055 tao
    {
2333
      serverLocation=1;
2334
      return serverLocation;
2335
    }
2336
2337
2338
    try
2339
    {
2340
      //check xml_replication table
2341 1217 tao
      //dbConn=util.openDBConnection();
2342
      //check out DBConnection
2343
      dbConn=DBConnectionPool.getDBConnection("DocumentImpl.getServerCode");
2344
      serialNumber=dbConn.getCheckOutSerialNumber();
2345 1055 tao
      pStmt = dbConn.prepareStatement
2346
      ("SELECT serverid FROM xml_replication WHERE server='" + serverName +"'");
2347
      pStmt.execute();
2348
2349
      ResultSet rs = pStmt.getResultSet();
2350
      boolean hasRow = rs.next();
2351
      //if there is entry in xml_replication, get the serverid
2352
      if (hasRow)
2353
      {
2354
        serverLocation = rs.getInt(1);
2355
        pStmt.close();
2356
      }
2357
      else
2358
      {
2359
        // if htere is no entry in xml_replication, -1 will return
2360
        serverLocation=-1;
2361
        pStmt.close();
2362
      }
2363
    }
2364
    catch (Exception e)
2365
    {
2366 1217 tao
      MetaCatUtil.debugMessage("Error in DocumentImpl.getServerCode(): "
2367 1055 tao
                                    +e.getMessage(), 30);
2368
    }
2369
    finally
2370
    {
2371
      try
2372
      {
2373 1217 tao
        pStmt.close();
2374 1055 tao
      }
2375
      catch (Exception ee)
2376 1217 tao
      {
2377
        MetaCatUtil.debugMessage("Error in DocumentImpl.getServerCode(): "
2378
                                    +ee.getMessage(), 50);
2379
      }
2380
      finally
2381
      {
2382
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2383
      }
2384 1055 tao
    }
2385
2386
2387
    return serverLocation;
2388
  }
2389
2390
  /**
2391
   * Insert a server into xml_replcation table
2392
   * @param server, the name of server
2393
   */
2394 1292 tao
  private static synchronized void
2395
                                insertServerIntoReplicationTable(String server)
2396 1055 tao
  {
2397
    PreparedStatement pStmt=null;
2398 1217 tao
    DBConnection dbConn = null;
2399
    int serialNumber = -1;
2400 1292 tao
2401
    // Initial value for the server
2402
    int replicate = 0;
2403
    int dataReplicate = 0;
2404
    int hub = 0;
2405
2406 1055 tao
    try
2407
    {
2408 1292 tao
       // Get DBConnection
2409 1217 tao
       dbConn=DBConnectionPool.
2410
                getDBConnection("DocumentImpl.insertServIntoReplicationTable");
2411
       serialNumber=dbConn.getCheckOutSerialNumber();
2412 1292 tao
2413
      // Compare the server to dabase
2414
      pStmt = dbConn.prepareStatement
2415
      ("SELECT serverid FROM xml_replication WHERE server='" + server +"'");
2416
      pStmt.execute();
2417
      ResultSet rs = pStmt.getResultSet();
2418
      boolean hasRow = rs.next();
2419
      // Close preparedstatement and result set
2420
      pStmt.close();
2421
      rs.close();
2422
2423
      // If the server is not in the table, and server is not local host,
2424
      // insert it
2425
      if ( !hasRow
2426
         && !server.equals(MetaCatUtil.getLocalReplicationServerName()))
2427
      {
2428
        // Set auto commit false
2429
        dbConn.setAutoCommit(false);
2430
        pStmt = dbConn.prepareStatement("INSERT INTO xml_replication " +
2431
                      "(server, last_checked, replicate, datareplicate, hub) " +
2432
                       "VALUES ('" + server + "', to_date(" +
2433
                       "'01/01/00', 'MM/DD/YY'), '" +
2434
                       replicate +"', '"+dataReplicate+"','"+ hub + "')");
2435 1055 tao
        pStmt.execute();
2436 1292 tao
        dbConn.commit();
2437
        // Increase usage number
2438
        dbConn.increaseUsageCount(1);
2439 1055 tao
        pStmt.close();
2440 1292 tao
2441
      }
2442 1217 tao
    }//try
2443 1055 tao
    catch (Exception e)
2444
    {
2445 1217 tao
      MetaCatUtil.debugMessage("Error in DocumentImpl.insertServerIntoRepli(): "
2446 1055 tao
                                    +e.getMessage(), 30);
2447 1217 tao
    }//catch
2448 1055 tao
    finally
2449
    {
2450 1217 tao
2451 1055 tao
      try
2452
      {
2453 1292 tao
        // Set auto commit true
2454
        dbConn.setAutoCommit(true);
2455 1055 tao
        pStmt.close();
2456 1292 tao
2457 1217 tao
      }//try
2458
      catch (Exception ee)
2459
      {
2460
        MetaCatUtil.debugMessage("Error in DocumentImpl.insetServerIntoRepl(): "
2461
                                    +ee.getMessage(), 50);
2462
      }//catch
2463
      finally
2464
      {
2465
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2466 1055 tao
      }
2467 1217 tao
2468
    }//finally
2469 1055 tao
2470
  }
2471
2472
2473
  /**
2474 407 jones
   * the main routine used to test the DBWriter utility.
2475
   * <p>
2476
   * Usage: java DocumentImpl <-f filename -a action -d docid>
2477
   *
2478
   * @param filename the filename to be loaded into the database
2479
   * @param action the action to perform (READ, INSERT, UPDATE, DELETE)
2480
   * @param docid the id of the document to process
2481
   */
2482
  static public void main(String[] args) {
2483 1217 tao
    DBConnection dbconn = null;
2484
    int serialNumber = -1;
2485 407 jones
    try {
2486 555 bojilova
      String filename    = null;
2487 598 bojilova
      String dtdfilename = null;
2488 555 bojilova
      String action      = null;
2489
      String docid       = null;
2490 429 jones
      boolean showRuntime = false;
2491
      boolean useOldReadAlgorithm = false;
2492 407 jones
2493 408 jones
      // Parse the command line arguments
2494 407 jones
      for ( int i=0 ; i < args.length; ++i ) {
2495
        if ( args[i].equals( "-f" ) ) {
2496
          filename =  args[++i];
2497 598 bojilova
        } else if ( args[i].equals( "-r" ) ) {
2498
          dtdfilename =  args[++i];
2499 407 jones
        } else if ( args[i].equals( "-a" ) ) {
2500
          action =  args[++i];
2501
        } else if ( args[i].equals( "-d" ) ) {
2502
          docid =  args[++i];
2503 429 jones
        } else if ( args[i].equals( "-t" ) ) {
2504
          showRuntime = true;
2505
        } else if ( args[i].equals( "-old" ) ) {
2506
          useOldReadAlgorithm = true;
2507 407 jones
        } else {
2508
          System.err.println
2509
            ( "   args[" +i+ "] '" +args[i]+ "' ignored." );
2510
        }
2511
      }
2512
2513 408 jones
      // Check if the required arguments are provided
2514 407 jones
      boolean argsAreValid = false;
2515
      if (action != null) {
2516
        if (action.equals("INSERT")) {
2517
          if (filename != null) {
2518
            argsAreValid = true;
2519
          }
2520
        } else if (action.equals("UPDATE")) {
2521
          if ((filename != null) && (docid != null)) {
2522
            argsAreValid = true;
2523
          }
2524
        } else if (action.equals("DELETE")) {
2525
          if (docid != null) {
2526
            argsAreValid = true;
2527
          }
2528
        } else if (action.equals("READ")) {
2529
          if (docid != null) {
2530
            argsAreValid = true;
2531
          }
2532
        }
2533
      }
2534
2535 408 jones
      // Print usage message if the arguments are not valid
2536 407 jones
      if (!argsAreValid) {
2537
        System.err.println("Wrong number of arguments!!!");
2538
        System.err.println(
2539 598 bojilova
          "USAGE: java DocumentImpl [-t] <-a INSERT> [-d docid] <-f filename> "+
2540 680 bojilova
          "[-r dtdfilename]");
2541 407 jones
        System.err.println(
2542 598 bojilova
          "   OR: java DocumentImpl [-t] <-a UPDATE -d docid -f filename> " +
2543 680 bojilova
          "[-r dtdfilename]");
2544 407 jones
        System.err.println(
2545 429 jones
          "   OR: java DocumentImpl [-t] <-a DELETE -d docid>");
2546 407 jones
        System.err.println(
2547 429 jones
          "   OR: java DocumentImpl [-t] [-old] <-a READ -d docid>");
2548 407 jones
        return;
2549
      }
2550 429 jones
2551
      // Time the request if asked for
2552
      double startTime = System.currentTimeMillis();
2553
2554 407 jones
      // Open a connection to the database
2555
      MetaCatUtil util = new MetaCatUtil();
2556 1217 tao
2557
      dbconn=DBConnectionPool.getDBConnection("DocumentImpl.main");
2558
      serialNumber=dbconn.getCheckOutSerialNumber();
2559 407 jones
2560 463 berkley
      double connTime = System.currentTimeMillis();
2561 408 jones
      // Execute the action requested (READ, INSERT, UPDATE, DELETE)
2562 407 jones
      if (action.equals("READ")) {
2563 1217 tao
          DocumentImpl xmldoc = new DocumentImpl(docid );
2564 429 jones
          if (useOldReadAlgorithm) {
2565
            System.out.println(xmldoc.readUsingSlowAlgorithm());
2566
          } else {
2567 1432 tao
            xmldoc.toXml(new PrintWriter(System.out), null, null);
2568 429 jones
          }
2569 408 jones
      } else if (action.equals("DELETE")) {
2570 1217 tao
        DocumentImpl.delete(docid, null, null);
2571 408 jones
        System.out.println("Document deleted: " + docid);
2572 407 jones
      } else {
2573 1383 tao
        /*String newdocid = DocumentImpl.write(dbconn, filename, null,
2574 598 bojilova
                                             dtdfilename, action, docid,
2575
                                             null, null);
2576 408 jones
        if ((docid != null) && (!docid.equals(newdocid))) {
2577
          if (action.equals("INSERT")) {
2578
            System.out.println("New document ID generated!!! ");
2579
          } else if (action.equals("UPDATE")) {
2580
            System.out.println("ERROR: Couldn't update document!!! ");
2581 407 jones
          }
2582 408 jones
        } else if ((docid == null) && (action.equals("UPDATE"))) {
2583
          System.out.println("ERROR: Couldn't update document!!! ");
2584 407 jones
        }
2585 408 jones
        System.out.println("Document processing finished for: " + filename
2586 1383 tao
              + " (" + newdocid + ")");*/
2587 407 jones
      }
2588
2589 429 jones
      double stopTime = System.currentTimeMillis();
2590 463 berkley
      double dbOpenTime = (connTime - startTime)/1000;
2591
      double insertTime = (stopTime - connTime)/1000;
2592 429 jones
      double executionTime = (stopTime - startTime)/1000;
2593
      if (showRuntime) {
2594 463 berkley
        System.out.println("\n\nTotal Execution time was: " +
2595
                           executionTime + " seconds.");
2596
        System.out.println("Time to open DB connection was: " + dbOpenTime +
2597
                           " seconds.");
2598
        System.out.println("Time to insert document was: " + insertTime +
2599
                           " seconds.");
2600 429 jones
      }
2601 463 berkley
      dbconn.close();
2602 407 jones
    } catch (McdbException me) {
2603
      me.toXml(new PrintWriter(System.err));
2604
    } catch (AccessionNumberException ane) {
2605
      System.out.println(ane.getMessage());
2606
    } catch (Exception e) {
2607
      System.err.println("EXCEPTION HANDLING REQUIRED");
2608
      System.err.println(e.getMessage());
2609
      e.printStackTrace(System.err);
2610
    }
2611 1217 tao
    finally
2612
    {
2613
      // Return db connection
2614
      DBConnectionPool.returnDBConnection(dbconn, serialNumber);
2615
    }
2616 407 jones
  }
2617 393 jones
}