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

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

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

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

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

    
319

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

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

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

    
614
     // Get the node from the stack
615
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
616
     String currentTag = currentNode.getTagName();
617
    
618
     // If before the end element, the parser hit text nodes and store them
619
     // into the buffer, write the buffer to data base. The reason we put
620
     // write database here is for xerces some time split text node
621
     if (hitTextNode)
622
     {
623
        // get access value
624
        String data = null;
625
        // add principal
626
       if (currentTag.equals(PRINCIPAL) && accessRule != null) 
627
       {
628
          data = (textBuffer.toString()).trim();
629
          accessRule.addPrincipal(data);
630

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

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

    
930
     // This loop deals with the case where there are more characters
931
     // than can fit in a single database text field (limit is
932
     // MAXDATACHARS).  If the text to be inserted exceeds MAXDATACHARS,
933
     // write a series of nodes that are MAXDATACHARS long, and then the
934
     // final node contains the remainder
935
     while (moredata) 
936
     {
937
       if (leftover > MAXDATACHARS) 
938
       {
939
         data = new String(cbuf, offset, MAXDATACHARS);
940
         leftover -= MAXDATACHARS;
941
         offset += MAXDATACHARS;
942
       } 
943
       else 
944
       {
945
         data = new String(cbuf, offset, leftover);
946
         moredata = false;
947
       }
948

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