Revision 1405
Added by Jing Tao almost 22 years ago
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
Implement to handle document level access control.