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