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