Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that handles the SAX XML events as they
4
 *             are generated from XML documents
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones, Jivka Bojilova
8
 *    Release: @release@
9
 *
10
 *   '$Author: tao $'
11
 *     '$Date: 2003-04-07 10:41:39 -0700 (Mon, 07 Apr 2003) $'
12
 * '$Revision: 1517 $'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.sql.*;
32
import java.io.BufferedReader;
33
import java.io.File;
34
import java.io.FileReader;
35
import java.io.FileWriter;
36
import java.io.StringReader;
37
import java.util.Stack;
38
import java.util.Vector;
39
import java.util.Hashtable;
40
import java.util.Enumeration;
41
import java.util.EmptyStackException;
42

    
43
import org.xml.sax.Attributes;
44
import org.xml.sax.SAXException;
45
import org.xml.sax.SAXParseException;
46
import org.xml.sax.ext.DeclHandler;
47
import org.xml.sax.ext.LexicalHandler;
48
import org.xml.sax.helpers.DefaultHandler;
49

    
50
/**
51
 * A database aware Class implementing callback bethods for the SAX parser to
52
 * call when processing the XML stream and generating events
53
 */
54
public class EmlSAXHandler extends DBSAXHandler implements 
55
                                                      AccessControlInterface
56
{
57
   private Vector allowRules = new Vector();
58
   private Vector denyRules = new Vector();
59
   private String documentId = null;
60
   private Vector subDocumentIdList = new Vector();
61
   private boolean processTopLeverAccess = false;
62
   private boolean processAdditionalAccess = false;
63
   private AccessSection accessObject= null;
64
   private AccessRule accessRule = null;
65
   private Vector accessObjectList = new Vector(); // store every access rule
66
   private Hashtable topLevelAccessControlMap = new Hashtable();
67
   private Hashtable additionalAccessControlMap = new Hashtable();// store 
68
                                                 //subtree access for single
69
                                                 // additionalmetacat
70
   private Vector additionalAccessMapList = new Vector();// store maps for 
71
                                                       // every addionalmetadata
72
   private Vector describesId = new Vector(); // store the ids in
73
                                      //additionalmetadata/describes
74
   private Stack subTreeInfoStack = new Stack();
75
   private Vector subTreeList = new Vector();// store the final subtree
76
   private int inLineDataIndex = 1;
77
   private Hashtable unChangableSubTreeHash;
78
   private Stack currentUnChangedableSubtreeNodeStack;
79
   private boolean startCriticalSubTree = false;
80
   private boolean firstElementForCriticalSubTree = false;
81
   private String firstElementNameForCriticalSubTree;
82
 
83
 
84
   // Constant
85
   private static final String DESCRIBES = "describes";
86
   private static final String ADDITIONALMETADATA = "additionalMetadata";
87
   private static final String ORDER = "order";
88
   private static final String ID ="id";
89
   private static final String REFERENCES = "references";
90
   public  static final String INLINE = "inline";
91
   private static final String PERMISSIONERROR ="User try to update a subtree"+
92
                               " which it doesn't have write permission!";
93
  
94
    /** Construct an instance of the handler class
95
    * In this constructor, user can specify the version need to upadate
96
    *
97
    * @param conn the JDBC connection to which information is written
98
    * @param action - "INSERT" or "UPDATE"
99
    * @param docid to be inserted or updated into JDBC connection
100
    * @param revision, the user specified the revision need to be update
101
    * @param user the user connected to MetaCat servlet and owns the document
102
    * @param groups the groups to which user belongs
103
    * @param pub flag for public "read" access on document
104
    * @param serverCode the serverid from xml_replication on which this document
105
    *        resides.
106
    *
107
    */
108
   public EmlSAXHandler(DBConnection conn, String action, String docid,
109
     String revision, String user, String[] groups, String pub, int serverCode)
110
                              throws SAXException
111
   {
112
     super(conn, action, docid, revision, user, groups, pub, serverCode);
113
     // Get the unchangable subtrees (user doesn't have write permission)
114
     try
115
     {
116
       PermissionController control = new PermissionController(docid);
117
       unChangableSubTreeHash = getUnchangableSubTree(control, user, groups);
118
     }
119
     catch (Exception e)
120
     {
121
       throw new SAXException(e.getMessage());
122
     }
123
   }
124
   
125
   /* Pass a permission control and get the list of unchangable subtree*/
126
   private Hashtable getUnchangableSubTree(PermissionController controller,
127
                                           String user, String[]groups)
128
                                           throws Exception
129
   {
130
     Hashtable list = null;
131
     Hashtable result = new Hashtable();
132
     // get unwritable sutree from controller
133
     list = controller.hasUnaccessableSubTree(user, groups, 
134
                                          AccessControlInterface.WRITESTRING);
135
      if (list != null)
136
      {
137
       
138
         Enumeration en = list.elements();
139
         while (en.hasMoreElements())
140
         {
141
           // Get  a subtree without node record list
142
           SubTree treeWithoutStack = (SubTree)en.nextElement();
143
           String subTreeId   = treeWithoutStack.getSubTreeId();
144
           MetaCatUtil.debugMessage("unchangable subtree id: " + subTreeId, 40);
145
           long   startNodeId = treeWithoutStack.getStartNodeId();
146
           MetaCatUtil.debugMessage("unchangable subtree startnodeid: " +
147
                                    startNodeId, 40);
148
           long   endNodeId   = treeWithoutStack.getEndNodeId();
149
           MetaCatUtil.debugMessage("unchangable subtree endnodeid: " +
150
                                     endNodeId, 40);
151
           // Get a subtree has the nodelist
152
           SubTree tree = new SubTree(docid, subTreeId, startNodeId, endNodeId);
153
           // add this tree to the result
154
           result.put(subTreeId, tree);
155
         
156
          }//while
157
      
158
      }//if
159
      
160
      return result;
161
   }
162
   
163
   /** SAX Handler that is called at the start of each XML element */
164
   public void startElement(String uri, String localName,
165
                            String qName, Attributes atts)
166
               throws SAXException 
167
  {
168
      // for element <eml:eml...> qname is "eml:eml", local name is "eml"            
169
     // for element <acl....> both qname and local name is "eml"
170
     // uri is namesapce
171
     MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
172
     MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
173
     MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
174
     
175
     
176
     DBSAXNode parentNode = null;
177
     DBSAXNode currentNode = null;
178

    
179
     // Get a reference to the parent node for the id
180
     try 
181
     {
182
       parentNode = (DBSAXNode)nodeStack.peek();
183
     } 
184
     catch (EmptyStackException e) 
185
     {
186
       parentNode = null;
187
     }
188
     
189
     // If hit a text node, we need write this text for current's parent node
190
     // This will happend if the element is mixted
191
     if (hitTextNode && parentNode != null)
192
     {
193
       //compare text node data
194
       if (startCriticalSubTree)
195
       {
196
            NodeRecord node = null;
197
            try
198
            { 
199
              node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
200
            }
201
            catch (EmptyStackException ee)
202
            {
203
              MetaCatUtil.debugMessage("Node stack is empty for text data in startElement", 35);
204
              throw new SAXException(PERMISSIONERROR);
205
            }
206
            MetaCatUtil.debugMessage("current node type from xml is TEXT in start element", 40);
207
            MetaCatUtil.debugMessage("node type from stack: " + 
208
                                        node.getNodeType(), 40);
209
            MetaCatUtil.debugMessage("current node data from xml is: " + 
210
                                        textBuffer.toString(), 40);
211
            MetaCatUtil.debugMessage("node data from stack: " +
212
                                        node.getNodeData(), 40);
213
            MetaCatUtil.debugMessage("node name from stack: " +
214
                                        node.getNodeName(), 40);
215
            MetaCatUtil.debugMessage("node is: "+ node.getNodeId(), 40);              
216
            if (!node.getNodeType().equals("TEXT") || 
217
               !(textBuffer.toString()).equals(node.getNodeData())) 
218
            { 
219
              MetaCatUtil.debugMessage("current node type from xml is TEXT in start element", 40);
220
              MetaCatUtil.debugMessage("node type from stack: " + 
221
                                        node.getNodeType(), 40);
222
              MetaCatUtil.debugMessage("current node data from xml is: " + 
223
                                        textBuffer.toString(), 40);
224
              MetaCatUtil.debugMessage("node data from stack: " +
225
                                        node.getNodeData(), 40);
226
              MetaCatUtil.debugMessage("node name from stack: " +
227
                                        node.getNodeName(), 40);
228
              MetaCatUtil.debugMessage("node is: "+ node.getNodeId(), 40);
229
              throw new SAXException(PERMISSIONERROR);
230
            }//if
231
        }//if
232
       // write the textbuffer into db for parent node.
233
        endNodeId = writeTextForDBSAXNode(textBuffer, parentNode);
234
        // rest hitTextNode
235
        hitTextNode =false;
236
        // reset textbuffer
237
        textBuffer = null;
238
        textBuffer = new StringBuffer();
239
       
240
     }
241
     
242
  
243
     // Document representation that points to the root document node
244
     if (atFirstElement) 
245
     {
246
       atFirstElement = false;
247
       // If no DOCTYPE declaration: docname = root element
248
       // doctype = root element name or name space
249
       if (docname == null) 
250
       {
251
         docname = localName;
252
         // if uri isn't null doctype = uri(namespace)
253
         // othewise root element
254
         if (uri != null && !(uri.trim()).equals(""))
255
         {
256
           doctype = uri;
257
         }
258
         else
259
         {
260
           doctype = docname;
261
         }
262
         MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
263
         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
264
       } 
265
       else if (doctype == null) 
266
       {
267
         // because docname is not null and it is declared in dtd
268
         // so could not be in schema, no namespace
269
         doctype = docname;
270
         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
271
       }
272
       rootNode.writeNodename(docname);
273
       try 
274
       {
275
         // for validated XML Documents store a reference to XML DB Catalog
276
         // Because this is select statement and it needn't to roll back if
277
         // insert document action fialed.
278
         // In order to decrease DBConnection usage count, we get a new
279
         // dbconnection from pool
280
         String catalogid = null;
281
         DBConnection dbConn = null;
282
         int serialNumber = -1;
283

    
284
         if ( systemid != null ) 
285
         {
286
           try
287
           {
288
            // Get dbconnection
289
            dbConn=DBConnectionPool.getDBConnection
290
                                          ("DBSAXHandler.startElement");
291
            serialNumber=dbConn.getCheckOutSerialNumber();
292

    
293
            Statement stmt = dbConn.createStatement();
294
            ResultSet rs = stmt.executeQuery(
295
                          "SELECT catalog_id FROM xml_catalog " +
296
                          "WHERE entry_type = 'DTD' " +
297
                          "AND public_id = '" + doctype + "'");
298
            boolean hasRow = rs.next();
299
            if ( hasRow ) {
300
              catalogid = rs.getString(1);
301
            }
302
            stmt.close();
303
           }//try
304
           finally
305
           {
306
             // Return dbconnection
307
             DBConnectionPool.returnDBConnection(dbConn, serialNumber);
308
           }//finally
309
         }
310

    
311
         //create documentImpl object by the constructor which can specify
312
         //the revision
313
         currentDocument = new DocumentImpl(connection, rootNode.getNodeID(),
314
                               docname, doctype, docid, revision, action, user,
315
                               this.pub, catalogid, this.serverCode);
316

    
317

    
318
       } 
319
       catch (Exception ane) 
320
       {
321
         throw (new SAXException("Error in DBSaxHandler.startElement " +
322
                                 action, ane));
323
       }
324
     }
325

    
326
     // Create the current node representation
327
     currentNode = new DBSAXNode(connection, qName, localName, parentNode,
328
                                 currentDocument.getRootNodeID(),docid,
329
                                 currentDocument.getDoctype());
330
     // Use a local variable to store the element node id
331
     // If this element is a start point of subtree(section), it will be stored
332
     // otherwise, it will be discated
333
     long startNodeId = currentNode.getNodeID();
334
     // Add all of the namespaces
335
     String prefix;
336
     String nsuri;
337
     Enumeration prefixes = namespaces.keys();
338
     while ( prefixes.hasMoreElements() ) 
339
     {
340
       prefix = (String)prefixes.nextElement();
341
       nsuri = (String)namespaces.get(prefix);
342
       endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
343
     }
344
   
345

    
346
     // Add all of the attributes
347
     for (int i=0; i<atts.getLength(); i++) 
348
     {
349
       String attributeName = atts.getQName(i);
350
       String attributeValue = atts.getValue(i);
351
       endNodeId = 
352
                currentNode.setAttribute(attributeName, attributeValue, docid);
353
       
354
       // To handle name space and schema location if the attribute name is
355
       // xsi:schemaLocation. If the name space is in not in catalog table
356
       // it will be regeistered.
357
       if (attributeName != null && 
358
           attributeName.indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1)
359
       {
360
         SchemaLocationResolver resolver = 
361
                                  new SchemaLocationResolver(attributeValue);
362
         resolver.resolveNameSpace();
363
         
364
       }
365
       else if (attributeName !=null && attributeName.equals(ID))
366
       {
367
        
368
        
369
         //check unchangedable subtree hash if contains this subtree id
370
         if (unChangableSubTreeHash.containsKey(attributeValue))
371
         {
372
           // this subtree couldn't be changed by the user and move it from hash
373
           SubTree currentUnChangedableSubtree = (SubTree)
374
                                  unChangableSubTreeHash.remove(attributeValue);
375
           currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree.
376
                                                         getSubTreeNodeStack();
377
           startCriticalSubTree = true;
378
           firstElementForCriticalSubTree = true;
379
         }
380
         
381
         // handle subtree info
382
         SubTree subTress = new SubTree();
383
         // set sub tree id
384
         subTress.setSubTreeId(attributeValue);
385
         // set sub tree sstart lement name
386
         subTress.setStartElementName(currentNode.getTagName());
387
         // set start node number
388
         subTress.setStartNodeId(startNodeId);
389
         // add to stack, but it didn't get end node id yet
390
         subTreeInfoStack.push(subTress);
391
         
392
       }
393
     }//for
394
   
395
     // handle access stuff
396
     if (localName.equals(ACCESS))
397
     {
398
       // if it is in addtionalmetacat
399
       if (parentNode.getTagName() == ADDITIONALMETADATA)
400
       {
401
         processAdditionalAccess = true;
402
        
403
       }
404
       else
405
       {
406
         processTopLeverAccess = true;
407
        
408
       }
409
       // create access object 
410
        accessObject = new AccessSection();
411
         // set permission order
412
       String permOrder = currentNode.getAttribute(ORDER);
413
       accessObject.setPermissionOrder(permOrder);
414
       // set access id
415
       String accessId = currentNode.getAttribute(ID);
416
       accessObject.setAccessSectionId(accessId);
417
       
418
     }
419
     // Set up a access rule for allow
420
     else if (parentNode.getTagName() != null && 
421
       (parentNode.getTagName()).equals(ACCESS) && localName.equals(ALLOW))
422
     {
423
      
424
       accessRule = new AccessRule(); 
425
      
426
       //set permission type "allow"
427
       accessRule.setPermissionType(ALLOW);
428
      
429
     }
430
     // set up an access rule for den
431
     else if (parentNode.getTagName() != null 
432
       && (parentNode.getTagName()).equals(ACCESS) && localName.equals(DENY))
433
     {
434
       accessRule = new AccessRule();
435
       //set permission type "allow"
436
       accessRule.setPermissionType(DENY);
437
     }
438
      
439
     // Add the node to the stack, so that any text data can be
440
     // added as it is encountered
441
     nodeStack.push(currentNode);
442
     // Add the node to the vector used by thread for writing XML Index
443
     nodeIndex.addElement(currentNode);
444
    
445
    // handle critical subtree
446
    if (startCriticalSubTree && firstElementForCriticalSubTree)
447
    {
448
      //store the element name
449
      firstElementNameForCriticalSubTree = qName;
450
      firstElementForCriticalSubTree = false;
451
    }//for first element
452
    // handle critical subtree
453
    if (startCriticalSubTree)
454
    {
455
      //Get element subtree node stack (element node)
456
      NodeRecord elementNode = null;
457
      try
458
      {
459
        elementNode= (NodeRecord) currentUnChangedableSubtreeNodeStack.pop();
460
      }
461
      catch (EmptyStackException ee)
462
      {
463
        MetaCatUtil.debugMessage("Node stack is empty for element data", 35);
464
        throw new SAXException(PERMISSIONERROR);
465
      }
466
      MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
467
      MetaCatUtil.debugMessage("node type from stack: " + 
468
                                  elementNode.getNodeType(), 40);
469
      MetaCatUtil.debugMessage("node name from xml document: " + 
470
                                  localName, 40);
471
      MetaCatUtil.debugMessage("node name from stack: " +
472
                                  elementNode.getNodeName(), 40);
473
      MetaCatUtil.debugMessage("node data from stack: " +
474
                                  elementNode.getNodeData(), 40);
475
      MetaCatUtil.debugMessage("node is: "+ elementNode.getNodeId(), 40);
476
      // if this node is not element or local name not equal or name space not
477
      // equals, throw an exception
478
      if (!elementNode.getNodeType().equals("ELEMENT") || 
479
          !localName.equals(elementNode.getNodeName()))
480
        //  (uri != null && !uri.equals(elementNode.getNodePrefix())))
481
      {
482
        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
483
        MetaCatUtil.debugMessage("node type from stack: " + 
484
                                  elementNode.getNodeType(), 40);
485
        MetaCatUtil.debugMessage("node name from xml document: " + 
486
                                  localName, 40);
487
        MetaCatUtil.debugMessage("node name from stack: " +
488
                                  elementNode.getNodeName(), 40);
489
        MetaCatUtil.debugMessage("node data from stack: " +
490
                                  elementNode.getNodeData(), 40);
491
        MetaCatUtil.debugMessage("node is: "+ elementNode.getNodeId(), 40);
492
        throw new SAXException(PERMISSIONERROR);
493
      }
494
      
495
      //compare namespace
496
     Enumeration nameEn = namespaces.keys();
497
     while ( nameEn.hasMoreElements() ) 
498
     {
499
       //Get namespacke node stack (element node)
500
       NodeRecord nameNode = null;
501
       try
502
       { 
503
         nameNode = (NodeRecord) currentUnChangedableSubtreeNodeStack.pop();
504
       }
505
       catch (EmptyStackException ee)
506
       {
507
         MetaCatUtil.debugMessage("Node stack is empty for namespace data", 35);
508
         throw new SAXException(PERMISSIONERROR);
509
       }
510
       
511
       String prefixName = (String)nameEn.nextElement(); 
512
       String nameSpaceUri = (String)namespaces.get(prefixName);
513
       if (!nameNode.getNodeType().equals("NAMESPACE") || 
514
           !prefixName.equals(nameNode.getNodeName()) || 
515
           !nameSpaceUri.equals(nameNode.getNodeData()))
516
       { 
517
         MetaCatUtil.debugMessage("current node type from xml is NAMESPACE", 40);
518
         MetaCatUtil.debugMessage("node type from stack: " + 
519
                                  nameNode.getNodeType(), 40);
520
         MetaCatUtil.debugMessage("current node name from xml is: " + 
521
                                   prefixName, 40);
522
         MetaCatUtil.debugMessage("node name from stack: " +
523
                                  nameNode.getNodeName(), 40);
524
         MetaCatUtil.debugMessage("current node data from xml is: " + 
525
                                   nameSpaceUri, 40);
526
         MetaCatUtil.debugMessage("node data from stack: " +
527
                                  nameNode.getNodeData(), 40);
528
         MetaCatUtil.debugMessage("node is: "+ nameNode.getNodeId(), 40);
529
         throw new SAXException(PERMISSIONERROR);
530
       }
531
      
532
     }//while
533
      
534
      //compare attributes
535
      for (int i=0; i<atts.getLength(); i++)
536
      {
537
        NodeRecord attriNode = null;
538
        try
539
        {
540
          attriNode = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
541
          
542
        }
543
        catch (EmptyStackException ee)
544
        {
545
          MetaCatUtil.debugMessage("Node stack is empty for attribute data", 35);
546
          throw new SAXException(PERMISSIONERROR);
547
        }
548
        String attributeName = atts.getQName(i);
549
        String attributeValue = atts.getValue(i);
550
        MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
551
        MetaCatUtil.debugMessage("node type from stack: " + 
552
                                   attriNode.getNodeType(), 40);
553
        MetaCatUtil.debugMessage("current node name from xml is: " + 
554
                                    attributeName, 40);
555
        MetaCatUtil.debugMessage("node name from stack: " +
556
                                    attriNode.getNodeName(), 40);
557
        MetaCatUtil.debugMessage("current node data from xml is: " + 
558
                                    attributeValue, 40);
559
        MetaCatUtil.debugMessage("node data from stack: " +
560
                                    attriNode.getNodeData(), 40);
561
        MetaCatUtil.debugMessage("node is: "+ attriNode.getNodeId(), 40);
562
        
563
        if (!attriNode.getNodeType().equals("ATTRIBUTE") || 
564
            !attributeName.equals(attriNode.getNodeName()) ||
565
            !attributeValue.equals(attriNode.getNodeData()))
566
        {
567
          MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
568
          MetaCatUtil.debugMessage("node type from stack: " + 
569
                                   attriNode.getNodeType(), 40);
570
          MetaCatUtil.debugMessage("current node name from xml is: " + 
571
                                    attributeName, 40);
572
          MetaCatUtil.debugMessage("node name from stack: " +
573
                                    attriNode.getNodeName(), 40);
574
          MetaCatUtil.debugMessage("current node data from xml is: " + 
575
                                    attributeValue, 40);
576
          MetaCatUtil.debugMessage("node data from stack: " +
577
                                    attriNode.getNodeData(), 40);
578
          MetaCatUtil.debugMessage("node is: "+ attriNode.getNodeId(), 40);
579
          throw new SAXException(PERMISSIONERROR);
580
        }
581
      }//for
582
      
583
    }
584
    // reset name space
585
    namespaces = null;
586
    namespaces = new Hashtable();
587
  }
588
  
589
   
590
  /** SAX Handler that is called at the end of each XML element */
591
   public void endElement(String uri, String localName,
592
                          String qName) throws SAXException 
593
  {
594
     MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
595

    
596
     // Get the node from the stack
597
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
598
     String currentTag = currentNode.getTagName();
599
    
600
     // If before the end element, the parser hit text nodes and store them
601
     // into the buffer, write the buffer to data base. The reason we put
602
     // write database here is for xerces some time split text node
603
     if (hitTextNode)
604
     {
605
        // get access value
606
        String data = null;
607
        // add principal
608
       if (currentTag.equals(PRINCIPAL) && accessRule != null) 
609
       {
610
          data = (textBuffer.toString()).trim();
611
          accessRule.addPrincipal(data);
612

    
613
       } 
614
       else if (currentTag.equals(PERMISSION) && accessRule != null) 
615
       {
616
         data = (textBuffer.toString()).trim();
617
         // we conbine different a permission into one value
618
         int permission = accessRule.getPermission();
619
         // add permision
620
         if ( data.toUpperCase().equals(READSTRING) ) 
621
         {
622
           permission = permission | READ;
623
         } 
624
         else if ( data.toUpperCase().equals(WRITESTRING) ) 
625
         {
626
           permission = permission | WRITE;
627
         } 
628
         else if ( data.toUpperCase().equals(CHMODSTRING)) 
629
         {
630
           permission = permission | CHMOD;
631
         } 
632
         else if ( data.toUpperCase().equals(ALLSTRING) ) 
633
         {
634
          permission = permission | ALL;
635
         }
636
         accessRule.setPermission(permission);
637
       }
638
       // put additionalmetadata/describes into vector
639
       else if (currentTag.equals(DESCRIBES))
640
       {
641
          data = (textBuffer.toString()).trim();
642
          describesId.add(data);
643
       }
644
       else if (currentTag.equals(REFERENCES) && 
645
               (processTopLeverAccess||processAdditionalAccess))
646
       {
647
         // get reference 
648
         data = (textBuffer.toString()).trim();
649
         // put reference id into accessSection
650
         accessObject.setReferences(data);
651
         
652
       }
653
       // write text to db if it is not inline data
654
       if (!localName.equals(INLINE))
655
       {
656
          MetaCatUtil.debugMessage("Write text into DB in End Element", 50);
657
          //compare whitespace if need
658
          if (startCriticalSubTree)
659
          {
660
            NodeRecord node = null;
661
            try
662
            {
663
              node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
664
            }
665
            catch (EmptyStackException ee)
666
            {
667
              MetaCatUtil.debugMessage("the stack is empty for text data", 32);
668
              throw new SAXException(PERMISSIONERROR);
669
            }
670
            MetaCatUtil.debugMessage("current node type from xml is TEXT in endElement", 40);
671
            MetaCatUtil.debugMessage("node type from stack: " + 
672
                                        node.getNodeType(), 40);
673
            MetaCatUtil.debugMessage("current node data from xml is: " + 
674
                                        textBuffer.toString(), 40);
675
            MetaCatUtil.debugMessage("node data from stack: " +
676
                                        node.getNodeData(), 40);
677
            MetaCatUtil.debugMessage("node name from stack: " + 
678
                                        node.getNodeName(), 40);
679
            MetaCatUtil.debugMessage("node is from stack: " + 
680
                                        node.getNodeId(), 40);
681
            if (!node.getNodeType().equals("TEXT") || 
682
               !(textBuffer.toString()).equals(node.getNodeData())) 
683
            { 
684
              MetaCatUtil.debugMessage("current node type from xml is TEXT in endElement", 40);
685
              MetaCatUtil.debugMessage("node type from stack: " + 
686
                                        node.getNodeType(), 40);
687
              MetaCatUtil.debugMessage("current node data from xml is: " + 
688
                                        textBuffer.toString(), 40);
689
              MetaCatUtil.debugMessage("node data from stack: " +
690
                                        node.getNodeData(), 40);
691
              MetaCatUtil.debugMessage("node name from stack: " + 
692
                                        node.getNodeName(), 40);
693
              MetaCatUtil.debugMessage("node is from stack: " + 
694
                                        node.getNodeId(), 40);
695
              throw new SAXException(PERMISSIONERROR);
696
            }//if
697
          }//if
698
          endNodeId = writeTextForDBSAXNode(textBuffer, currentNode);
699
       }
700
       else
701
       {
702
          MetaCatUtil.debugMessage("Write inline data into file system", 35);
703
          
704
          //check if user changed inine data or not if user doesn't have
705
          // write permission
706
          if (startCriticalSubTree)
707
          {
708
            NodeRecord node = null;
709
            String inlineData;
710
            try
711
            {
712
              node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
713
              // get file name from db
714
              String fileName = node.getNodeData();
715
              MetaCatUtil.debugMessage("in handle inline data", 35);
716
              MetaCatUtil.debugMessage("the inline data file name from node is: "+
717
                                      fileName, 40);
718
              inlineData = readInlineDataFromFileSystem(fileName);
719
            }
720
            catch (EmptyStackException ee)
721
            {
722
              MetaCatUtil.debugMessage("the stack is empty for text data", 32);
723
              throw new SAXException(PERMISSIONERROR);
724
            }
725
            catch (McdbException eee)
726
            {
727
              throw new SAXException(eee.getMessage());
728
            }
729
            
730
            if (!(textBuffer.toString()).equals(inlineData))
731
            {
732
              MetaCatUtil.debugMessage("inline data was changed by a user" +
733
                                       " who doesn't have permission", 30);
734
              throw new SAXException(PERMISSIONERROR);
735
            }//if
736
          }//if
737
          // write inline data into file system and return file name
738
          textBuffer = writeInlineDataIntoFile(textBuffer);
739
          // write file name into db
740
          endNodeId = writeTextForDBSAXNode(textBuffer, currentNode);
741
       }
742
     }//if
743
     
744
     //end crtical subtree(user doesn't have permission to write)
745
     //When reach the first element and stack is empty
746
     if (localName.equals(firstElementNameForCriticalSubTree) && 
747
         currentUnChangedableSubtreeNodeStack.isEmpty()) 
748
     {
749
       startCriticalSubTree = false;
750
     }
751
     
752
     
753
     //set hitText false
754
     hitTextNode = false;
755
     // reset textbuff
756
     textBuffer = null;
757
     textBuffer = new StringBuffer();
758
     
759
     // hand sub stree stuff
760
     if (!subTreeInfoStack.empty())
761
     {
762
       SubTree tree = (SubTree)subTreeInfoStack.peek();// get last subtree
763
       if (tree != null && tree.getStartElementName() != null && 
764
         (tree.getStartElementName()).equals(currentTag))
765
       {
766
         // find the end of sub tree and set the end node id
767
         tree.setEndNodeId(endNodeId);
768
         // add the subtree into the final store palace
769
         subTreeList.add(tree);
770
         // get rid of it from stack
771
         subTreeInfoStack.pop();
772
       }//if
773
     }//if
774

    
775
     // access stuff
776
     if (currentTag.equals(ALLOW) || currentTag.equals(DENY))
777
     {
778
       // finish parser a ccess rule and  assign it to new one
779
       AccessRule newRule = accessRule;
780
       //add the new rule to access section object
781
       accessObject.addAccessRule(newRule);
782
       // reset access rule
783
       accessRule = null;
784
     }
785
     else if (currentTag.equals(ACCESS))
786
     {
787
       // finish parse a access setction and assign it to new one
788
       AccessSection newAccessObject = accessObject;
789
       if (newAccessObject != null)
790
       {
791
        // add the accessSection into a vector to store it
792
        // if it is not a reference, need to store it
793
        if ( newAccessObject.getReferences() == null)
794
        {
795
          accessObjectList.add(newAccessObject);
796
        }
797
        if (processTopLeverAccess)
798
        {
799
          // top level access control will handle whole document -docid
800
          topLevelAccessControlMap.put(docid, newAccessObject);
801
          // reset processtopleveraccess tag
802
          
803
        }//if
804
        else if (processAdditionalAccess)
805
        {
806
          // for additional control
807
          // put everything in describes value and access object into hash
808
       
809
          for ( int i=0; i<describesId.size(); i++)
810
          {
811
           
812
            String subId = (String)describesId.elementAt(i);
813
            if (subId != null)
814
            {
815
              additionalAccessControlMap.put(subId, newAccessObject);
816
            }//if
817
          }//for
818
          // add this hashtable in to vector
819
         
820
          additionalAccessMapList.add(additionalAccessControlMap);
821
          // reset this hashtable in order to store another additional 
822
          //accesscontrol
823
          additionalAccessControlMap = null;
824
          additionalAccessControlMap = new Hashtable();
825
        }//if
826
       }//if
827
       //reset access section object
828
       accessObject = null;
829
       // reset flag
830
       processAdditionalAccess =false;
831
       processTopLeverAccess =false;
832
     }
833
     else if (currentTag.equals(ADDITIONALMETADATA))
834
     {
835
        //reset describesId
836
        describesId = null;
837
        describesId = new Vector();
838
     }
839
   }
840
   
841
   /**
842
    * SAX Handler that receives notification of comments in the DTD
843
    */
844
   public void comment(char[] ch, int start, int length) throws SAXException {
845
     MetaCatUtil.debugMessage("COMMENT", 50);
846
     if ( !processingDTD ) 
847
     {
848
       DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
849
       String str = new String(ch, start, length);
850
       
851
       //compare comment if need
852
       if (startCriticalSubTree)
853
       {
854
         NodeRecord node = null;
855
         try
856
         {
857
           node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
858
         }
859
         catch (EmptyStackException ee)
860
         {
861
           MetaCatUtil.debugMessage("the stack is empty for comment data", 32);
862
           throw new SAXException(PERMISSIONERROR);
863
         }
864
         MetaCatUtil.debugMessage("current node type from xml is COMMENT", 40);
865
         MetaCatUtil.debugMessage("node type from stack: " + 
866
                                    node.getNodeType(), 40);
867
         MetaCatUtil.debugMessage("current node data from xml is: " + 
868
                                    str, 40);
869
         MetaCatUtil.debugMessage("node data from stack: " +
870
                                    node.getNodeData(), 40);
871
         MetaCatUtil.debugMessage("node is from stack: " + 
872
                                        node.getNodeId(), 40);
873
         if (!node.getNodeType().equals("COMMENT") || 
874
             !str.equals(node.getNodeData())) 
875
         { 
876
          MetaCatUtil.debugMessage("current node type from xml is COMMENT", 40);
877
          MetaCatUtil.debugMessage("node type from stack: " + 
878
                                    node.getNodeType(), 40);
879
          MetaCatUtil.debugMessage("current node data from xml is: " + 
880
                                    str, 40);
881
          MetaCatUtil.debugMessage("node data from stack: " +
882
                                    node.getNodeData(), 40);
883
          MetaCatUtil.debugMessage("node is from stack: " + 
884
                                        node.getNodeId(), 40);
885
          throw new SAXException(PERMISSIONERROR);
886
        }//if
887
       }//if
888
       
889
       endNodeId = currentNode.writeChildNodeToDB("COMMENT", null, str, docid);
890
     }
891
   }
892
   
893
      /**
894
    * SAX Handler that is called for each XML text node that is
895
    * Ignorable white space
896
    */
897
   public void ignorableWhitespace(char[] cbuf, int start, int len)
898
               throws SAXException 
899
  {
900
     // When validation is turned "on", white spaces are reported here
901
     // When validation is turned "off" white spaces are not reported here,
902
     // but through characters() callback
903
     MetaCatUtil.debugMessage("IGNORABLEWHITESPACE", 50);
904
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
905
     String data = null;
906
     int leftover = len;
907
     int offset = start;
908
     boolean moredata = true;
909

    
910
     // This loop deals with the case where there are more characters
911
     // than can fit in a single database text field (limit is
912
     // MAXDATACHARS).  If the text to be inserted exceeds MAXDATACHARS,
913
     // write a series of nodes that are MAXDATACHARS long, and then the
914
     // final node contains the remainder
915
     while (moredata) 
916
     {
917
       if (leftover > MAXDATACHARS) 
918
       {
919
         data = new String(cbuf, offset, MAXDATACHARS);
920
         leftover -= MAXDATACHARS;
921
         offset += MAXDATACHARS;
922
       } 
923
       else 
924
       {
925
         data = new String(cbuf, offset, leftover);
926
         moredata = false;
927
       }
928

    
929
       //compare whitespace if need
930
       if (startCriticalSubTree)
931
       {
932
         NodeRecord node = null;
933
         try
934
         {
935
           node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
936
         }
937
         catch (EmptyStackException ee)
938
         {
939
           MetaCatUtil.debugMessage("the stack is empty for whitespace data", 32);
940
           throw new SAXException(PERMISSIONERROR);
941
         }
942
         if (!node.getNodeType().equals("TEXT") || 
943
             !data.equals(node.getNodeData())) 
944
         { 
945
          MetaCatUtil.debugMessage("current node type from xml is WHITESPACE TEXT", 40);
946
          MetaCatUtil.debugMessage("node type from stack: " + 
947
                                    node.getNodeType(), 40);
948
          MetaCatUtil.debugMessage("current node data from xml is: " + 
949
                                    data, 40);
950
          MetaCatUtil.debugMessage("node data from stack: " +
951
                                    node.getNodeData(), 40);
952
          MetaCatUtil.debugMessage("node is from stack: " + 
953
                                        node.getNodeId(), 40);
954
          throw new SAXException(PERMISSIONERROR);
955
        }//if
956
       }//if
957
       // Write the content of the node to the database
958
       endNodeId = currentNode.writeChildNodeToDB("TEXT", null, data, docid);
959
     }
960
     
961
     
962
   
963
   }
964
   
965
   /** SAX Handler that receives notification of end of the document */
966
   public void endDocument() throws SAXException 
967
   {
968
     MetaCatUtil.debugMessage("end Document", 50);
969
     // There are some unchangable subtree didn't be compare
970
     // This maybe cause user change the subtree id
971
     if (!unChangableSubTreeHash.isEmpty())
972
     {
973
       MetaCatUtil.debugMessage("The unChangealbe subtree is not empty", 40);
974
       throw new SAXException(PERMISSIONERROR);
975
     }
976
     
977
     // write access rule to db
978
     writeAccessRuleToDB();
979
   
980
     // Starting new thread for writing XML Index.
981
     // It calls the run method of the thread.
982
     try 
983
     {
984
       xmlIndex.start();
985
     } 
986
     catch (NullPointerException e) 
987
     {
988
       xmlIndex = null;
989
       throw new
990
       SAXException("Problem with starting thread for writing XML Index. " +
991
                    e.getMessage());
992
     }
993
   
994
   }
995
   
996
  /* The method to write all access rule intodb */
997
  private void writeAccessRuleToDB() throws SAXException
998
  {
999
    //Delete old permssion
1000
    deletePermissionsInAccessTable(docid);
1001
    //write top leve access rule
1002
    writeTopLevelAccessRuleToDB();
1003
    //write additional access rule
1004
    writeAddtionalAccessRuleToDB();
1005
  }//writeAccessRuleToDB
1006
   
1007
  /* The method to write top level access rule into db. */
1008
  private void writeTopLevelAccessRuleToDB() throws SAXException
1009
  {
1010
    
1011
    // for top document level
1012
    Object accessSection = topLevelAccessControlMap.get(docid);
1013
    boolean top = true;
1014
    String subSectionId = null;
1015
    if ( accessSection != null )
1016
    {
1017
       AccessSection accessSectionObj = (AccessSection)accessSection;
1018
       // if accessSection is not null and is not reference
1019
       if ( accessSectionObj.getReferences() == null)
1020
       {
1021
          writeGivenAccessRuleIntoDB(accessSectionObj, top, subSectionId);
1022
       }
1023
       else
1024
       {
1025
   
1026
        // this is a reference and go trough the vector which contains all
1027
        // access object
1028
        String referenceId = accessSectionObj.getReferences();
1029
        boolean findAccessObject = false;
1030
        MetaCatUtil.debugMessage("referered id for top access: "+ 
1031
                               referenceId, 35);
1032
        for (int i=0; i<accessObjectList.size(); i++)
1033
        {
1034
          AccessSection accessObj = (AccessSection)accessObjectList.elementAt(i);
1035
          String accessObjId = accessObj.getAccessSectionId();
1036
          if (referenceId != null && accessObj != null &&
1037
              referenceId.equals(accessObjId))
1038
          {
1039
            writeGivenAccessRuleIntoDB(accessObj, top, subSectionId);
1040
            findAccessObject = true;
1041
          }
1042
        }//for
1043
        // if we couldn't find an access subtree id for this reference id
1044
        if (!findAccessObject)
1045
        {
1046
          throw new SAXException("The referenceid: " + referenceId +
1047
                               " is not access subtree");
1048
        }//if
1049
      }//else
1050
      
1051
    }//if
1052
    else
1053
    {
1054
      // couldn't find a access section object 
1055
      MetaCatUtil.debugMessage("couldn't find access control for document: "+
1056
                                docid, 35);
1057
    }
1058
    
1059
  }//writeTopLevelAccessRuletoDB
1060
   
1061
   /* The method to write addtional access rule into db. */
1062
  private void writeAddtionalAccessRuleToDB() throws SAXException
1063
  {
1064
    
1065
     PreparedStatement pstmt = null;
1066
     boolean topLevel =false;
1067
    // go through the vector which contains the additional access control 
1068
    //hashtable. Each hashtable has info for one additonalmetadata container 
1069
   for (int j= 0; j < additionalAccessMapList.size(); j++)
1070
   {
1071
     
1072
     Hashtable accessControlMap = 
1073
                                (Hashtable)additionalAccessMapList.elementAt(j);
1074
     // additional access rule
1075
     Enumeration en = accessControlMap.keys();
1076
     
1077
     while(en.hasMoreElements())
1078
     {
1079
       try
1080
       {
1081
         // Get subsection id
1082
          String subSectionId = (String)en.nextElement();
1083
          MetaCatUtil.debugMessage("sub section id in additional access mapping"
1084
                                   +"(go through): "+ subSectionId, 35);
1085
          
1086
          if (subSectionId == null)
1087
          {
1088
            // if id is null, terminate the program
1089
            throw new SAXException("subtree id is null");
1090
          }
1091
          // Get AccessSection Object
1092
          Object accessSectionObj = accessControlMap.get(subSectionId);
1093
          if (accessSectionObj == null)
1094
          {
1095
            // if accesssection is null, terminate the program
1096
            throw new SAXException("access subtree is null");
1097
          }
1098
          else
1099
          {
1100
            AccessSection accessControlObj = (AccessSection)accessSectionObj;
1101
            // if the access section is not references, write it to db
1102
            if (accessControlObj.getReferences() == null)
1103
            {
1104
              writeGivenAccessRuleIntoDB(accessControlObj, topLevel, 
1105
                                         subSectionId);
1106
            }
1107
            else
1108
            {
1109
              // this is a reference and go trough the vector which contains all
1110
              // access object
1111
              String referenceId = accessControlObj.getReferences();
1112
            
1113
              boolean findAccessObject = false;
1114
              MetaCatUtil.debugMessage("referered id for additional access "+
1115
                                     "mapping(go through): "+ referenceId, 35);
1116
              for (int i=0; i<accessObjectList.size(); i++)
1117
              {
1118
                AccessSection accessObj = 
1119
                                (AccessSection)accessObjectList.elementAt(i);
1120
                String accessObjId = accessObj.getAccessSectionId();
1121
                MetaCatUtil.debugMessage("access obj id in the list(go through): "
1122
                                        + accessObjId, 35);
1123
                if (referenceId != null && accessObj != null &&
1124
                    referenceId.equals(accessObjId))
1125
                {
1126
                  writeGivenAccessRuleIntoDB(accessObj, topLevel, subSectionId);
1127
                  findAccessObject = true;
1128
                }//if
1129
              }//for
1130
              // if we couldn't find an access subtree id for this reference id
1131
              if (!findAccessObject)
1132
              {
1133
                throw new SAXException("The referenceid: " + referenceId +
1134
                               " is not access subtree");
1135
              }//if
1136
            }//else
1137
          }//else
1138
       }//try
1139
       catch (Exception e)
1140
       {
1141
         
1142
         MetaCatUtil.debugMessage("error in EmlSAXHandler.writeAddtionalAccess"
1143
                                   + ": "+e.getMessage(), 30);
1144
         throw new SAXException(e.getMessage());
1145
       }
1146
     }//while
1147
    }//for
1148
  }//writeAccessRuletoDB
1149
  
1150
  /* Write a gaven access rule into db*/
1151
  private void writeGivenAccessRuleIntoDB(AccessSection accessSection, 
1152
                                         boolean topLevel, String subSectionId) 
1153
                                         throws SAXException
1154
  {
1155
     if (accessSection == null)
1156
     {
1157
       throw new SAXException("The access object is null");
1158
     }
1159
     
1160
      String permOrder = accessSection.getPermissionOrder();
1161
      String sql = null;
1162
      PreparedStatement pstmt = null;
1163
      if (topLevel)
1164
      {
1165
        sql = "INSERT INTO xml_access (docid, principal_name, permission, "+
1166
                 "perm_type, perm_order, accessfileid) VALUES " +
1167
                 " (?, ?, ?, ?, ?, ?)";
1168
      }
1169
      else
1170
      {
1171
        sql ="INSERT INTO xml_access (docid,principal_name, "+ 
1172
             "permission, perm_type, perm_order, accessfileid, subtreeid, "+
1173
             " startnodeid, endnodeid) VALUES" +
1174
             " (?, ?, ?, ?, ?, ?, ?, ?, ?)";
1175
      }
1176
      try 
1177
      {
1178
     
1179
        pstmt = connection.prepareStatement(sql);
1180
        // Increase DBConnection usage count
1181
        connection.increaseUsageCount(1);
1182
        // Bind the values to the query
1183
        pstmt.setString(1, docid);
1184
        MetaCatUtil.debugMessage("Docid in accesstable: "+ docid, 35);
1185
        pstmt.setString(6, docid);
1186
        MetaCatUtil.debugMessage("Accessfileid in accesstable: "+ docid, 35);
1187
        pstmt.setString(5, permOrder);
1188
        MetaCatUtil.debugMessage("PermOder in accesstable: "+ permOrder, 35);
1189
        // if it is not top level, set subsection id
1190
        if (!topLevel)
1191
        {
1192
          long startNodeId = 0;
1193
          long endNodeId = 0;
1194
          // for subtree should specify the
1195
          if (subSectionId == null)
1196
          {
1197
            throw new SAXException("The subsection is null");
1198
          }
1199
          // go through the substree list vector and found the start node id
1200
          // and stop node id for this subtree id
1201
          for (int i=0; i<subTreeList.size(); i++)
1202
          {
1203
            SubTree tree = (SubTree)subTreeList.elementAt(i);
1204
            String subTreeId = tree.getSubTreeId();
1205
            if (subSectionId.equals(subTreeId))
1206
            {
1207
              startNodeId = tree.getStartNodeId();
1208
              endNodeId = tree.getEndNodeId(); 
1209
            }//if
1210
          }//for
1211
          if (startNodeId == 0 || endNodeId == 0)
1212
          {
1213
            throw new SAXException("Could find the subtree"
1214
                                   + "for this id: "+subSectionId);
1215
          }
1216
          pstmt.setString(7, subSectionId);
1217
          MetaCatUtil.debugMessage("SubSectionId in accesstable: "+ 
1218
                                    subSectionId, 35);
1219
          pstmt.setLong(8, startNodeId);
1220
          MetaCatUtil.debugMessage("Start node id is: " + startNodeId, 35);
1221
          pstmt.setLong(9, endNodeId);
1222
          MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
1223
          
1224
        }
1225
      
1226
        Vector accessRules = accessSection.getAccessRules();
1227
        // go through every rule
1228
        for (int i=0; i<accessRules.size(); i++)
1229
        {
1230
          AccessRule rule = (AccessRule)accessRules.elementAt(i);
1231
          String permType = rule.getPermissionType();
1232
          int permission = rule.getPermission();
1233
          pstmt.setInt(3, permission);
1234
          MetaCatUtil.debugMessage("permission in accesstable: "+ permission, 35);
1235
          pstmt.setString(4, permType);
1236
          MetaCatUtil.debugMessage("Permtype in accesstable: "+ permType, 35);
1237
          // go through every principle in rule
1238
          Vector nameVector = rule.getPrincipal();
1239
          for ( int j = 0; j < nameVector.size(); j++ ) 
1240
          {
1241
            String prName = (String)nameVector.elementAt(j);
1242
            pstmt.setString(2, prName);
1243
            MetaCatUtil.debugMessage("Principal in accesstable: "+prName, 35);
1244
            pstmt.execute();
1245
          }//for
1246
        }//for
1247
        pstmt.close();
1248
      }//try 
1249
      catch (SQLException e) 
1250
      {
1251
        throw new 
1252
        SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + e.getMessage());
1253
      }//catch
1254
      finally
1255
      {
1256
        try
1257
        {
1258
          pstmt.close();
1259
        }
1260
        catch(SQLException ee)
1261
        {
1262
          throw new 
1263
          SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + 
1264
          ee.getMessage());
1265
        }
1266
      }//finally
1267
     
1268
  }//writeGivenAccessRuleIntoDB
1269
  
1270
  /* Delete from db all permission for resources related to @aclid if any.*/
1271
  private void deletePermissionsInAccessTable(String aclid) 
1272
          throws SAXException 
1273
  {
1274
    Statement stmt = null;
1275
    try
1276
    {
1277
      // delete all acl records for resources related to @aclid if any
1278
      stmt = connection.createStatement();
1279
      // Increase DBConnection usage count
1280
      connection.increaseUsageCount(1);
1281
      stmt.execute("DELETE FROM xml_access WHERE accessfileid = '" + aclid +
1282
                   "'"); 
1283
    
1284
    }
1285
    catch (SQLException e)
1286
    {
1287
      throw new SAXException(e.getMessage());
1288
    }
1289
    finally
1290
    {
1291
      try
1292
      {
1293
        stmt.close();
1294
      }
1295
      catch (SQLException ee)
1296
      {
1297
        throw new SAXException(ee.getMessage());
1298
      }
1299
    }
1300
  }//deletePermissionsInAccessTable
1301
  
1302
  // write inline data into file system and return file name(without path)
1303
  private StringBuffer writeInlineDataIntoFile(StringBuffer data) 
1304
                                               throws SAXException
1305
  {
1306
    StringBuffer fileNameBuffer = null;
1307
    String fileName = null;
1308
    String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
1309
    String path = MetaCatUtil.getOption("inlinedatafilepath");
1310
    String seperator = MetaCatUtil.getOption("accNumSeparator");
1311
    // the new file name will look like path/docid.rev.2
1312
    fileName = docidWithoutRev + seperator+revision+seperator +inLineDataIndex;
1313
    File inlineDataDirectory = new File(path);
1314
    File newFile = new File(inlineDataDirectory, fileName); 
1315
    // incease inLinedataindex for next one
1316
    inLineDataIndex++ ;
1317
    try
1318
    {
1319
      FileWriter writer = new FileWriter(newFile);
1320
      writer.write(data.toString());
1321
      writer.close();
1322
    }
1323
    catch (Exception e)
1324
    {
1325
      throw new SAXException(e.getMessage());
1326
    }
1327
    
1328
    fileNameBuffer = new StringBuffer(fileName);
1329
    return fileNameBuffer;
1330
  }
1331
  
1332
  /* In eml2, the inline data wouldn't store in db, it store in file system
1333
   * The db stores file name(without path).
1334
   */
1335
  public static String readInlineDataFromFileSystem(String fileName) 
1336
                                              throws McdbException
1337
  {
1338
    String data = null;
1339
    String path = MetaCatUtil.getOption("inlinedatafilepath");
1340
    // the new file name will look like path/docid.rev.2
1341
    File inlineDataDirectory = new File(path);
1342
    File dataFile = new File(inlineDataDirectory, fileName);
1343
    try
1344
    {
1345
      FileReader fileReader = new FileReader(dataFile);
1346
      BufferedReader stringReader = new BufferedReader(fileReader);
1347
      // read first line of data
1348
      String tmp = stringReader.readLine();
1349
      // pass first line data to data varible
1350
      data = tmp;
1351
      // at the end tmp will be null
1352
      while (tmp != null)
1353
      {
1354
        // read a new line
1355
        tmp = stringReader.readLine();
1356
        // append new line to data
1357
        if (tmp != null)
1358
        {
1359
          data = data+tmp;
1360
        }
1361
      }
1362
      
1363
    }
1364
    catch (Exception e)
1365
    {
1366
      throw new McdbException(e.getMessage());
1367
    }
1368
    MetaCatUtil.debugMessage("the inline data retrieve from file: "+data, 50);
1369
    return data;
1370
  }
1371
}
(33-33/56)