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 17:45:21 -0700 (Wed, 09 Apr 2003) $'
12
 * '$Revision: 1537 $'
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
       accessObject.setAccessSectionStartNodeId(startNodeId);
436
       
437
     }
438
     // Set up a access rule for allow
439
     else if (parentNode.getTagName() != null && 
440
       (parentNode.getTagName()).equals(ACCESS) && localName.equals(ALLOW))
441
     {
442
      
443
       accessRule = new AccessRule(); 
444
      
445
       //set permission type "allow"
446
       accessRule.setPermissionType(ALLOW);
447
      
448
     }
449
     // set up an access rule for den
450
     else if (parentNode.getTagName() != null 
451
       && (parentNode.getTagName()).equals(ACCESS) && localName.equals(DENY))
452
     {
453
       accessRule = new AccessRule();
454
       //set permission type "allow"
455
       accessRule.setPermissionType(DENY);
456
     }
457
      
458
     // Add the node to the stack, so that any text data can be
459
     // added as it is encountered
460
     nodeStack.push(currentNode);
461
     // Add the node to the vector used by thread for writing XML Index
462
     nodeIndex.addElement(currentNode);
463
    
464
    // handle critical subtree
465
    if (startCriticalSubTree && firstElementForCriticalSubTree)
466
    {
467
      //store the element name
468
      firstElementNameForCriticalSubTree = qName;
469
      firstElementForCriticalSubTree = false;
470
    }//for first element
471
    // handle critical subtree
472
    if (startCriticalSubTree)
473
    {
474
      //Get element subtree node stack (element node)
475
      NodeRecord elementNode = null;
476
      try
477
      {
478
        elementNode= (NodeRecord) currentUnChangedableSubtreeNodeStack.pop();
479
      }
480
      catch (EmptyStackException ee)
481
      {
482
        MetaCatUtil.debugMessage("Node stack is empty for element data", 35);
483
        throw new SAXException(PERMISSIONERROR);
484
      }
485
      MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
486
      MetaCatUtil.debugMessage("node type from stack: " + 
487
                                  elementNode.getNodeType(), 40);
488
      MetaCatUtil.debugMessage("node name from xml document: " + 
489
                                  localName, 40);
490
      MetaCatUtil.debugMessage("node name from stack: " +
491
                                  elementNode.getNodeName(), 40);
492
      MetaCatUtil.debugMessage("node data from stack: " +
493
                                  elementNode.getNodeData(), 40);
494
      MetaCatUtil.debugMessage("node is: "+ elementNode.getNodeId(), 40);
495
      // if this node is not element or local name not equal or name space not
496
      // equals, throw an exception
497
      if (!elementNode.getNodeType().equals("ELEMENT") || 
498
          !localName.equals(elementNode.getNodeName()))
499
        //  (uri != null && !uri.equals(elementNode.getNodePrefix())))
500
      {
501
        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
502
        MetaCatUtil.debugMessage("node type from stack: " + 
503
                                  elementNode.getNodeType(), 40);
504
        MetaCatUtil.debugMessage("node name from xml document: " + 
505
                                  localName, 40);
506
        MetaCatUtil.debugMessage("node name from stack: " +
507
                                  elementNode.getNodeName(), 40);
508
        MetaCatUtil.debugMessage("node data from stack: " +
509
                                  elementNode.getNodeData(), 40);
510
        MetaCatUtil.debugMessage("node is: "+ elementNode.getNodeId(), 40);
511
        throw new SAXException(PERMISSIONERROR);
512
      }
513
      
514
      //compare namespace
515
     Enumeration nameEn = namespaces.keys();
516
     while ( nameEn.hasMoreElements() ) 
517
     {
518
       //Get namespacke node stack (element node)
519
       NodeRecord nameNode = null;
520
       try
521
       { 
522
         nameNode = (NodeRecord) currentUnChangedableSubtreeNodeStack.pop();
523
       }
524
       catch (EmptyStackException ee)
525
       {
526
         MetaCatUtil.debugMessage("Node stack is empty for namespace data", 35);
527
         throw new SAXException(PERMISSIONERROR);
528
       }
529
       
530
       String prefixName = (String)nameEn.nextElement(); 
531
       String nameSpaceUri = (String)namespaces.get(prefixName);
532
       if (!nameNode.getNodeType().equals("NAMESPACE") || 
533
           !prefixName.equals(nameNode.getNodeName()) || 
534
           !nameSpaceUri.equals(nameNode.getNodeData()))
535
       { 
536
         MetaCatUtil.debugMessage("current node type from xml is NAMESPACE", 40);
537
         MetaCatUtil.debugMessage("node type from stack: " + 
538
                                  nameNode.getNodeType(), 40);
539
         MetaCatUtil.debugMessage("current node name from xml is: " + 
540
                                   prefixName, 40);
541
         MetaCatUtil.debugMessage("node name from stack: " +
542
                                  nameNode.getNodeName(), 40);
543
         MetaCatUtil.debugMessage("current node data from xml is: " + 
544
                                   nameSpaceUri, 40);
545
         MetaCatUtil.debugMessage("node data from stack: " +
546
                                  nameNode.getNodeData(), 40);
547
         MetaCatUtil.debugMessage("node is: "+ nameNode.getNodeId(), 40);
548
         throw new SAXException(PERMISSIONERROR);
549
       }
550
      
551
     }//while
552
      
553
      //compare attributes
554
      for (int i=0; i<atts.getLength(); i++)
555
      {
556
        NodeRecord attriNode = null;
557
        try
558
        {
559
          attriNode = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
560
          
561
        }
562
        catch (EmptyStackException ee)
563
        {
564
          MetaCatUtil.debugMessage("Node stack is empty for attribute data", 35);
565
          throw new SAXException(PERMISSIONERROR);
566
        }
567
        String attributeName = atts.getQName(i);
568
        String attributeValue = atts.getValue(i);
569
        MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
570
        MetaCatUtil.debugMessage("node type from stack: " + 
571
                                   attriNode.getNodeType(), 40);
572
        MetaCatUtil.debugMessage("current node name from xml is: " + 
573
                                    attributeName, 40);
574
        MetaCatUtil.debugMessage("node name from stack: " +
575
                                    attriNode.getNodeName(), 40);
576
        MetaCatUtil.debugMessage("current node data from xml is: " + 
577
                                    attributeValue, 40);
578
        MetaCatUtil.debugMessage("node data from stack: " +
579
                                    attriNode.getNodeData(), 40);
580
        MetaCatUtil.debugMessage("node is: "+ attriNode.getNodeId(), 40);
581
        
582
        if (!attriNode.getNodeType().equals("ATTRIBUTE") || 
583
            !attributeName.equals(attriNode.getNodeName()) ||
584
            !attributeValue.equals(attriNode.getNodeData()))
585
        {
586
          MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
587
          MetaCatUtil.debugMessage("node type from stack: " + 
588
                                   attriNode.getNodeType(), 40);
589
          MetaCatUtil.debugMessage("current node name from xml is: " + 
590
                                    attributeName, 40);
591
          MetaCatUtil.debugMessage("node name from stack: " +
592
                                    attriNode.getNodeName(), 40);
593
          MetaCatUtil.debugMessage("current node data from xml is: " + 
594
                                    attributeValue, 40);
595
          MetaCatUtil.debugMessage("node data from stack: " +
596
                                    attriNode.getNodeData(), 40);
597
          MetaCatUtil.debugMessage("node is: "+ attriNode.getNodeId(), 40);
598
          throw new SAXException(PERMISSIONERROR);
599
        }
600
      }//for
601
      
602
    }
603
    // reset name space
604
    namespaces = null;
605
    namespaces = new Hashtable();
606
  }
607
  
608
   
609
  /** SAX Handler that is called at the end of each XML element */
610
   public void endElement(String uri, String localName,
611
                          String qName) throws SAXException 
612
  {
613
     MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
614

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

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

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

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

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