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