Project

General

Profile

« Previous | Next » 

Revision 1405

Added by Jing Tao almost 22 years ago

Implement to handle document level access control.

View differences:

src/edu/ucsb/nceas/metacat/EmlSAXHandler.java
54 54
   private Vector denyRules = new Vector();
55 55
   private String documentId = null;
56 56
   private Vector subDocumentIdList = new Vector();
57
   private boolean processTopLeverAccess = false;
58
   private boolean processAdditionalAccess = false;
59
   private AccessSection accessObject= null;
60
   private AccessRule accessRule = null;
61
   private Hashtable topLevelAccessControlMap = new Hashtable();
62
   private Hashtable additionalAccessControlMap = new Hashtable();
57 63
   
64
   
58 65
   // Constant
59 66
   private static final String DESCRIBES = "describes";
67
   private static final String ADDITIONALMETADATA = "additionalMetadata";
68
   private static final String ORDER = "order";
69
   private static final String ID ="id";
60 70
    
61 71
    /** Construct an instance of the handler class
62 72
    *
......
219 229
     if (localName.equals(ACCESS))
220 230
     {
221 231
       // if it is in addtionalmetacat
222
       if (currentNode.getTagName() == DESCRIBES)
232
       if (parentNode.getTagName() == ADDITIONALMETADATA)
223 233
       {
224
      
225
         // get the value in current
234
          processAdditionalAccess = true;
235
        
226 236
       }
237
       else
238
       {
239
         processTopLeverAccess = true;
240
        
241
       }
242
       // create access object 
243
        accessObject = new AccessSection();
227 244
     }
245
     
246
     // Set up accesssection object permorder and id
247
     if ( currentNode.getTagName().equals(ACCESS) ) 
248
     {
249
       // set permission order
250
       String permOrder = currentNode.getAttribute(ORDER);
251
       accessObject.setPermissionOrder(permOrder);
252
       // set access id
253
       String accessId = currentNode.getAttribute(ID);
254
       accessObject.setAccessSectionId(accessId);
255
       
256
     }
257
     
258
     // Set up a access rule
259
     if (parentNode.getTagName().equals(ACCESS) && 
260
         currentNode.getTagName().equals(ALLOW))
261
     {
262
       accessRule = new AccessRule();
263
       //set permission type "allow"
264
       accessRule.setPermissionType(ALLOW);
265
     }
266
     
267
     // set up an access rule
268
     if (parentNode.getTagName().equals(ACCESS) && 
269
         currentNode.getTagName().equals(DENY))
270
     {
271
       accessRule = new AccessRule();
272
       //set permission type "allow"
273
       accessRule.setPermissionType(DENY);
274
     }
275
       
276
     
228 277
     // Add the node to the stack, so that any text data can be
229 278
     // added as it is encountered
230 279
     nodeStack.push(currentNode);
......
232 281
     nodeIndex.addElement(currentNode);
233 282

  
234 283
  }
235

  
236
  /* The run method of xmlIndex thread. It writes XML Index for the document. */
237
  public void run ()
284
  
285
    /** SAX Handler that is called for each XML text node */
286
  public void characters(char[] cbuf, int start, int len) throws SAXException 
238 287
  {
239
    DBSAXNode currNode = null;
240
    DBSAXNode prevNode = null;
241
    DBConnection dbConn = null;
242
    int serialNumber = -1;
243
    String doctype = currentDocument.getDoctype();
244
    int step = 0;
245
    int counter = 0;
288
     super.characters(cbuf, start, len);
289
     // access stuff
290
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
291
     String currentTag = currentNode.getTagName();
292
     String data = null;
293
     // add principal
294
     if (currentTag.equals(PRINCIPAL) && accessRule != null) 
295
     {
296
        data = (new String(cbuf, start, len)).trim();
297
        accessRule.addPrincipal(data);
246 298

  
247
    try
248
    {
249

  
250
      // Opening separate db connection for writing XML Index
251
      dbConn=DBConnectionPool.getDBConnection("DBSAXHandler.run");
252
      serialNumber=dbConn.getCheckOutSerialNumber();
253
      dbConn.setAutoCommit(false);
254

  
255
      //the following while loop construct checks to make sure that the docid
256
      //of the document that we are trying to index is already
257
      //in the xml_documents table.  if this is not the case, the foreign
258
      //key relationship between xml_documents and xml_index is temporarily
259
      //broken causing multiple problems.
260
      boolean inxmldoc = false;
261
      long startTime = System.currentTimeMillis();
262
      while(!inxmldoc)
263
      {
264
        String xmlDocumentsCheck = "select distinct docid from xml_documents";
265
        PreparedStatement xmlDocCheck =
266
                                 dbConn.prepareStatement(xmlDocumentsCheck);
267
        // Increase usage count
268
        dbConn.increaseUsageCount(1);
269
        xmlDocCheck.execute();
270
        ResultSet doccheckRS = xmlDocCheck.getResultSet();
271
        boolean tableHasRows = doccheckRS.next();
272
        Vector docids = new Vector();
273
        while(tableHasRows)
299
     } 
300
     else if (currentTag.equals(PERMISSION) && accessRule != null) 
301
     {
302
        data = (new String(cbuf, start, len)).trim();
303
        // we conbine different a permission into one value
304
        int permission = accessRule.getPermission();
305
        // add permision
306
        if ( data.toUpperCase().equals("READ") ) 
274 307
        {
275
          docids.add(doccheckRS.getString(1).trim());
276
          tableHasRows = doccheckRS.next();
277
        }
278

  
279
        for(int i=0; i<docids.size(); i++)
308
          permission = permission | READ;
309
        } 
310
        else if ( data.toUpperCase().equals("WRITE") ) 
280 311
        {
281
          String d = ((String)docids.elementAt(i)).trim();
282
          if(docid.trim().equals(d))
283
          {
284
            inxmldoc = true;
285
          }
286
        }
287
        doccheckRS.close();
288
        xmlDocCheck.close();
289
        // make sure the while loop will be ended in reseaonable time
290
        long stopTime = System.currentTimeMillis();
291
        if ((stopTime - startTime) > INDEXDELAY)
312
          permission = permission | WRITE;
313
        } 
314
        else if ( data.toUpperCase().equals("CHANGEPERMISSION")) 
292 315
        {
293
          throw new Exception("Couldn't find the docid for index build in" +
294
                              "reseaonable time!");
316
          permission = permission | CHMOD;
317
        } 
318
        else if ( data.toUpperCase().equals("ALL") ) 
319
        {
320
          permission = permission | ALL;
295 321
        }
296
      }
322
        accessRule.setPermission(permission);
323
     }
324
   }//character
325
  
326
  /** SAX Handler that is called at the end of each XML element */
327
   public void endElement(String uri, String localName,
328
                          String qName) throws SAXException 
329
  {
330
     MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
297 331

  
298
      // Going through the elements of the document and writing its Index
299
      Enumeration nodes = nodeIndex.elements();
300
      while ( nodes.hasMoreElements() ) {
301
        currNode = (DBSAXNode)nodes.nextElement();
302
        currNode.updateNodeIndex(dbConn, docid, doctype);
303
      }
304
      dbConn.commit();
332
     // Get the node from the stack
333
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
334
     
335
     // access stuff
336
     if ((currentNode.getTagName()).equals(ALLOW) ||
337
         (currentNode.getTagName()).equals(DENY))
338
     {
339
       // finish parser a ccess rule and  clone it
340
       AccessRule newRule = (AccessRule)accessRule.clone();
341
       //add the new rule to access section object
342
       accessObject.addAccessRule(newRule);
343
       // reset access rule( if we didn't clone, after rseting, this object will
344
       // point to null
345
       accessRule = null;
346
     }
347
     else if ((currentNode.getTagName()).equals(ACCESS))
348
     {
349
       // finish parse a access setction and clone it
350
       AccessSection newAccessObject = (AccessSection)accessObject.clone();
351
       if (processTopLeverAccess)
352
       {
353
         // top level access control will handle whole document -docid
354
         topLevelAccessControlMap.put(docid, newAccessObject);
355
         // reset processtopleveraccess tag
356
         processTopLeverAccess =false;
357
       }
358
       else if (processAdditionalAccess)
359
       {
360
         // for additional control
361
       }
362
       
363
       //reset access section object
364
       accessObject = null;
365
     }
305 366
   }
306
   catch (Exception e) 
367
   
368
   /** SAX Handler that receives notification of end of the document */
369
   public void endDocument() throws SAXException 
307 370
   {
308
      try 
309
      {
310
        dbConn.rollback();
371
     MetaCatUtil.debugMessage("end Document", 50);
372
     // write access rule to db
373
     writeAccessRuleToDB();
374
     // Starting new thread for writing XML Index.
375
     // It calls the run method of the thread.
376
     try 
377
     {
378
       xmlIndex.start();
379
     } 
380
     catch (NullPointerException e) 
381
     {
382
       xmlIndex = null;
383
       throw new
384
       SAXException("Problem with starting thread for writing XML Index. " +
385
                    e.getMessage());
386
     }
387
   }
388
  /* The method to write access rule into db. */
389
  private void writeAccessRuleToDB() throws SAXException
390
  {
311 391
    
312
      } 
313
      catch (SQLException sqle) 
314
      {}
315
      MetaCatUtil.debugMessage("Error in DBSAXHandler.run " + 
316
                                e.getMessage(), 30);
392
    // for top document level
393
    AccessSection accessSection = (AccessSection)
394
                                          topLevelAccessControlMap.get(docid);
395
    String permOrder = accessSection.getPermissionOrder();
396
    String sql = "INSERT INTO xml_access (docid, principal_name, permission, "+
397
                 "perm_type, perm_order, accessfileid) VALUES " +
398
                 " (?, ?, ?, ?, ?, ?)";
399
    PreparedStatement pstmt = null;
400
   
401
    try 
402
    {
403
     
404
      pstmt = connection.prepareStatement(sql);
405
      // Increase DBConnection usage count
406
      connection.increaseUsageCount(1);
407
      // Bind the values to the query
408
      pstmt.setString(1, docid);
409
      pstmt.setString(6, docid);
410
      pstmt.setString(5, permOrder);
317 411
      
318
    }
412
      Vector accessRules = accessSection.getAccessRules();
413
      // go through every rule
414
      for (int i=0; i<accessRules.size(); i++)
415
      {
416
        AccessRule rule = (AccessRule)accessRules.elementAt(i);
417
        String permType = rule.getPermissionType();
418
        int permission = rule.getPermission();
419
        pstmt.setInt(3, permission);
420
        pstmt.setString(4, permType);
421
        // go through every principle in rule
422
        Vector nameVector = rule.getPrincipal();
423
        for ( int j = 0; j < nameVector.size(); j++ ) 
424
       {
425
         String prName = (String)nameVector.elementAt(j);
426
         pstmt.setString(2, prName);
427
         pstmt.execute();
428
       }//for
429
     }//for
430
     pstmt.close();
431
    }//try 
432
    catch (SQLException e) 
433
    {
434
      throw new 
435
      SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + e.getMessage());
436
    }//catch
319 437
    finally
320 438
    {
321
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
439
      try
440
      {
441
        pstmt.close();
442
      }
443
      catch(SQLException ee)
444
      {
445
        throw new 
446
        SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + ee.getMessage());
447
      }
322 448
    }//finally
323
 }//run
449
  }//writeAccessRuletoDB
324 450
     
325 451
 
326 452
}

Also available in: Unified diff