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-03-18 14:14:15 -0800 (Tue, 18 Mar 2003) $'
12
 * '$Revision: 1481 $'
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.File;
33
import java.io.FileWriter;
34
import java.io.StringReader;
35
import java.util.Stack;
36
import java.util.Vector;
37
import java.util.Hashtable;
38
import java.util.Enumeration;
39
import java.util.EmptyStackException;
40

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

    
48
/**
49
 * A database aware Class implementing callback bethods for the SAX parser to
50
 * call when processing the XML stream and generating events
51
 */
52
public class EmlSAXHandler extends DBSAXHandler implements 
53
                                                      AccessControlInterface
54
{
55
   private Vector allowRules = new Vector();
56
   private Vector denyRules = new Vector();
57
   private String documentId = null;
58
   private Vector subDocumentIdList = new Vector();
59
   private boolean processTopLeverAccess = false;
60
   private boolean processAdditionalAccess = false;
61
   private AccessSection accessObject= null;
62
   private AccessRule accessRule = null;
63
   private Vector accessObjectList = new Vector(); // store every access rule
64
   private Hashtable topLevelAccessControlMap = new Hashtable();
65
   private Hashtable additionalAccessControlMap = new Hashtable();// store 
66
                                                 //subtree access for single
67
                                                 // additionalmetacat
68
   private Vector additionalAccessMapList = new Vector();// store maps for 
69
                                                       // every addionalmetadata
70
   private Vector describesId = new Vector(); // store the ids in
71
                                      //additionalmetadata/describes
72
   private Stack subTreeInfoStack = new Stack();
73
   private Vector subTreeList = new Vector();// store the final subtree
74
   private int inLineDataIndex = 1;
75
 
76
 
77
   // Constant
78
   private static final String DESCRIBES = "describes";
79
   private static final String ADDITIONALMETADATA = "additionalMetadata";
80
   private static final String ORDER = "order";
81
   private static final String ID ="id";
82
   private static final String REFERENCES = "references";
83
   public  static final String INLINE = "inline";
84
      
85
  
86
    /** Construct an instance of the handler class
87
    * In this constructor, user can specify the version need to upadate
88
    *
89
    * @param conn the JDBC connection to which information is written
90
    * @param action - "INSERT" or "UPDATE"
91
    * @param docid to be inserted or updated into JDBC connection
92
    * @param revision, the user specified the revision need to be update
93
    * @param user the user connected to MetaCat servlet and owns the document
94
    * @param groups the groups to which user belongs
95
    * @param pub flag for public "read" access on document
96
    * @param serverCode the serverid from xml_replication on which this document
97
    *        resides.
98
    *
99
    */
100
   public EmlSAXHandler(DBConnection conn, String action, String docid,
101
     String revision, String user, String[] groups, String pub, int serverCode)
102
   {
103
     super(conn, action, docid, revision, user, groups, pub, serverCode);
104
   }
105
   
106
   /** SAX Handler that is called at the start of each XML element */
107
   public void startElement(String uri, String localName,
108
                            String qName, Attributes atts)
109
               throws SAXException 
110
  {
111
      // for element <eml:eml...> qname is "eml:eml", local name is "eml"            
112
     // for element <acl....> both qname and local name is "eml"
113
     // uri is namesapce
114
     MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
115
     MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
116
     MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
117
     
118
     
119
     DBSAXNode parentNode = null;
120
     DBSAXNode currentNode = null;
121

    
122
     // Get a reference to the parent node for the id
123
     try 
124
     {
125
       parentNode = (DBSAXNode)nodeStack.peek();
126
     } 
127
     catch (EmptyStackException e) 
128
     {
129
       parentNode = null;
130
     }
131
     
132
     // If hit a text node, we need write this text for current's parent node
133
     // This will happend if the element is mixted
134
     if (hitTextNode && parentNode != null)
135
     {
136
       // write the textbuffer into db for parent node.
137
        endNodeId = writeTextForDBSAXNode(textBuffer, parentNode);
138
        // rest hitTextNode
139
        hitTextNode =false;
140
        // reset textbuffer
141
        textBuffer = null;
142
        textBuffer = new StringBuffer();
143
       
144
     }
145
     
146
  
147
     // Document representation that points to the root document node
148
     if (atFirstElement) 
149
     {
150
       atFirstElement = false;
151
       // If no DOCTYPE declaration: docname = root element
152
       // doctype = root element name or name space
153
       if (docname == null) 
154
       {
155
         docname = localName;
156
         // if uri isn't null doctype = uri(namespace)
157
         // othewise root element
158
         if (uri != null && !(uri.trim()).equals(""))
159
         {
160
           doctype = uri;
161
         }
162
         else
163
         {
164
           doctype = docname;
165
         }
166
         MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
167
         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
168
       } 
169
       else if (doctype == null) 
170
       {
171
         // because docname is not null and it is declared in dtd
172
         // so could not be in schema, no namespace
173
         doctype = docname;
174
         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
175
       }
176
       rootNode.writeNodename(docname);
177
       try 
178
       {
179
         // for validated XML Documents store a reference to XML DB Catalog
180
         // Because this is select statement and it needn't to roll back if
181
         // insert document action fialed.
182
         // In order to decrease DBConnection usage count, we get a new
183
         // dbconnection from pool
184
         String catalogid = null;
185
         DBConnection dbConn = null;
186
         int serialNumber = -1;
187

    
188
         if ( systemid != null ) 
189
         {
190
           try
191
           {
192
            // Get dbconnection
193
            dbConn=DBConnectionPool.getDBConnection
194
                                          ("DBSAXHandler.startElement");
195
            serialNumber=dbConn.getCheckOutSerialNumber();
196

    
197
            Statement stmt = dbConn.createStatement();
198
            ResultSet rs = stmt.executeQuery(
199
                          "SELECT catalog_id FROM xml_catalog " +
200
                          "WHERE entry_type = 'DTD' " +
201
                          "AND public_id = '" + doctype + "'");
202
            boolean hasRow = rs.next();
203
            if ( hasRow ) {
204
              catalogid = rs.getString(1);
205
            }
206
            stmt.close();
207
           }//try
208
           finally
209
           {
210
             // Return dbconnection
211
             DBConnectionPool.returnDBConnection(dbConn, serialNumber);
212
           }//finally
213
         }
214

    
215
         //create documentImpl object by the constructor which can specify
216
         //the revision
217
         currentDocument = new DocumentImpl(connection, rootNode.getNodeID(),
218
                               docname, doctype, docid, revision, action, user,
219
                               this.pub, catalogid, this.serverCode);
220

    
221

    
222
       } 
223
       catch (Exception ane) 
224
       {
225
         throw (new SAXException("Error in DBSaxHandler.startElement " +
226
                                 action, ane));
227
       }
228
     }
229

    
230
     // Create the current node representation
231
     currentNode = new DBSAXNode(connection, qName, localName, parentNode,
232
                                 currentDocument.getRootNodeID(),docid,
233
                                 currentDocument.getDoctype());
234
     // Use a local variable to store the element node id
235
     // If this element is a start point of subtree(section), it will be stored
236
     // otherwise, it will be discated
237
     long startNodeId = currentNode.getNodeID();
238
     // Add all of the namespaces
239
     String prefix;
240
     String nsuri;
241
     Enumeration prefixes = namespaces.keys();
242
     while ( prefixes.hasMoreElements() ) 
243
     {
244
       prefix = (String)prefixes.nextElement();
245
       nsuri = (String)namespaces.get(prefix);
246
       endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
247
     }
248
     namespaces = null;
249
     namespaces = new Hashtable();
250

    
251
     // Add all of the attributes
252
     for (int i=0; i<atts.getLength(); i++) 
253
     {
254
       String attributeName = atts.getQName(i);
255
       String attributeValue = atts.getValue(i);
256
       endNodeId = 
257
                currentNode.setAttribute(attributeName, attributeValue, docid);
258
       
259
       // To handle name space and schema location if the attribute name is
260
       // xsi:schemaLocation. If the name space is in not in catalog table
261
       // it will be regeistered.
262
       if (attributeName != null && 
263
           attributeName.indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1)
264
       {
265
         SchemaLocationResolver resolver = 
266
                                  new SchemaLocationResolver(attributeValue);
267
         resolver.resolveNameSpace();
268
         
269
       }
270
       else if (attributeName !=null && attributeName.equals(ID))
271
       {
272
         // handle subtree info
273
         SubTree subTress = new SubTree();
274
         // set sub tree id
275
         subTress.setSubTreeId(attributeValue);
276
         // set sub tree sstart lement name
277
         subTress.setStartElementName(currentNode.getTagName());
278
         // set start node number
279
         subTress.setStartNodeId(startNodeId);
280
         // add to stack, but it didn't get end node id yet
281
         subTreeInfoStack.push(subTress);
282
         
283
       }
284
     }
285
   
286
     // handle access stuff
287
     if (localName.equals(ACCESS))
288
     {
289
       // if it is in addtionalmetacat
290
       if (parentNode.getTagName() == ADDITIONALMETADATA)
291
       {
292
         processAdditionalAccess = true;
293
        
294
       }
295
       else
296
       {
297
         processTopLeverAccess = true;
298
        
299
       }
300
       // create access object 
301
        accessObject = new AccessSection();
302
         // set permission order
303
       String permOrder = currentNode.getAttribute(ORDER);
304
       accessObject.setPermissionOrder(permOrder);
305
       // set access id
306
       String accessId = currentNode.getAttribute(ID);
307
       accessObject.setAccessSectionId(accessId);
308
       
309
     }
310
     // Set up a access rule for allow
311
     else if (parentNode.getTagName() != null && 
312
       (parentNode.getTagName()).equals(ACCESS) && localName.equals(ALLOW))
313
     {
314
      
315
       accessRule = new AccessRule(); 
316
      
317
       //set permission type "allow"
318
       accessRule.setPermissionType(ALLOW);
319
      
320
     }
321
     // set up an access rule for den
322
     else if (parentNode.getTagName() != null 
323
       && (parentNode.getTagName()).equals(ACCESS) && localName.equals(DENY))
324
     {
325
       accessRule = new AccessRule();
326
       //set permission type "allow"
327
       accessRule.setPermissionType(DENY);
328
     }
329
      
330
     // Add the node to the stack, so that any text data can be
331
     // added as it is encountered
332
     nodeStack.push(currentNode);
333
     // Add the node to the vector used by thread for writing XML Index
334
     nodeIndex.addElement(currentNode);
335
    
336

    
337
  }
338
  
339
   
340
  /** SAX Handler that is called at the end of each XML element */
341
   public void endElement(String uri, String localName,
342
                          String qName) throws SAXException 
343
  {
344
     MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
345

    
346
     // Get the node from the stack
347
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
348
     String currentTag = currentNode.getTagName();
349
     
350
    
351
     // If before the end element, the parser hit text nodes and store them
352
     // into the buffer, write the buffer to data base. The reason we put
353
     // write database here is for xerces some time split text node
354
     if (hitTextNode)
355
     {
356
        // get access value
357
        String data = null;
358
        // add principal
359
       if (currentTag.equals(PRINCIPAL) && accessRule != null) 
360
       {
361
          data = (textBuffer.toString()).trim();
362
          accessRule.addPrincipal(data);
363

    
364
       } 
365
       else if (currentTag.equals(PERMISSION) && accessRule != null) 
366
       {
367
         data = (textBuffer.toString()).trim();
368
         // we conbine different a permission into one value
369
         int permission = accessRule.getPermission();
370
         // add permision
371
         if ( data.toUpperCase().equals(READSTRING) ) 
372
         {
373
           permission = permission | READ;
374
         } 
375
         else if ( data.toUpperCase().equals(WRITESTRING) ) 
376
         {
377
           permission = permission | WRITE;
378
         } 
379
         else if ( data.toUpperCase().equals(CHMODSTRING)) 
380
         {
381
           permission = permission | CHMOD;
382
         } 
383
         else if ( data.toUpperCase().equals(ALLSTRING) ) 
384
         {
385
          permission = permission | ALL;
386
         }
387
         accessRule.setPermission(permission);
388
       }
389
       // put additionalmetadata/describes into vector
390
       else if (currentTag.equals(DESCRIBES))
391
       {
392
          data = (textBuffer.toString()).trim();
393
          describesId.add(data);
394
       }
395
       else if (currentTag.equals(REFERENCES) && 
396
               (processTopLeverAccess||processAdditionalAccess))
397
       {
398
         // get reference 
399
         data = (textBuffer.toString()).trim();
400
         // put reference id into accessSection
401
         accessObject.setReferences(data);
402
         
403
       }
404
       // write text to db if it is not inline data
405
       if (!localName.equals(INLINE))
406
       {
407
          MetaCatUtil.debugMessage("Write text into DB in End Element", 50);
408
          endNodeId = writeTextForDBSAXNode(textBuffer, currentNode);
409
       }
410
       else
411
       {
412
          MetaCatUtil.debugMessage("Write inline data into file system", 35);
413
          // write inline data into file system and return file name
414
          textBuffer = writeInlineDataIntoFile(textBuffer);
415
          // write file name into db
416
          endNodeId = writeTextForDBSAXNode(textBuffer, currentNode);
417
       }
418
     }//if
419
     
420
     //set hitText false
421
     hitTextNode = false;
422
     // reset textbuff
423
     textBuffer = null;
424
     textBuffer = new StringBuffer();
425
     
426
     // hand sub stree stuff
427
     if (!subTreeInfoStack.empty())
428
     {
429
       SubTree tree = (SubTree)subTreeInfoStack.peek();// get last subtree
430
       if (tree != null && tree.getStartElementName() != null && 
431
         (tree.getStartElementName()).equals(currentTag))
432
       {
433
         // find the end of sub tree and set the end node id
434
         tree.setEndNodeId(endNodeId);
435
         // add the subtree into the final store palace
436
         subTreeList.add(tree);
437
         // get rid of it from stack
438
         subTreeInfoStack.pop();
439
       }//if
440
     }//if
441

    
442
     // access stuff
443
     if (currentTag.equals(ALLOW) || currentTag.equals(DENY))
444
     {
445
       // finish parser a ccess rule and  assign it to new one
446
       AccessRule newRule = accessRule;
447
       //add the new rule to access section object
448
       accessObject.addAccessRule(newRule);
449
       // reset access rule
450
       accessRule = null;
451
     }
452
     else if (currentTag.equals(ACCESS))
453
     {
454
       // finish parse a access setction and assign it to new one
455
       AccessSection newAccessObject = accessObject;
456
       if (newAccessObject != null)
457
       {
458
        // add the accessSection into a vector to store it
459
        // if it is not a reference, need to store it
460
        if ( newAccessObject.getReferences() == null)
461
        {
462
          accessObjectList.add(newAccessObject);
463
        }
464
        if (processTopLeverAccess)
465
        {
466
          // top level access control will handle whole document -docid
467
          topLevelAccessControlMap.put(docid, newAccessObject);
468
          // reset processtopleveraccess tag
469
          
470
        }//if
471
        else if (processAdditionalAccess)
472
        {
473
          // for additional control
474
          // put everything in describes value and access object into hash
475
       
476
          for ( int i=0; i<describesId.size(); i++)
477
          {
478
           
479
            String subId = (String)describesId.elementAt(i);
480
            if (subId != null)
481
            {
482
              additionalAccessControlMap.put(subId, newAccessObject);
483
            }//if
484
          }//for
485
          // add this hashtable in to vector
486
         
487
          additionalAccessMapList.add(additionalAccessControlMap);
488
          // reset this hashtable in order to store another additional 
489
          //accesscontrol
490
          additionalAccessControlMap = null;
491
          additionalAccessControlMap = new Hashtable();
492
        }//if
493
       }//if
494
       //reset access section object
495
       accessObject = null;
496
       // reset flag
497
       processAdditionalAccess =false;
498
       processTopLeverAccess =false;
499
     }
500
     else if (currentTag.equals(ADDITIONALMETADATA))
501
     {
502
        //reset describesId
503
        describesId = null;
504
        describesId = new Vector();
505
     }
506
   }
507
   
508
   /** SAX Handler that receives notification of end of the document */
509
   public void endDocument() throws SAXException 
510
   {
511
     MetaCatUtil.debugMessage("end Document", 50);
512
     // write access rule to db
513
     writeAccessRuleToDB();
514
     // Starting new thread for writing XML Index.
515
     // It calls the run method of the thread.
516
     try 
517
     {
518
       xmlIndex.start();
519
     } 
520
     catch (NullPointerException e) 
521
     {
522
       xmlIndex = null;
523
       throw new
524
       SAXException("Problem with starting thread for writing XML Index. " +
525
                    e.getMessage());
526
     }
527
   }
528
   
529
  /* The method to write all access rule intodb */
530
  private void writeAccessRuleToDB() throws SAXException
531
  {
532
    //Delete old permssion
533
    deletePermissionsInAccessTable(docid);
534
    //write top leve access rule
535
    writeTopLevelAccessRuleToDB();
536
    //write additional access rule
537
    writeAddtionalAccessRuleToDB();
538
  }//writeAccessRuleToDB
539
   
540
  /* The method to write top level access rule into db. */
541
  private void writeTopLevelAccessRuleToDB() throws SAXException
542
  {
543
    
544
    // for top document level
545
    Object accessSection = topLevelAccessControlMap.get(docid);
546
    boolean top = true;
547
    String subSectionId = null;
548
    if ( accessSection != null )
549
    {
550
       AccessSection accessSectionObj = (AccessSection)accessSection;
551
       // if accessSection is not null and is not reference
552
       if ( accessSectionObj.getReferences() == null)
553
       {
554
          writeGivenAccessRuleIntoDB(accessSectionObj, top, subSectionId);
555
       }
556
       else
557
       {
558
   
559
        // this is a reference and go trough the vector which contains all
560
        // access object
561
        String referenceId = accessSectionObj.getReferences();
562
        boolean findAccessObject = false;
563
        MetaCatUtil.debugMessage("referered id for top access: "+ 
564
                               referenceId, 35);
565
        for (int i=0; i<accessObjectList.size(); i++)
566
        {
567
          AccessSection accessObj = (AccessSection)accessObjectList.elementAt(i);
568
          String accessObjId = accessObj.getAccessSectionId();
569
          if (referenceId != null && accessObj != null &&
570
              referenceId.equals(accessObjId))
571
          {
572
            writeGivenAccessRuleIntoDB(accessObj, top, subSectionId);
573
            findAccessObject = true;
574
          }
575
        }//for
576
        // if we couldn't find an access subtree id for this reference id
577
        if (!findAccessObject)
578
        {
579
          throw new SAXException("The referenceid: " + referenceId +
580
                               " is not access subtree");
581
        }//if
582
      }//else
583
      
584
    }//if
585
    else
586
    {
587
      // couldn't find a access section object 
588
      MetaCatUtil.debugMessage("couldn't find access control for document: "+
589
                                docid, 35);
590
    }
591
    
592
  }//writeTopLevelAccessRuletoDB
593
   
594
   /* The method to write addtional access rule into db. */
595
  private void writeAddtionalAccessRuleToDB() throws SAXException
596
  {
597
    
598
     PreparedStatement pstmt = null;
599
     boolean topLevel =false;
600
    // go through the vector which contains the additional access control 
601
    //hashtable. Each hashtable has info for one additonalmetadata container 
602
   for (int j= 0; j < additionalAccessMapList.size(); j++)
603
   {
604
     
605
     Hashtable accessControlMap = 
606
                                (Hashtable)additionalAccessMapList.elementAt(j);
607
     // additional access rule
608
     Enumeration en = accessControlMap.keys();
609
     
610
     while(en.hasMoreElements())
611
     {
612
       try
613
       {
614
         // Get subsection id
615
          String subSectionId = (String)en.nextElement();
616
          MetaCatUtil.debugMessage("sub section id in additional access mapping"
617
                                   +"(go through): "+ subSectionId, 35);
618
          
619
          if (subSectionId == null)
620
          {
621
            // if id is null, terminate the program
622
            throw new SAXException("subtree id is null");
623
          }
624
          // Get AccessSection Object
625
          Object accessSectionObj = accessControlMap.get(subSectionId);
626
          if (accessSectionObj == null)
627
          {
628
            // if accesssection is null, terminate the program
629
            throw new SAXException("access subtree is null");
630
          }
631
          else
632
          {
633
            AccessSection accessControlObj = (AccessSection)accessSectionObj;
634
            // if the access section is not references, write it to db
635
            if (accessControlObj.getReferences() == null)
636
            {
637
              writeGivenAccessRuleIntoDB(accessControlObj, topLevel, 
638
                                         subSectionId);
639
            }
640
            else
641
            {
642
              // this is a reference and go trough the vector which contains all
643
              // access object
644
              String referenceId = accessControlObj.getReferences();
645
            
646
              boolean findAccessObject = false;
647
              MetaCatUtil.debugMessage("referered id for additional access "+
648
                                     "mapping(go through): "+ referenceId, 35);
649
              for (int i=0; i<accessObjectList.size(); i++)
650
              {
651
                AccessSection accessObj = 
652
                                (AccessSection)accessObjectList.elementAt(i);
653
                String accessObjId = accessObj.getAccessSectionId();
654
                MetaCatUtil.debugMessage("access obj id in the list(go through): "
655
                                        + accessObjId, 35);
656
                if (referenceId != null && accessObj != null &&
657
                    referenceId.equals(accessObjId))
658
                {
659
                  writeGivenAccessRuleIntoDB(accessObj, topLevel, subSectionId);
660
                  findAccessObject = true;
661
                }//if
662
              }//for
663
              // if we couldn't find an access subtree id for this reference id
664
              if (!findAccessObject)
665
              {
666
                throw new SAXException("The referenceid: " + referenceId +
667
                               " is not access subtree");
668
              }//if
669
            }//else
670
          }//else
671
       }//try
672
       catch (Exception e)
673
       {
674
         
675
         MetaCatUtil.debugMessage("error in EmlSAXHandler.writeAddtionalAccess"
676
                                   + ": "+e.getMessage(), 30);
677
         throw new SAXException(e.getMessage());
678
       }
679
     }//while
680
    }//for
681
  }//writeAccessRuletoDB
682
  
683
  /* Write a gaven access rule into db*/
684
  private void writeGivenAccessRuleIntoDB(AccessSection accessSection, 
685
                                         boolean topLevel, String subSectionId) 
686
                                         throws SAXException
687
  {
688
     if (accessSection == null)
689
     {
690
       throw new SAXException("The access object is null");
691
     }
692
     
693
      String permOrder = accessSection.getPermissionOrder();
694
      String sql = null;
695
      PreparedStatement pstmt = null;
696
      if (topLevel)
697
      {
698
        sql = "INSERT INTO xml_access (docid, principal_name, permission, "+
699
                 "perm_type, perm_order, accessfileid) VALUES " +
700
                 " (?, ?, ?, ?, ?, ?)";
701
      }
702
      else
703
      {
704
        sql ="INSERT INTO xml_access (docid,principal_name, "+ 
705
             "permission, perm_type, perm_order, accessfileid, subtreeid, "+
706
             " startnodeid, endnodeid) VALUES" +
707
             " (?, ?, ?, ?, ?, ?, ?, ?, ?)";
708
      }
709
      try 
710
      {
711
     
712
        pstmt = connection.prepareStatement(sql);
713
        // Increase DBConnection usage count
714
        connection.increaseUsageCount(1);
715
        // Bind the values to the query
716
        pstmt.setString(1, docid);
717
        MetaCatUtil.debugMessage("Docid in accesstable: "+ docid, 35);
718
        pstmt.setString(6, docid);
719
        MetaCatUtil.debugMessage("Accessfileid in accesstable: "+ docid, 35);
720
        pstmt.setString(5, permOrder);
721
        MetaCatUtil.debugMessage("PermOder in accesstable: "+ permOrder, 35);
722
        // if it is not top level, set subsection id
723
        if (!topLevel)
724
        {
725
          long startNodeId = 0;
726
          long endNodeId = 0;
727
          // for subtree should specify the
728
          if (subSectionId == null)
729
          {
730
            throw new SAXException("The subsection is null");
731
          }
732
          // go through the substree list vector and found the start node id
733
          // and stop node id for this subtree id
734
          for (int i=0; i<subTreeList.size(); i++)
735
          {
736
            SubTree tree = (SubTree)subTreeList.elementAt(i);
737
            String subTreeId = tree.getSubTreeId();
738
            if (subSectionId.equals(subTreeId))
739
            {
740
              startNodeId = tree.getStartNodeId();
741
              endNodeId = tree.getEndNodeId(); 
742
            }//if
743
          }//for
744
          if (startNodeId == 0 || endNodeId == 0)
745
          {
746
            throw new SAXException("Could find the subtree"
747
                                   + "for this id: "+subSectionId);
748
          }
749
          pstmt.setString(7, subSectionId);
750
          MetaCatUtil.debugMessage("SubSectionId in accesstable: "+ 
751
                                    subSectionId, 35);
752
          pstmt.setLong(8, startNodeId);
753
          MetaCatUtil.debugMessage("Start node id is: " + startNodeId, 35);
754
          pstmt.setLong(9, endNodeId);
755
          MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
756
          
757
        }
758
      
759
        Vector accessRules = accessSection.getAccessRules();
760
        // go through every rule
761
        for (int i=0; i<accessRules.size(); i++)
762
        {
763
          AccessRule rule = (AccessRule)accessRules.elementAt(i);
764
          String permType = rule.getPermissionType();
765
          int permission = rule.getPermission();
766
          pstmt.setInt(3, permission);
767
          MetaCatUtil.debugMessage("permission in accesstable: "+ permission, 35);
768
          pstmt.setString(4, permType);
769
          MetaCatUtil.debugMessage("Permtype in accesstable: "+ permType, 35);
770
          // go through every principle in rule
771
          Vector nameVector = rule.getPrincipal();
772
          for ( int j = 0; j < nameVector.size(); j++ ) 
773
          {
774
            String prName = (String)nameVector.elementAt(j);
775
            pstmt.setString(2, prName);
776
            MetaCatUtil.debugMessage("Principal in accesstable: "+prName, 35);
777
            pstmt.execute();
778
          }//for
779
        }//for
780
        pstmt.close();
781
      }//try 
782
      catch (SQLException e) 
783
      {
784
        throw new 
785
        SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + e.getMessage());
786
      }//catch
787
      finally
788
      {
789
        try
790
        {
791
          pstmt.close();
792
        }
793
        catch(SQLException ee)
794
        {
795
          throw new 
796
          SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + 
797
          ee.getMessage());
798
        }
799
      }//finally
800
     
801
  }//writeGivenAccessRuleIntoDB
802
  
803
  /* Delete from db all permission for resources related to @aclid if any.*/
804
  private void deletePermissionsInAccessTable(String aclid) 
805
          throws SAXException 
806
  {
807
    Statement stmt = null;
808
    try
809
    {
810
      // delete all acl records for resources related to @aclid if any
811
      stmt = connection.createStatement();
812
      // Increase DBConnection usage count
813
      connection.increaseUsageCount(1);
814
      stmt.execute("DELETE FROM xml_access WHERE accessfileid = '" + aclid +
815
                   "'"); 
816
    
817
    }
818
    catch (SQLException e)
819
    {
820
      throw new SAXException(e.getMessage());
821
    }
822
    finally
823
    {
824
      try
825
      {
826
        stmt.close();
827
      }
828
      catch (SQLException ee)
829
      {
830
        throw new SAXException(ee.getMessage());
831
      }
832
    }
833
  }//deletePermissionsInAccessTable
834
  
835
  // write inline data into file system and return file name(without path)
836
  private StringBuffer writeInlineDataIntoFile(StringBuffer data) 
837
                                               throws SAXException
838
  {
839
    StringBuffer fileNameBuffer = null;
840
    String fileName = null;
841
    String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
842
    String path = MetaCatUtil.getOption("inlinedatafilepath");
843
    String seperator = MetaCatUtil.getOption("accNumSeparator");
844
    // the new file name will look like path/docid.rev.2
845
    fileName = docidWithoutRev + seperator+revision+seperator +inLineDataIndex;
846
    File inlineDataDirectory = new File(path);
847
    File newFile = new File(inlineDataDirectory, fileName); 
848
    // incease inLinedataindex for next one
849
    inLineDataIndex++ ;
850
    try
851
    {
852
      FileWriter writer = new FileWriter(newFile);
853
      writer.write(data.toString());
854
      writer.close();
855
    }
856
    catch (Exception e)
857
    {
858
      throw new SAXException(e.getMessage());
859
    }
860
    
861
    fileNameBuffer = new StringBuffer(fileName);
862
    return fileNameBuffer;
863
  }
864
 
865
}
(32-32/54)