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