Project

General

Profile

« Previous | Next » 

Revision 2077

Added by Matt Jones over 20 years ago

Reformatted source for readability and conformance.

View differences:

src/edu/ucsb/nceas/metacat/EmlSAXHandler.java
51 51
 * A database aware Class implementing callback bethods for the SAX parser to
52 52
 * call when processing the XML stream and generating events
53 53
 */
54
public class EmlSAXHandler extends DBSAXHandler implements 
55
                                                      AccessControlInterface
54
public class EmlSAXHandler extends DBSAXHandler implements
55
        AccessControlInterface
56 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 Hashtable unChangableSubTreeHash = new Hashtable();
78
   private Stack currentUnChangedableSubtreeNodeStack =new Stack();
79
   private boolean startCriticalSubTree = false;
80
   private boolean firstElementForCriticalSubTree = false;
81
   private String firstElementNameForCriticalSubTree;
82
   private boolean needCheckingAccessModule = false;
83
   private Vector unChangableAccessSubTreeVector = new Vector();
84
   private Stack currentUnchangableAccessModuleNodeStack = new Stack();
85
   private AccessSection topAccessSection;
86
   
87
   // we need an another stack to store the access node which we pull out just
88
   // from xml. If a reference happend, we can use the stack the compare nodes
89
   private Stack storedAccessNodeStack = new Stack();
90
   // vector stored the data file id which will be write into relation table
91
   private Vector onlineDataFileIdVector = new Vector();
92
   // Indicator of inline data
93
   private boolean handleInlineData = false;
94
   private Stack   inlineDataNodeStack = null;
95
   private Hashtable inlineDataNameSpace = null;
96
   private FileWriter inlineDataFileWriter = null;
97
   private String inlineDataFileName = null;
98
   private int inLineDataIndex = 0;
99
   private Vector inlineFileIDList = new Vector();
100
 
101
   // Constant
102
   private static final String EML ="eml";
103
   private static final String DESCRIBES = "describes";
104
   private static final String ADDITIONALMETADATA = "additionalMetadata";
105
   private static final String ORDER = "order";
106
   private static final String ID ="id";
107
   private static final String REFERENCES = "references";
108
   public  static final String INLINE = "inline";
109
   private static final String ONLINE = "online";
110
   private static final String URL    = "url";
111
   private static final String PERMISSIONERROR ="User try to update a subtree"+
112
                               " which it doesn't have write permission!";
113
   private static final String UPDATEACCESSERROR = "User try to update a " + 
114
                      "access module which it doesn't have \"ALL\" permission!";
115
   private static final String TOPLEVEL = "top";
116
   private static final String SUBTREELEVEL ="subtree";
117
   private static final String RELATION = "Provides info for";
118
  
119
    /** Construct an instance of the handler class
120
    * In this constructor, user can specify the version need to upadate
121
    *
122
    * @param conn the JDBC connection to which information is written
123
    * @param action - "INSERT" or "UPDATE"
124
    * @param docid to be inserted or updated into JDBC connection
125
    * @param revision, the user specified the revision need to be update
126
    * @param user the user connected to MetaCat servlet and owns the document
127
    * @param groups the groups to which user belongs
128
    * @param pub flag for public "read" access on document
129
    * @param serverCode the serverid from xml_replication on which this document
130
    *        resides.
131
    *
132
    */
133
   public EmlSAXHandler(DBConnection conn, String action, String docid,
134
     String revision, String user, String[] groups, String pub, int serverCode)
135
                              throws SAXException
136
   {
137
     super(conn, action, docid, revision, user, groups, pub, serverCode);
138
     // Get the unchangable subtrees (user doesn't have write permission)
139
     try
140
     {
141
       PermissionController control = new PermissionController(docid+
142
                             MetaCatUtil.getOption("accNumSeparator")+revision);
143
       //unChangableSubTreeHash = getUnchangableSubTree(control, user, groups);
144
       
145
       
146
       //If the action is update and user doesn't have "ALL" permission
147
       // we need to check if user update access subtree
148
       if (action.equals("UPDATE") && 
149
         !control.hasPermission(user, groups, AccessControlInterface.ALLSTRING))
150
       {
151
         needCheckingAccessModule = true;
152
         unChangableAccessSubTreeVector = getAccessSubTreeListFromDB();
153
       }
154
     }
155
     catch (Exception e)
156
     {
157
       throw new SAXException(e.getMessage());
158
     }
159
   }
160
   
161
   /* Pass a permission control and get the list of unchangable subtree*/
162
   private Hashtable getUnchangableSubTree(PermissionController controller,
163
                                           String user, String[]groups)
164
                                           throws Exception
165
   {
166
     Hashtable list = null;
167
     Hashtable result = new Hashtable();
168
     // get unwritable sutree from controller
169
     list = controller.hasUnaccessableSubTree(user, groups, 
170
                                          AccessControlInterface.WRITESTRING);
171
      if (list != null)
172
      {
173
       
174
         Enumeration en = list.elements();
175
         while (en.hasMoreElements())
176
         {
177
           // Get  a subtree without node record list
178
           SubTree treeWithoutStack = (SubTree)en.nextElement();
179
           String subTreeId   = treeWithoutStack.getSubTreeId();
180
           MetaCatUtil.debugMessage("unchangable subtree id: " + subTreeId, 40);
181
           long   startNodeId = treeWithoutStack.getStartNodeId();
182
           MetaCatUtil.debugMessage("unchangable subtree startnodeid: " +
183
                                    startNodeId, 40);
184
           long   endNodeId   = treeWithoutStack.getEndNodeId();
185
           MetaCatUtil.debugMessage("unchangable subtree endnodeid: " +
186
                                     endNodeId, 40);
187
           // Get a subtree has the nodelist
188
           SubTree tree = new SubTree(docid, subTreeId, startNodeId, endNodeId);
189
           // add this tree to the result
190
           result.put(subTreeId, tree);
191
         
192
          }//while
193
      
194
      }//if
195
      
196
      return result;
197
   }
198
   
199
   
200
   /*
201
    * Get the subtree node info from xml_accesssubtree table
202
    */
203
   private Vector getAccessSubTreeListFromDB() throws Exception
204
   {
205
      Vector result = new Vector();
206
      PreparedStatement pstmt = null;
207
      ResultSet rs = null;
208
      String sql = "SELECT controllevel, subtreeid, startnodeid, endnodeid " + 
209
                   "FROM xml_accesssubtree WHERE docid like ? " +
210
                   "ORDER BY startnodeid ASC";
211
              
212
      try 
213
      {
214
     
215
        pstmt = connection.prepareStatement(sql);
216
        // Increase DBConnection usage count
217
        connection.increaseUsageCount(1);
218
        // Bind the values to the query
219
        pstmt.setString(1, docid);
220
        pstmt.execute();
221
        
222
        // Get result set
223
        rs = pstmt.getResultSet();
224
        while (rs.next())
225
        {
226
          String level = rs.getString(1);
227
          String sectionId = rs.getString(2);
228
          long startNodeId = rs.getLong(3);
229
          long endNodeId = rs.getLong(4);
230
          // create a new access section
231
          AccessSection accessObj = new AccessSection();
232
          accessObj.setControlLevel(level);
233
          accessObj.setDocId(docid);
234
          accessObj.setSubTreeId(sectionId);
235
          accessObj.setStartNodeId(startNodeId);
236
          accessObj.setEndNodeId(endNodeId); 
237
          Stack nodeStack = accessObj.getSubTreeNodeList();
238
          accessObj.setSubTreeNodeStack(nodeStack);
239
          // add this access obj into vector
240
          result.add(accessObj);
241
          // Get the top level access subtree control
242
          if ( level != null && level.equals(TOPLEVEL))
243
          {
244
            topAccessSection = accessObj;
245
          }
246
        }
247
        pstmt.close();
248
      }//try 
249
      catch (SQLException e) 
250
      {
251
        throw new 
252
        SAXException("EMLSAXHandler.getAccessSubTreeListFromDB(): " + 
253
                      e.getMessage());
254
      }//catch
255
      finally
256
      {
257
        try
258
        {
259
          pstmt.close();
260
        }
261
        catch(SQLException ee)
262
        {
263
          throw new 
264
          SAXException("EMLSAXHandler.getAccessSubTreeListFromDB(): " + 
265
          ee.getMessage());
266
        }
267
      }//finally
268
      return result;
269
   }
270
   /** SAX Handler that is called at the start of each XML element */
271
   public void startElement(String uri, String localName,
272
                            String qName, Attributes atts)
273
               throws SAXException 
274
  {
275
    // for element <eml:eml...> qname is "eml:eml", local name is "eml"            
276
    // for element <acl....> both qname and local name is "eml"
277
    // uri is namesapce
278
    MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
279
    MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
280
    MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
281
     
282
     
283
    DBSAXNode parentNode = null;
284
    DBSAXNode currentNode = null;
285
   
286
   if (!handleInlineData)
287
   {
288
     // Get a reference to the parent node for the id
289
     try 
290
     {
291
       parentNode = (DBSAXNode)nodeStack.peek();
292
     } 
293
     catch (EmptyStackException e) 
294
     {
295
       parentNode = null;
296
     }
297
     
298
     //start handle inline data
299
     if (localName.equals(INLINE))
300
     {
301
       handleInlineData = true;
302
       inLineDataIndex ++;
303
       //intitialize namespace hash for in line data
304
       inlineDataNameSpace = new Hashtable();
305
       //initialize file writer
306
       String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
307
       String seperator = MetaCatUtil.getOption("accNumSeparator");
308
       // the new file name will look like docid.rev.2
309
       inlineDataFileName = docidWithoutRev + seperator+revision+seperator +
310
                         inLineDataIndex;
311
       inlineDataFileWriter = createInlineDataFileWriter(inlineDataFileName);
312
       // put the inline file id into a vector. If upload failed, metacat will
313
       // delete the inline data file
314
       inlineFileIDList.add(inlineDataFileName);
315
       
316
     }
317
     
318
     
319
     // If hit a text node, we need write this text for current's parent node
320
     // This will happend if the element is mixted
321
     if (hitTextNode && parentNode != null)
322
     {
323
       //compare text node data for unchangesubtree
324
       if (startCriticalSubTree)
325
       {
326
         compareTextNode(currentUnChangedableSubtreeNodeStack, textBuffer, 
327
                         PERMISSIONERROR);
328
       }//if
329
      
330
       //compare top level access module
331
       if (processTopLeverAccess && needCheckingAccessModule)
332
       {
333
          compareTextNode(currentUnchangableAccessModuleNodeStack, 
334
                          textBuffer, UPDATEACCESSERROR);
335
       }
336
       
337
       if (needCheckingAccessModule && 
338
       (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
339
       {
340
        // stored the pull out nodes into storedNode stack
341
        NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT", 
342
                      null, null, MetaCatUtil.normalize(textBuffer.toString()));
343
        storedAccessNodeStack.push(nodeElement);
344
                                         
345
      }
346
        
347
       // write the textbuffer into db for parent node.
348
        endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, parentNode);
349
        // rest hitTextNode
350
        hitTextNode =false;
351
        // reset textbuffer
352
        textBuffer = null;
353
        textBuffer = new StringBuffer();
354
       
355
     }
356
     
357
  
358
     // Document representation that points to the root document node
359
     if (atFirstElement) 
360
     {
361
       atFirstElement = false;
362
       // If no DOCTYPE declaration: docname = root element
363
       // doctype = root element name or name space
364
       if (docname == null) 
365
       {
366
         docname = localName;
367
         // if uri isn't null doctype = uri(namespace)
368
         // othewise root element
369
         if (uri != null && !(uri.trim()).equals(""))
370
         {
371
           doctype = uri;
372
         }
373
         else
374
         {
375
           doctype = docname;
376
         }
377
         MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
378
         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
379
       } 
380
       else if (doctype == null) 
381
       {
382
         // because docname is not null and it is declared in dtd
383
         // so could not be in schema, no namespace
384
         doctype = docname;
385
         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
386
       }
387
       rootNode.writeNodename(docname);
388
       try 
389
       {
390
         // for validated XML Documents store a reference to XML DB Catalog
391
         // Because this is select statement and it needn't to roll back if
392
         // insert document action fialed.
393
         // In order to decrease DBConnection usage count, we get a new
394
         // dbconnection from pool
395
         String catalogid = null;
396
         DBConnection dbConn = null;
397
         int serialNumber = -1;
398 57

  
399
        
400
         try
401
         {
402
            // Get dbconnection
403
            dbConn=DBConnectionPool.getDBConnection
404
                                          ("DBSAXHandler.startElement");
405
            serialNumber=dbConn.getCheckOutSerialNumber();
58
    private Vector allowRules = new Vector();
406 59

  
407
            Statement stmt = dbConn.createStatement();
408
            ResultSet rs = stmt.executeQuery(
409
                          "SELECT catalog_id FROM xml_catalog " +
410
                          "WHERE entry_type = 'Schema' " +
411
                          "AND public_id = '" + doctype + "'");
412
            boolean hasRow = rs.next();
413
            if ( hasRow ) 
414
            {
415
              catalogid = rs.getString(1);
416
            }
417
            stmt.close();
418
         }//try
419
         finally
420
         {
421
             // Return dbconnection
422
             DBConnectionPool.returnDBConnection(dbConn, serialNumber);
423
         }//finally
424
       
60
    private Vector denyRules = new Vector();
425 61

  
426
         //create documentImpl object by the constructor which can specify
427
         //the revision
428
         currentDocument = new DocumentImpl(connection, rootNode.getNodeID(),
429
                               docname, doctype, docid, revision, action, user,
430
                               this.pub, catalogid, this.serverCode);
62
    private String documentId = null;
431 63

  
64
    private Vector subDocumentIdList = new Vector();
432 65

  
433
       } 
434
       catch (Exception ane) 
435
       {
436
         throw (new SAXException("Error in EMLSaxHandler.startElement " +
437
                                 action, ane));
438
       }
439
     }
66
    private boolean processTopLeverAccess = false;
440 67

  
441
     // Create the current node representation
442
     currentNode = new DBSAXNode(connection, qName, localName, parentNode,
443
                                 currentDocument.getRootNodeID(),docid,
444
                                 currentDocument.getDoctype());
445
     // Use a local variable to store the element node id
446
     // If this element is a start point of subtree(section), it will be stored
447
     // otherwise, it will be discated
448
     long startNodeId = currentNode.getNodeID();
449
     // Add all of the namespaces
450
     String prefix =null;
451
     String nsuri = null;
452
     Enumeration prefixes = namespaces.keys();
453
     while ( prefixes.hasMoreElements() ) 
454
     {
455
       prefix = (String)prefixes.nextElement();
456
       nsuri = (String)namespaces.get(prefix);
457
       endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
458
     }
459
   
68
    private boolean processAdditionalAccess = false;
460 69

  
461
     // Add all of the attributes
462
     for (int i=0; i<atts.getLength(); i++) 
463
     {
464
       String attributeName = atts.getQName(i);
465
       String attributeValue = atts.getValue(i);
466
       endNodeId = 
467
                currentNode.setAttribute(attributeName, attributeValue, docid);
468
       
469
       // To handle name space and schema location if the attribute name is
470
       // xsi:schemaLocation. If the name space is in not in catalog table
471
       // it will be regeistered.
472
       if (attributeName != null && 
473
           attributeName.indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1)
474
       {
475
         SchemaLocationResolver resolver = 
476
                                  new SchemaLocationResolver(attributeValue);
477
         resolver.resolveNameSpace();
478
         
479
       }
480
       else if (attributeName !=null && attributeName.equals(ID))
481
       {
482
        
483
        
484
         //check unchangedable subtree hash if contains this subtree id
485
         if (unChangableSubTreeHash.containsKey(attributeValue))
486
         {
487
           // this subtree couldn't be changed by the user and move it from hash
488
           SubTree currentUnChangedableSubtree = (SubTree)
489
                                  unChangableSubTreeHash.remove(attributeValue);
490
           currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree.
491
                                                         getSubTreeNodeStack();
492
           startCriticalSubTree = true;
493
           firstElementForCriticalSubTree = true;
494
         }
495
         
496
         // handle subtree info
497
         SubTree subTress = new SubTree();
498
         // set sub tree id
499
         subTress.setSubTreeId(attributeValue);
500
         // set sub tree sstart lement name
501
         subTress.setStartElementName(currentNode.getTagName());
502
         // set start node number
503
         subTress.setStartNodeId(startNodeId);
504
         // add to stack, but it didn't get end node id yet
505
         subTreeInfoStack.push(subTress);
506
         
507
       }
508
     }//for
509
   
510
     // handle access stuff
511
     if (localName.equals(ACCESS))
512
     {
513
       // if it is in addtionalmetacat
514
       if (parentNode.getTagName() == ADDITIONALMETADATA)
515
       {
516
         processAdditionalAccess = true;
517
        
518
       }
519
       else
520
       {
521
         //make sure the access is top level
522
         // this mean current node's parent's parent should be "eml"
523
         DBSAXNode tmpNode = (DBSAXNode) nodeStack.pop();// pop out parent node
524
         //peek out grandParentNode
525
         DBSAXNode grandParentNode = (DBSAXNode)nodeStack.peek();
526
         // put parent node back
527
         nodeStack.push(tmpNode);
528
         String grandParentTag = grandParentNode.getTagName();
529
         if (grandParentTag.equals(EML))
530
         {
531
           processTopLeverAccess = true;
532
         }
533
         else
534
         {
535
           // process other access embedded into resource level module
536
           processOtherAccess = true;
537
         }
538
        
539
       }
540
       // create access object 
541
       accessObject = new AccessSection();
542
         // set permission order
543
       String permOrder = currentNode.getAttribute(ORDER);
544
       accessObject.setPermissionOrder(permOrder);
545
       // set access id
546
       String accessId = currentNode.getAttribute(ID);
547
       accessObject.setSubTreeId(accessId);
548
       accessObject.setStartNodeId(startNodeId);
549
       accessObject.setDocId(docid);
550
       
551
       // load top level node stack to currentUnchangableAccessModuleNodeStack
552
       if (processTopLeverAccess && needCheckingAccessModule)
553
       {
554
         // get the node stack for
555
         currentUnchangableAccessModuleNodeStack = 
556
                                        topAccessSection.getSubTreeNodeStack();
557
       }
558
                 
559
       
560
     }
561
     // Set up a access rule for allow
562
     else if (parentNode.getTagName() != null && 
563
       (parentNode.getTagName()).equals(ACCESS) && localName.equals(ALLOW))
564
     {
565
      
566
       accessRule = new AccessRule(); 
567
      
568
       //set permission type "allow"
569
       accessRule.setPermissionType(ALLOW);
570
      
571
     }
572
     // set up an access rule for den
573
     else if (parentNode.getTagName() != null 
574
       && (parentNode.getTagName()).equals(ACCESS) && localName.equals(DENY))
575
     {
576
       accessRule = new AccessRule();
577
       //set permission type "allow"
578
       accessRule.setPermissionType(DENY);
579
     }
580
      
581
     // Add the node to the stack, so that any text data can be
582
     // added as it is encountered
583
     nodeStack.push(currentNode);
584
     // Add the node to the vector used by thread for writing XML Index
585
     nodeIndex.addElement(currentNode);
586
    
587
    // handle critical subtree
588
    if (startCriticalSubTree && firstElementForCriticalSubTree)
70
    private boolean processOtherAccess = false;
71

  
72
    private AccessSection accessObject = null;
73

  
74
    private AccessRule accessRule = null;
75

  
76
    private Vector accessObjectList = new Vector(); // store every access rule
77

  
78
    private Hashtable topLevelAccessControlMap = new Hashtable();
79

  
80
    private Hashtable additionalAccessControlMap = new Hashtable();// store
81

  
82
    //subtree access for single
83
    // additionalmetacat
84
    private Vector additionalAccessMapList = new Vector();// store maps for
85

  
86
    // every addionalmetadata
87
    private Vector describesId = new Vector(); // store the ids in
88

  
89
    //additionalmetadata/describes
90
    private Stack subTreeInfoStack = new Stack();
91

  
92
    private Vector subTreeList = new Vector();// store the final subtree
93

  
94
    private Hashtable unChangableSubTreeHash = new Hashtable();
95

  
96
    private Stack currentUnChangedableSubtreeNodeStack = new Stack();
97

  
98
    private boolean startCriticalSubTree = false;
99

  
100
    private boolean firstElementForCriticalSubTree = false;
101

  
102
    private String firstElementNameForCriticalSubTree;
103

  
104
    private boolean needCheckingAccessModule = false;
105

  
106
    private Vector unChangableAccessSubTreeVector = new Vector();
107

  
108
    private Stack currentUnchangableAccessModuleNodeStack = new Stack();
109

  
110
    private AccessSection topAccessSection;
111

  
112
    // we need an another stack to store the access node which we pull out just
113
    // from xml. If a reference happend, we can use the stack the compare nodes
114
    private Stack storedAccessNodeStack = new Stack();
115

  
116
    // vector stored the data file id which will be write into relation table
117
    private Vector onlineDataFileIdVector = new Vector();
118

  
119
    // Indicator of inline data
120
    private boolean handleInlineData = false;
121

  
122
    private Stack inlineDataNodeStack = null;
123

  
124
    private Hashtable inlineDataNameSpace = null;
125

  
126
    private FileWriter inlineDataFileWriter = null;
127

  
128
    private String inlineDataFileName = null;
129

  
130
    private int inLineDataIndex = 0;
131

  
132
    private Vector inlineFileIDList = new Vector();
133

  
134
    // Constant
135
    private static final String EML = "eml";
136

  
137
    private static final String DESCRIBES = "describes";
138

  
139
    private static final String ADDITIONALMETADATA = "additionalMetadata";
140

  
141
    private static final String ORDER = "order";
142

  
143
    private static final String ID = "id";
144

  
145
    private static final String REFERENCES = "references";
146

  
147
    public static final String INLINE = "inline";
148

  
149
    private static final String ONLINE = "online";
150

  
151
    private static final String URL = "url";
152

  
153
    private static final String PERMISSIONERROR = "User try to update a subtree"
154
            + " which it doesn't have write permission!";
155

  
156
    private static final String UPDATEACCESSERROR = "User try to update a "
157
            + "access module which it doesn't have \"ALL\" permission!";
158

  
159
    private static final String TOPLEVEL = "top";
160

  
161
    private static final String SUBTREELEVEL = "subtree";
162

  
163
    private static final String RELATION = "Provides info for";
164

  
165
    /**
166
     * Construct an instance of the handler class In this constructor, user can
167
     * specify the version need to upadate
168
     * 
169
     * @param conn the JDBC connection to which information is written
170
     * @param action - "INSERT" or "UPDATE"
171
     * @param docid to be inserted or updated into JDBC connection
172
     * @param revision, the user specified the revision need to be update
173
     * @param user the user connected to MetaCat servlet and owns the document
174
     * @param groups the groups to which user belongs
175
     * @param pub flag for public "read" access on document
176
     * @param serverCode the serverid from xml_replication on which this
177
     *            document resides.
178
     *  
179
     */
180
    public EmlSAXHandler(DBConnection conn, String action, String docid,
181
            String revision, String user, String[] groups, String pub,
182
            int serverCode) throws SAXException
589 183
    {
590
      //store the element name
591
      firstElementNameForCriticalSubTree = qName;
592
      firstElementForCriticalSubTree = false;
593
    }//for first element
594
    
595
    // handle critical subtree
596
    if (startCriticalSubTree)
184
        super(conn, action, docid, revision, user, groups, pub, serverCode);
185
        // Get the unchangable subtrees (user doesn't have write permission)
186
        try {
187
            PermissionController control = new PermissionController(docid
188
                    + MetaCatUtil.getOption("accNumSeparator") + revision);
189
            //unChangableSubTreeHash = getUnchangableSubTree(control, user,
190
            // groups);
191

  
192
            //If the action is update and user doesn't have "ALL" permission
193
            // we need to check if user update access subtree
194
            if (action.equals("UPDATE")
195
                    && !control.hasPermission(user, groups,
196
                            AccessControlInterface.ALLSTRING)) {
197
                needCheckingAccessModule = true;
198
                unChangableAccessSubTreeVector = getAccessSubTreeListFromDB();
199
            }
200
        } catch (Exception e) {
201
            throw new SAXException(e.getMessage());
202
        }
203
    }
204

  
205
    /* Pass a permission control and get the list of unchangable subtree */
206
    private Hashtable getUnchangableSubTree(PermissionController controller,
207
            String user, String[] groups) throws Exception
597 208
    {
598
      compareElementNameSpaceAttributes(currentUnChangedableSubtreeNodeStack,
599
                                        namespaces, atts, localName, 
600
                                        PERMISSIONERROR);
601
      
209
        Hashtable list = null;
210
        Hashtable result = new Hashtable();
211
        // get unwritable sutree from controller
212
        list = controller.hasUnaccessableSubTree(user, groups,
213
                AccessControlInterface.WRITESTRING);
214
        if (list != null) {
215

  
216
            Enumeration en = list.elements();
217
            while (en.hasMoreElements()) {
218
                // Get a subtree without node record list
219
                SubTree treeWithoutStack = (SubTree) en.nextElement();
220
                String subTreeId = treeWithoutStack.getSubTreeId();
221
                MetaCatUtil.debugMessage(
222
                        "unchangable subtree id: " + subTreeId, 40);
223
                long startNodeId = treeWithoutStack.getStartNodeId();
224
                MetaCatUtil.debugMessage("unchangable subtree startnodeid: "
225
                        + startNodeId, 40);
226
                long endNodeId = treeWithoutStack.getEndNodeId();
227
                MetaCatUtil.debugMessage("unchangable subtree endnodeid: "
228
                        + endNodeId, 40);
229
                // Get a subtree has the nodelist
230
                SubTree tree = new SubTree(docid, subTreeId, startNodeId,
231
                        endNodeId);
232
                // add this tree to the result
233
                result.put(subTreeId, tree);
234

  
235
            }//while
236

  
237
        }//if
238

  
239
        return result;
602 240
    }
603
    //compare top access level module
604
    if (processTopLeverAccess && needCheckingAccessModule)
241

  
242
    /*
243
     * Get the subtree node info from xml_accesssubtree table
244
     */
245
    private Vector getAccessSubTreeListFromDB() throws Exception
605 246
    {
606
      compareElementNameSpaceAttributes(currentUnchangableAccessModuleNodeStack, 
607
                                        namespaces, atts, localName, 
608
                                        UPDATEACCESSERROR);
609
       
247
        Vector result = new Vector();
248
        PreparedStatement pstmt = null;
249
        ResultSet rs = null;
250
        String sql = "SELECT controllevel, subtreeid, startnodeid, endnodeid "
251
                + "FROM xml_accesssubtree WHERE docid like ? "
252
                + "ORDER BY startnodeid ASC";
253

  
254
        try {
255

  
256
            pstmt = connection.prepareStatement(sql);
257
            // Increase DBConnection usage count
258
            connection.increaseUsageCount(1);
259
            // Bind the values to the query
260
            pstmt.setString(1, docid);
261
            pstmt.execute();
262

  
263
            // Get result set
264
            rs = pstmt.getResultSet();
265
            while (rs.next()) {
266
                String level = rs.getString(1);
267
                String sectionId = rs.getString(2);
268
                long startNodeId = rs.getLong(3);
269
                long endNodeId = rs.getLong(4);
270
                // create a new access section
271
                AccessSection accessObj = new AccessSection();
272
                accessObj.setControlLevel(level);
273
                accessObj.setDocId(docid);
274
                accessObj.setSubTreeId(sectionId);
275
                accessObj.setStartNodeId(startNodeId);
276
                accessObj.setEndNodeId(endNodeId);
277
                Stack nodeStack = accessObj.getSubTreeNodeList();
278
                accessObj.setSubTreeNodeStack(nodeStack);
279
                // add this access obj into vector
280
                result.add(accessObj);
281
                // Get the top level access subtree control
282
                if (level != null && level.equals(TOPLEVEL)) {
283
                    topAccessSection = accessObj;
284
                }
285
            }
286
            pstmt.close();
287
        }//try
288
        catch (SQLException e) {
289
            throw new SAXException(
290
                    "EMLSAXHandler.getAccessSubTreeListFromDB(): "
291
                            + e.getMessage());
292
        }//catch
293
        finally {
294
            try {
295
                pstmt.close();
296
            } catch (SQLException ee) {
297
                throw new SAXException(
298
                        "EMLSAXHandler.getAccessSubTreeListFromDB(): "
299
                                + ee.getMessage());
300
            }
301
        }//finally
302
        return result;
610 303
    }
611
    
612
    // store access module element and attributes into stored stack
613
    if (needCheckingAccessModule && 
614
       (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
304

  
305
    /** SAX Handler that is called at the start of each XML element */
306
    public void startElement(String uri, String localName, String qName,
307
            Attributes atts) throws SAXException
615 308
    {
616
       // stored the pull out nodes into storedNode stack
617
       NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "ELEMENT", 
618
                                localName, prefix, MetaCatUtil.normalize(null));
619
       storedAccessNodeStack.push(nodeElement);
620
       for (int i=0; i<atts.getLength(); i++) 
621
       {
622
         String attributeName = atts.getQName(i);
623
         String attributeValue = atts.getValue(i);
624
         NodeRecord nodeAttribute = new NodeRecord(-2, -2, -2, "ATTRIBUTE",
625
                    attributeName, null, MetaCatUtil.normalize(attributeValue));
626
         storedAccessNodeStack.push(nodeAttribute);
627
       }
628
                                   
309
        // for element <eml:eml...> qname is "eml:eml", local name is "eml"
310
        // for element <acl....> both qname and local name is "eml"
311
        // uri is namesapce
312
        MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
313
        MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
314
        MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
315

  
316
        DBSAXNode parentNode = null;
317
        DBSAXNode currentNode = null;
318

  
319
        if (!handleInlineData) {
320
            // Get a reference to the parent node for the id
321
            try {
322
                parentNode = (DBSAXNode) nodeStack.peek();
323
            } catch (EmptyStackException e) {
324
                parentNode = null;
325
            }
326

  
327
            //start handle inline data
328
            if (localName.equals(INLINE)) {
329
                handleInlineData = true;
330
                inLineDataIndex++;
331
                //intitialize namespace hash for in line data
332
                inlineDataNameSpace = new Hashtable();
333
                //initialize file writer
334
                String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
335
                String seperator = MetaCatUtil.getOption("accNumSeparator");
336
                // the new file name will look like docid.rev.2
337
                inlineDataFileName = docidWithoutRev + seperator + revision
338
                        + seperator + inLineDataIndex;
339
                inlineDataFileWriter = createInlineDataFileWriter(inlineDataFileName);
340
                // put the inline file id into a vector. If upload failed,
341
                // metacat will
342
                // delete the inline data file
343
                inlineFileIDList.add(inlineDataFileName);
344

  
345
            }
346

  
347
            // If hit a text node, we need write this text for current's parent
348
            // node
349
            // This will happend if the element is mixted
350
            if (hitTextNode && parentNode != null) {
351
                //compare text node data for unchangesubtree
352
                if (startCriticalSubTree) {
353
                    compareTextNode(currentUnChangedableSubtreeNodeStack,
354
                            textBuffer, PERMISSIONERROR);
355
                }//if
356

  
357
                //compare top level access module
358
                if (processTopLeverAccess && needCheckingAccessModule) {
359
                    compareTextNode(currentUnchangableAccessModuleNodeStack,
360
                            textBuffer, UPDATEACCESSERROR);
361
                }
362

  
363
                if (needCheckingAccessModule
364
                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
365
                    // stored the pull out nodes into storedNode stack
366
                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT",
367
                            null, null, MetaCatUtil.normalize(textBuffer
368
                                    .toString()));
369
                    storedAccessNodeStack.push(nodeElement);
370

  
371
                }
372

  
373
                // write the textbuffer into db for parent node.
374
                endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
375
                        parentNode);
376
                // rest hitTextNode
377
                hitTextNode = false;
378
                // reset textbuffer
379
                textBuffer = null;
380
                textBuffer = new StringBuffer();
381

  
382
            }
383

  
384
            // Document representation that points to the root document node
385
            if (atFirstElement) {
386
                atFirstElement = false;
387
                // If no DOCTYPE declaration: docname = root element
388
                // doctype = root element name or name space
389
                if (docname == null) {
390
                    docname = localName;
391
                    // if uri isn't null doctype = uri(namespace)
392
                    // othewise root element
393
                    if (uri != null && !(uri.trim()).equals("")) {
394
                        doctype = uri;
395
                    } else {
396
                        doctype = docname;
397
                    }
398
                    MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
399
                    MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
400
                } else if (doctype == null) {
401
                    // because docname is not null and it is declared in dtd
402
                    // so could not be in schema, no namespace
403
                    doctype = docname;
404
                    MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
405
                }
406
                rootNode.writeNodename(docname);
407
                try {
408
                    // for validated XML Documents store a reference to XML DB
409
                    // Catalog
410
                    // Because this is select statement and it needn't to roll
411
                    // back if
412
                    // insert document action fialed.
413
                    // In order to decrease DBConnection usage count, we get a
414
                    // new
415
                    // dbconnection from pool
416
                    String catalogid = null;
417
                    DBConnection dbConn = null;
418
                    int serialNumber = -1;
419

  
420
                    try {
421
                        // Get dbconnection
422
                        dbConn = DBConnectionPool
423
                                .getDBConnection("DBSAXHandler.startElement");
424
                        serialNumber = dbConn.getCheckOutSerialNumber();
425

  
426
                        Statement stmt = dbConn.createStatement();
427
                        ResultSet rs = stmt
428
                                .executeQuery("SELECT catalog_id FROM xml_catalog "
429
                                        + "WHERE entry_type = 'Schema' "
430
                                        + "AND public_id = '" + doctype + "'");
431
                        boolean hasRow = rs.next();
432
                        if (hasRow) {
433
                            catalogid = rs.getString(1);
434
                        }
435
                        stmt.close();
436
                    }//try
437
                    finally {
438
                        // Return dbconnection
439
                        DBConnectionPool.returnDBConnection(dbConn,
440
                                serialNumber);
441
                    }//finally
442

  
443
                    //create documentImpl object by the constructor which can
444
                    // specify
445
                    //the revision
446
                    currentDocument = new DocumentImpl(connection, rootNode
447
                            .getNodeID(), docname, doctype, docid, revision,
448
                            action, user, this.pub, catalogid, this.serverCode);
449

  
450
                } catch (Exception ane) {
451
                    throw (new SAXException(
452
                            "Error in EMLSaxHandler.startElement " + action,
453
                            ane));
454
                }
455
            }
456

  
457
            // Create the current node representation
458
            currentNode = new DBSAXNode(connection, qName, localName,
459
                    parentNode, currentDocument.getRootNodeID(), docid,
460
                    currentDocument.getDoctype());
461
            // Use a local variable to store the element node id
462
            // If this element is a start point of subtree(section), it will be
463
            // stored
464
            // otherwise, it will be discated
465
            long startNodeId = currentNode.getNodeID();
466
            // Add all of the namespaces
467
            String prefix = null;
468
            String nsuri = null;
469
            Enumeration prefixes = namespaces.keys();
470
            while (prefixes.hasMoreElements()) {
471
                prefix = (String) prefixes.nextElement();
472
                nsuri = (String) namespaces.get(prefix);
473
                endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
474
            }
475

  
476
            // Add all of the attributes
477
            for (int i = 0; i < atts.getLength(); i++) {
478
                String attributeName = atts.getQName(i);
479
                String attributeValue = atts.getValue(i);
480
                endNodeId = currentNode.setAttribute(attributeName,
481
                        attributeValue, docid);
482

  
483
                // To handle name space and schema location if the attribute
484
                // name is
485
                // xsi:schemaLocation. If the name space is in not in catalog
486
                // table
487
                // it will be regeistered.
488
                if (attributeName != null
489
                        && attributeName
490
                                .indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1) {
491
                    SchemaLocationResolver resolver = new SchemaLocationResolver(
492
                            attributeValue);
493
                    resolver.resolveNameSpace();
494

  
495
                } else if (attributeName != null && attributeName.equals(ID)) {
496

  
497
                    //check unchangedable subtree hash if contains this
498
                    // subtree id
499
                    if (unChangableSubTreeHash.containsKey(attributeValue)) {
500
                        // this subtree couldn't be changed by the user and
501
                        // move it from hash
502
                        SubTree currentUnChangedableSubtree = (SubTree) unChangableSubTreeHash
503
                                .remove(attributeValue);
504
                        currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree
505
                                .getSubTreeNodeStack();
506
                        startCriticalSubTree = true;
507
                        firstElementForCriticalSubTree = true;
508
                    }
509

  
510
                    // handle subtree info
511
                    SubTree subTress = new SubTree();
512
                    // set sub tree id
513
                    subTress.setSubTreeId(attributeValue);
514
                    // set sub tree sstart lement name
515
                    subTress.setStartElementName(currentNode.getTagName());
516
                    // set start node number
517
                    subTress.setStartNodeId(startNodeId);
518
                    // add to stack, but it didn't get end node id yet
519
                    subTreeInfoStack.push(subTress);
520

  
521
                }
522
            }//for
523

  
524
            // handle access stuff
525
            if (localName.equals(ACCESS)) {
526
                // if it is in addtionalmetacat
527
                if (parentNode.getTagName() == ADDITIONALMETADATA) {
528
                    processAdditionalAccess = true;
529

  
530
                } else {
531
                    //make sure the access is top level
532
                    // this mean current node's parent's parent should be "eml"
533
                    DBSAXNode tmpNode = (DBSAXNode) nodeStack.pop();// pop out
534
                                                                    // parent
535
                                                                    // node
536
                    //peek out grandParentNode
537
                    DBSAXNode grandParentNode = (DBSAXNode) nodeStack.peek();
538
                    // put parent node back
539
                    nodeStack.push(tmpNode);
540
                    String grandParentTag = grandParentNode.getTagName();
541
                    if (grandParentTag.equals(EML)) {
542
                        processTopLeverAccess = true;
543
                    } else {
544
                        // process other access embedded into resource level
545
                        // module
546
                        processOtherAccess = true;
547
                    }
548

  
549
                }
550
                // create access object
551
                accessObject = new AccessSection();
552
                // set permission order
553
                String permOrder = currentNode.getAttribute(ORDER);
554
                accessObject.setPermissionOrder(permOrder);
555
                // set access id
556
                String accessId = currentNode.getAttribute(ID);
557
                accessObject.setSubTreeId(accessId);
558
                accessObject.setStartNodeId(startNodeId);
559
                accessObject.setDocId(docid);
560

  
561
                // load top level node stack to
562
                // currentUnchangableAccessModuleNodeStack
563
                if (processTopLeverAccess && needCheckingAccessModule) {
564
                    // get the node stack for
565
                    currentUnchangableAccessModuleNodeStack = topAccessSection
566
                            .getSubTreeNodeStack();
567
                }
568

  
569
            }
570
            // Set up a access rule for allow
571
            else if (parentNode.getTagName() != null
572
                    && (parentNode.getTagName()).equals(ACCESS)
573
                    && localName.equals(ALLOW)) {
574

  
575
                accessRule = new AccessRule();
576

  
577
                //set permission type "allow"
578
                accessRule.setPermissionType(ALLOW);
579

  
580
            }
581
            // set up an access rule for den
582
            else if (parentNode.getTagName() != null
583
                    && (parentNode.getTagName()).equals(ACCESS)
584
                    && localName.equals(DENY)) {
585
                accessRule = new AccessRule();
586
                //set permission type "allow"
587
                accessRule.setPermissionType(DENY);
588
            }
589

  
590
            // Add the node to the stack, so that any text data can be
591
            // added as it is encountered
592
            nodeStack.push(currentNode);
593
            // Add the node to the vector used by thread for writing XML Index
594
            nodeIndex.addElement(currentNode);
595

  
596
            // handle critical subtree
597
            if (startCriticalSubTree && firstElementForCriticalSubTree) {
598
                //store the element name
599
                firstElementNameForCriticalSubTree = qName;
600
                firstElementForCriticalSubTree = false;
601
            }//for first element
602

  
603
            // handle critical subtree
604
            if (startCriticalSubTree) {
605
                compareElementNameSpaceAttributes(
606
                        currentUnChangedableSubtreeNodeStack, namespaces, atts,
607
                        localName, PERMISSIONERROR);
608

  
609
            }
610
            //compare top access level module
611
            if (processTopLeverAccess && needCheckingAccessModule) {
612
                compareElementNameSpaceAttributes(
613
                        currentUnchangableAccessModuleNodeStack, namespaces,
614
                        atts, localName, UPDATEACCESSERROR);
615

  
616
            }
617

  
618
            // store access module element and attributes into stored stack
619
            if (needCheckingAccessModule
620
                    && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
621
                // stored the pull out nodes into storedNode stack
622
                NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "ELEMENT",
623
                        localName, prefix, MetaCatUtil.normalize(null));
624
                storedAccessNodeStack.push(nodeElement);
625
                for (int i = 0; i < atts.getLength(); i++) {
626
                    String attributeName = atts.getQName(i);
627
                    String attributeValue = atts.getValue(i);
628
                    NodeRecord nodeAttribute = new NodeRecord(-2, -2, -2,
629
                            "ATTRIBUTE", attributeName, null, MetaCatUtil
630
                                    .normalize(attributeValue));
631
                    storedAccessNodeStack.push(nodeAttribute);
632
                }
633

  
634
            }
635

  
636
            // reset name space
637
            namespaces = null;
638
            namespaces = new Hashtable();
639
        }//not inline data
640
        else {
641
            // we don't buffer the inline data in characters() method
642
            // so start character don't need to hand text node.
643

  
644
            // inline data may be the xml format.
645
            StringBuffer inlineElements = new StringBuffer();
646
            inlineElements.append("<").append(qName);
647
            // append attributes
648
            for (int i = 0; i < atts.getLength(); i++) {
649
                String attributeName = atts.getQName(i);
650
                String attributeValue = atts.getValue(i);
651
                inlineElements.append(" ");
652
                inlineElements.append(attributeName);
653
                inlineElements.append("=\"");
654
                inlineElements.append(attributeValue);
655
                inlineElements.append("\"");
656
            }
657
            // append namespace
658
            String prefix = null;
659
            String nsuri = null;
660
            Enumeration prefixes = inlineDataNameSpace.keys();
661
            while (prefixes.hasMoreElements()) {
662
                prefix = (String) prefixes.nextElement();
663
                nsuri = (String) namespaces.get(prefix);
664
                inlineElements.append(" ");
665
                inlineElements.append("xmlns:");
666
                inlineElements.append(prefix);
667
                inlineElements.append("=\"");
668
                inlineElements.append(nsuri);
669
                inlineElements.append("\"");
670
            }
671
            inlineElements.append(">");
672
            //reset inline data name space
673
            inlineDataNameSpace = null;
674
            inlineDataNameSpace = new Hashtable();
675
            //write inline data into file
676
            MetaCatUtil.debugMessage("the inline element data is: "
677
                    + inlineElements.toString(), 50);
678
            writeInlineDataIntoFile(inlineDataFileWriter, inlineElements);
679
        }//else
680

  
629 681
    }
630
   
631
    // reset name space
632
    namespaces = null;
633
    namespaces = new Hashtable();
634
   }//not inline data
635
   else
636
   {
637
       // we don't buffer the inline data in characters() method
638
       // so start character don't need to hand text node.
639
       
640
       // inline data may be the xml format.
641
       StringBuffer inlineElements = new StringBuffer();
642
       inlineElements.append("<").append(qName);
643
       // append attributes
644
       for (int i=0; i<atts.getLength(); i++) 
645
       {
646
         String attributeName = atts.getQName(i);
647
         String attributeValue = atts.getValue(i);
648
         inlineElements.append(" ");
649
         inlineElements.append(attributeName);
650
         inlineElements.append("=\"");
651
         inlineElements.append(attributeValue);
652
         inlineElements.append("\"");
653
       }
654
       // append namespace
655
       String prefix =null;
656
       String nsuri = null;
657
       Enumeration prefixes = inlineDataNameSpace.keys();
658
       while ( prefixes.hasMoreElements() ) 
659
       {
660
         prefix = (String)prefixes.nextElement();
661
         nsuri = (String)namespaces.get(prefix);
662
         inlineElements.append(" ");
663
         inlineElements.append("xmlns:");
664
         inlineElements.append(prefix);
665
         inlineElements.append("=\"");
666
         inlineElements.append(nsuri);
667
         inlineElements.append("\"");
668
       }
669
       inlineElements.append(">");
670
       //reset inline data name space
671
       inlineDataNameSpace = null;
672
       inlineDataNameSpace = new Hashtable();
673
       //write inline data into file
674
       MetaCatUtil.debugMessage("the inline element data is: "+ 
675
                                 inlineElements.toString(), 50);
676
       writeInlineDataIntoFile(inlineDataFileWriter, inlineElements);
677
   }//else
678
   
679
  }
680
  
681
  private void compareElementNameSpaceAttributes(Stack unchangableNodeStack, 
682
                                            Hashtable nameSpaces,
683
                                            Attributes attributes,
684
                                            String localName, String error) 
685
                                            throws SAXException
686
  {
687
     //Get element subtree node stack (element node)
688
      NodeRecord elementNode = null;
689
      try
690
      {
691
        elementNode= (NodeRecord) unchangableNodeStack.pop();
692
      }
693
      catch (EmptyStackException ee)
694
      {
695
        MetaCatUtil.debugMessage("Node stack is empty for element data", 35);
696
        throw new SAXException(error);
697
      }
698
      MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
699
      MetaCatUtil.debugMessage("node type from stack: " + 
700
                                  elementNode.getNodeType(), 40);
701
      MetaCatUtil.debugMessage("node name from xml document: " + 
702
                                  localName, 40);
703
      MetaCatUtil.debugMessage("node name from stack: " +
704
                                  elementNode.getNodeName(), 40);
705
      MetaCatUtil.debugMessage("node data from stack: " +
706
                                  elementNode.getNodeData(), 40);
707
      MetaCatUtil.debugMessage("node id is: "+ elementNode.getNodeId(), 40);
708
      // if this node is not element or local name not equal or name space not
709
      // equals, throw an exception
710
      if (!elementNode.getNodeType().equals("ELEMENT") || 
711
          !localName.equals(elementNode.getNodeName()))
682

  
683
    private void compareElementNameSpaceAttributes(Stack unchangableNodeStack,
684
            Hashtable nameSpaces, Attributes attributes, String localName,
685
            String error) throws SAXException
686
    {
687
        //Get element subtree node stack (element node)
688
        NodeRecord elementNode = null;
689
        try {
690
            elementNode = (NodeRecord) unchangableNodeStack.pop();
691
        } catch (EmptyStackException ee) {
692
            MetaCatUtil
693
                    .debugMessage("Node stack is empty for element data", 35);
694
            throw new SAXException(error);
695
        }
696
        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
697
        MetaCatUtil.debugMessage("node type from stack: "
698
                + elementNode.getNodeType(), 40);
699
        MetaCatUtil.debugMessage("node name from xml document: " + localName,
700
                40);
701
        MetaCatUtil.debugMessage("node name from stack: "
702
                + elementNode.getNodeName(), 40);
703
        MetaCatUtil.debugMessage("node data from stack: "
704
                + elementNode.getNodeData(), 40);
705
        MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(), 40);
706
        // if this node is not element or local name not equal or name space
707
        // not
708
        // equals, throw an exception
709
        if (!elementNode.getNodeType().equals("ELEMENT")
710
                || !localName.equals(elementNode.getNodeName()))
712 711
        //  (uri != null && !uri.equals(elementNode.getNodePrefix())))
713
      {
714
        MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
715
        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
716
        MetaCatUtil.debugMessage("node type from stack: " + 
717
                                  elementNode.getNodeType(), 40);
718
        MetaCatUtil.debugMessage("node name from xml document: " + 
719
                                  localName, 40);
720
        MetaCatUtil.debugMessage("node name from stack: " +
721
                                  elementNode.getNodeName(), 40);
722
        MetaCatUtil.debugMessage("node data from stack: " +
723
                                  elementNode.getNodeData(), 40);
724
        MetaCatUtil.debugMessage("node id is: "+ elementNode.getNodeId(), 40);
725
        throw new SAXException(error);
726
      }
727
      
728
      //compare namespace
729
     Enumeration nameEn = nameSpaces.keys();
730
     while ( nameEn.hasMoreElements() ) 
731
     {
732
       //Get namespacke node stack (element node)
733
       NodeRecord nameNode = null;
734
       try
735
       { 
736
         nameNode = (NodeRecord) unchangableNodeStack.pop();
737
       }
738
       catch (EmptyStackException ee)
739
       {
740
         MetaCatUtil.debugMessage("Node stack is empty for namespace data", 35);
741
         throw new SAXException(error);
742
       }
743
       
744
       String prefixName = (String)nameEn.nextElement(); 
745
       String nameSpaceUri = (String)nameSpaces.get(prefixName);
746
       if (!nameNode.getNodeType().equals("NAMESPACE") || 
747
           !prefixName.equals(nameNode.getNodeName()) || 
748
           !nameSpaceUri.equals(nameNode.getNodeData()))
749
       { 
750
         MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
751
         MetaCatUtil.debugMessage("current node type from xml is NAMESPACE", 40);
752
         MetaCatUtil.debugMessage("node type from stack: " + 
753
                                  nameNode.getNodeType(), 40);
754
         MetaCatUtil.debugMessage("current node name from xml is: " + 
755
                                   prefixName, 40);
756
         MetaCatUtil.debugMessage("node name from stack: " +
757
                                  nameNode.getNodeName(), 40);
758
         MetaCatUtil.debugMessage("current node data from xml is: " + 
759
                                   nameSpaceUri, 40);
760
         MetaCatUtil.debugMessage("node data from stack: " +
761
                                  nameNode.getNodeData(), 40);
762
         MetaCatUtil.debugMessage("node id is: "+ nameNode.getNodeId(), 40);
763
         throw new SAXException(error);
764
       }
765
      
766
     }//while
767
      
768
      //compare attributes
769
      for (int i=0; i<attributes.getLength(); i++)
770
      {
771
        NodeRecord attriNode = null;
772
        try
773 712
        {
774
          attriNode = (NodeRecord)unchangableNodeStack.pop();
775
          
713
            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
714
            MetaCatUtil.debugMessage("current node type from xml is ELEMENT",
715
                    40);
716
            MetaCatUtil.debugMessage("node type from stack: "
717
                    + elementNode.getNodeType(), 40);
718
            MetaCatUtil.debugMessage("node name from xml document: "
719
                    + localName, 40);
720
            MetaCatUtil.debugMessage("node name from stack: "
721
                    + elementNode.getNodeName(), 40);
722
            MetaCatUtil.debugMessage("node data from stack: "
723
                    + elementNode.getNodeData(), 40);
724
            MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(),
725
                    40);
726
            throw new SAXException(error);
776 727
        }
777
        catch (EmptyStackException ee)
778
        {
779
          MetaCatUtil.debugMessage("Node stack is empty for attribute data", 35);
780
          throw new SAXException(error);
728

  
729
        //compare namespace
730
        Enumeration nameEn = nameSpaces.keys();
731
        while (nameEn.hasMoreElements()) {
732
            //Get namespacke node stack (element node)
733
            NodeRecord nameNode = null;
734
            try {
735
                nameNode = (NodeRecord) unchangableNodeStack.pop();
736
            } catch (EmptyStackException ee) {
737
                MetaCatUtil.debugMessage(
738
                        "Node stack is empty for namespace data", 35);
739
                throw new SAXException(error);
740
            }
741

  
742
            String prefixName = (String) nameEn.nextElement();
743
            String nameSpaceUri = (String) nameSpaces.get(prefixName);
744
            if (!nameNode.getNodeType().equals("NAMESPACE")
745
                    || !prefixName.equals(nameNode.getNodeName())
746
                    || !nameSpaceUri.equals(nameNode.getNodeData())) {
747
                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
748
                MetaCatUtil.debugMessage(
749
                        "current node type from xml is NAMESPACE", 40);
750
                MetaCatUtil.debugMessage("node type from stack: "
751
                        + nameNode.getNodeType(), 40);
752
                MetaCatUtil.debugMessage("current node name from xml is: "
753
                        + prefixName, 40);
754
                MetaCatUtil.debugMessage("node name from stack: "
755
                        + nameNode.getNodeName(), 40);
756
                MetaCatUtil.debugMessage("current node data from xml is: "
757
                        + nameSpaceUri, 40);
758
                MetaCatUtil.debugMessage("node data from stack: "
759
                        + nameNode.getNodeData(), 40);
760
                MetaCatUtil.debugMessage("node id is: " + nameNode.getNodeId(),
761
                        40);
762
                throw new SAXException(error);
763
            }
764

  
765
        }//while
766

  
767
        //compare attributes
768
        for (int i = 0; i < attributes.getLength(); i++) {
769
            NodeRecord attriNode = null;
770
            try {
771
                attriNode = (NodeRecord) unchangableNodeStack.pop();
772

  
773
            } catch (EmptyStackException ee) {
774
                MetaCatUtil.debugMessage(
775
                        "Node stack is empty for attribute data", 35);
776
                throw new SAXException(error);
777
            }
778
            String attributeName = attributes.getQName(i);
779
            String attributeValue = attributes.getValue(i);
780
            MetaCatUtil.debugMessage(
781
                    "current node type from xml is ATTRIBUTE ", 40);
782
            MetaCatUtil.debugMessage("node type from stack: "
783
                    + attriNode.getNodeType(), 40);
784
            MetaCatUtil.debugMessage("current node name from xml is: "
785
                    + attributeName, 40);
786
            MetaCatUtil.debugMessage("node name from stack: "
787
                    + attriNode.getNodeName(), 40);
788
            MetaCatUtil.debugMessage("current node data from xml is: "
789
                    + attributeValue, 40);
790
            MetaCatUtil.debugMessage("node data from stack: "
791
                    + attriNode.getNodeData(), 40);
792
            MetaCatUtil.debugMessage("node id  is: " + attriNode.getNodeId(),
793
                    40);
794

  
795
            if (!attriNode.getNodeType().equals("ATTRIBUTE")
796
                    || !attributeName.equals(attriNode.getNodeName())
797
                    || !attributeValue.equals(attriNode.getNodeData())) {
798
                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
799
                MetaCatUtil.debugMessage(
800
                        "current node type from xml is ATTRIBUTE ", 40);
801
                MetaCatUtil.debugMessage("node type from stack: "
802
                        + attriNode.getNodeType(), 40);
803
                MetaCatUtil.debugMessage("current node name from xml is: "
804
                        + attributeName, 40);
805
                MetaCatUtil.debugMessage("node name from stack: "
806
                        + attriNode.getNodeName(), 40);
807
                MetaCatUtil.debugMessage("current node data from xml is: "
808
                        + attributeValue, 40);
809
                MetaCatUtil.debugMessage("node data from stack: "
810
                        + attriNode.getNodeData(), 40);
811
                MetaCatUtil.debugMessage("node is: " + attriNode.getNodeId(),
812
                        40);
813
                throw new SAXException(error);
814
            }
815
        }//for
816

  
817
    }
818

  
819
    /* mehtod to compare current text node and node in db */
820
    private void compareTextNode(Stack nodeStack, StringBuffer text,
821
            String error) throws SAXException
822
    {
823
        NodeRecord node = null;
824
        //get node from current stack
825
        try {
826
            node = (NodeRecord) nodeStack.pop();
827
        } catch (EmptyStackException ee) {
828
            MetaCatUtil.debugMessage(
829
                    "Node stack is empty for text data in startElement", 35);
830
            throw new SAXException(error);
781 831
        }
782
        String attributeName = attributes.getQName(i);
783
        String attributeValue = attributes.getValue(i);
784
        MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
785
        MetaCatUtil.debugMessage("node type from stack: " + 
786
                                   attriNode.getNodeType(), 40);
787
        MetaCatUtil.debugMessage("current node name from xml is: " + 
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff