View Javadoc
1 /* 2 * ==================================================================== 3 * 4 * This code is subject to the freebxml License, Version 1.1 5 * 6 * Copyright (c) 2001 - 2003 freebxml.org. All rights reserved. 7 * 8 * ==================================================================== 9 */ 10 11 package com.sun.ebxml.registry.persistence.rdb; 12 13 import java.sql.Connection; 14 import java.sql.ResultSet; 15 import java.sql.SQLException; 16 import java.sql.Statement; 17 import java.util.ArrayList; 18 import java.util.HashMap; 19 import java.util.Iterator; 20 21 import org.oasis.ebxml.registry.bindings.query.ResponseOption; 22 import org.oasis.ebxml.registry.bindings.rim.ClassificationNode; 23 import org.oasis.ebxml.registry.bindings.rim.ClassificationNodeType; 24 import org.oasis.ebxml.registry.bindings.rim.ClassificationScheme; 25 import org.oasis.ebxml.registry.bindings.rim.ObjectRef; 26 import org.oasis.ebxml.registry.bindings.rim.ObjectRefType; 27 import org.oasis.ebxml.registry.bindings.rim.User; 28 29 import com.sun.ebxml.registry.RegistryException; 30 import com.sun.ebxml.registry.lcm.LifeCycleManagerImpl; 31 import com.sun.ebxml.registry.lcm.ObjectNotFoundException; 32 import com.sun.ebxml.registry.lcm.ReferencedObjectNotFoundException; 33 import com.sun.ebxml.registry.lcm.ReferencesExistException; 34 import com.sun.ebxml.registry.security.authorization.AuthorizationServiceImpl; 35 import com.sun.ebxml.registry.util.BindingUtility; 36 37 /*** 38 * Concept instances are used to define tree structures where each node in the tree is a Concept. Such 39 * classificationNode trees constructed with Concepts are used to define classificationNode schemes or ontologies. 40 * 41 * Note this interface used to be called ClassificationNode. 42 * 43 * @see <{RegistryEntry}> 44 * @see <{ClassificationNode}> 45 * @author Farrukh S. Najmi 46 * @author Adrian Chong 47 */ 48 public class ClassificationNodeDAO extends RegistryObjectDAO { 49 protected ClassificationNodeDAO(){} 50 51 static BindingUtility bu = BindingUtility.getInstance(); 52 53 public static String getTableNameStatic() { 54 return "ClassificationNode"; 55 } 56 57 public String getTableName() { 58 return getTableNameStatic(); 59 } 60 61 /*** 62 * Does a bulk insert of a Collection of objects that match the type for this persister. 63 * 64 */ 65 public void insert(User user, java.sql.Connection connection, ArrayList classificationNodes) throws RegistryException { 66 67 if (classificationNodes.size()==0) { 68 return; 69 } 70 71 String nodeId = null; 72 Statement stmt = null; 73 try { 74 75 // Update the exisitng ClassificationNode 76 classificationNodes = updateExistingObjects(user, connection , classificationNodes); 77 if (classificationNodes.size()==0) { 78 return; 79 } 80 System.err.println("Inserting " + classificationNodes.size() + " ClassificationNodes"); 81 82 stmt = connection.createStatement(); 83 84 Iterator iter = classificationNodes.iterator(); 85 86 ArrayList nestedNodes = new ArrayList(); 87 88 while (iter.hasNext()) { 89 ClassificationNode classificationNode = (ClassificationNode)iter.next(); 90 91 nodeId = classificationNode.getId(); 92 93 String parentId = bu.getObjectId(classificationNode.getParent()); 94 if (parentId != null) { 95 parentId = "'" + parentId + "'"; 96 } 97 98 String code = classificationNode.getCode(); 99 100 String path = generatePath(connection, classificationNode); 101 102 String str = "INSERT INTO ClassificationNode " + 103 "VALUES(null, " + //AccessControlPolicy 104 "'" + classificationNode.getId() + "', " + 105 "'ClassificationNode', " + 106 "'" + code + "', " + 107 parentId + ", " + 108 "'" + path + "' )"; 109 110 System.err.println("stmt = " + str); 111 stmt.addBatch(str); 112 113 //Now process any composed ClassificationNodes 114 ClassificationNode[] nodes = classificationNode.getClassificationNode(); 115 for(int i=0; i < nodes.length; i++) { 116 nestedNodes.add(nodes[i]); 117 } 118 } 119 120 if (classificationNodes.size() > 0) { 121 int [] updateCounts = stmt.executeBatch(); 122 //stmt.close(); 123 super.insert(user, connection, classificationNodes); 124 // Now generate the AE for inserting ClassificationNode 125 generateAuditbleEvent(connection, classificationNodes, "Created" 126 , user); 127 // Insert nested ClassificationNodes 128 insert(user, connection, nestedNodes); 129 } 130 } 131 catch (java.sql.SQLException e) { 132 e.printStackTrace(); 133 RegistryException exception = new RegistryException(e); 134 throw exception; 135 } finally { 136 try { 137 if (stmt != null) 138 stmt.close(); 139 } catch (SQLException sqle) { 140 sqle.printStackTrace(); 141 } 142 } 143 144 145 } 146 147 /*** 148 * Generate the path for the specified ClassificationNode. The path starts with a slash, followed 149 * by the id of its ClassificationScheme, if any, which is followed by codes 150 * of the intermidate ClassificationNodes and ends with the code of this 151 * ClassificationNode. If any of the ClassificationNode does not have code, 152 * empty string is appended for that ClassificationNode. 153 * <br> 154 */ 155 public String generatePath(Connection conn, ClassificationNodeType node) throws RegistryException { 156 String path = null; 157 158 /* 159 * Recursively build the path of the ClassificationNode in the form of 160 * /.../.../.. . It is composed of ClassificationScheme 's id as root and 161 * then the codes of enclosing ClassificationNodes 162 */ 163 Object parent = node.getParent(); 164 if (parent != null) { 165 if (parent instanceof org.oasis.ebxml.registry.bindings.rim.ClassificationNodeType) { 166 path = generatePath(conn, (ClassificationNodeType)parent); 167 } 168 else if (parent instanceof org.oasis.ebxml.registry.bindings.rim.ClassificationSchemeType) { 169 path = "/" + ((ClassificationScheme)parent).getId(); 170 } 171 else if (parent instanceof org.oasis.ebxml.registry.bindings.rim.ObjectRefType) { 172 path = getPathForExistingObject(conn, (ObjectRefType)parent); 173 } 174 else { 175 throw new RegistryException("Parent of ClassificationNode cannot be of type" + parent.getClass().getName()); 176 } 177 } 178 179 path += "/" + node.getCode(); 180 181 return path; 182 } 183 184 /*** 185 * Get the path for a ClassificationNode or ClassificationScheme identified by an ObjectRefType 186 * (i.e. object is expected to already exist in registry) 187 */ 188 public String getPathForExistingObject(Connection conn, ObjectRefType ref) throws RegistryException { 189 String path = null; 190 191 String objectType = super.getObjectType(conn, ((ObjectRef)ref).getId(), super.getTableName()); 192 193 if (objectType.equalsIgnoreCase("ClassificationNode")) { 194 Statement stmt = null; 195 try { 196 String sql = "select path from " + getTableName() 197 + " where id='" + ref.getId() + "'"; 198 //System.err.println(sql); 199 stmt = conn.createStatement(); 200 ResultSet rs = stmt.executeQuery(sql); 201 if (!rs.next()) { 202 throw new ReferencedObjectNotFoundException("Cannot get the path " + 203 "of the ClassificationNode from parent, which is specified by " + 204 "ObjectRef"); 205 } 206 else { 207 path = rs.getString("path"); 208 } 209 } 210 catch (SQLException e) { 211 e.printStackTrace(); 212 throw new RegistryException(e); 213 } finally { 214 try { 215 if (stmt != null) 216 stmt.close(); 217 } catch (SQLException sqle) { 218 sqle.printStackTrace(); 219 } 220 } 221 } 222 else if (objectType.equalsIgnoreCase("ClassificationScheme")) { 223 path = "/" + ref.getId(); 224 } 225 else { 226 throw new ReferencedObjectNotFoundException("The objectType of " + 227 "parent should be either ClassificationScheme or ClassificationNode"); 228 } 229 230 return path; 231 } 232 233 /*** 234 * Does a bulk delete of objects for specified parentIds 235 * 236 */ 237 public void deleteByParentIds(User user, java.sql.Connection connection, ArrayList parentIds) throws RegistryException { 238 Statement stmt = null; 239 240 try { 241 stmt = connection.createStatement(); 242 ResultSet rs = null; 243 244 ArrayList ids = new ArrayList(); 245 246 Iterator iter = parentIds.iterator(); 247 while (iter.hasNext()) { 248 String parentId = (String)iter.next(); 249 250 rs = stmt.executeQuery("SELECT id from " + getTableName() + " WHERE parent = '" + 251 parentId + "' "); 252 253 while (rs.next()) { 254 String id = rs.getString(1); 255 ids.add(id); 256 } 257 } 258 259 if (ids.size() > 0) { 260 delete(user, connection, ids); 261 } 262 //stmt.close(); 263 } 264 catch (java.sql.SQLException e) { 265 RegistryException exception = new RegistryException(e); 266 throw exception; 267 } finally { 268 try { 269 if (stmt != null) 270 stmt.close(); 271 } catch (SQLException sqle) { 272 sqle.printStackTrace(); 273 } 274 } 275 } 276 277 public void update(User user, java.sql.Connection connection 278 , ArrayList classificationNodes) throws RegistryException { 279 /* 280 * We do not need to check whether the user is authorized to update because the authorization is expected to be checked by higher level. 281 * Should we move the authorization to persistance layer?????? 282 */ 283 update(user, connection, classificationNodes, true, false); 284 285 } 286 287 /*** 288 * Does a bulk update of a ArrayList of ClassificationNode. The parent and code 289 * attribute are not mutable. The composed old ClassificationNode will be 290 * deleted and the new composed new ClassificationNode will be inserted 291 */ 292 public void update(User user, java.sql.Connection connection, ArrayList classificationNodes 293 , boolean checkExistence, boolean checkAuthorization) throws RegistryException { 294 295 System.err.println("Updating " + classificationNodes.size() + " ClassificationNodes"); 296 if (classificationNodes.size()==0) { 297 return; 298 } 299 // Check whether the user can update the objects 300 if (checkAuthorization) { 301 AuthorizationServiceImpl authorization = AuthorizationServiceImpl.getInstance(); 302 authorization.checkAuthorization(user, bu.getIdsFromRegistryObjects(classificationNodes), AuthorizationServiceImpl.UPDATE_OBJECTS_REQUEST); 303 } 304 305 Iterator iter = classificationNodes.iterator(); 306 ArrayList nodesIds = new ArrayList(); 307 ArrayList childrenNodesList = new ArrayList(); 308 309 HashMap idMap = new HashMap(); 310 while (iter.hasNext()) { 311 ClassificationNode classificationNode = (ClassificationNode)iter.next(); 312 313 //Log.print(Log.TRACE, 8, "\tDATABASE EVENT: storing ClassificationNode " ); 314 315 String nodeId = classificationNode.getId(); 316 nodesIds.add(nodeId); 317 318 // checking whether it exists 319 if (checkExistence && !registryObjectExist(connection, nodeId, getTableName())) { 320 throw new ObjectNotFoundException(nodeId, "ClassificationNode"); 321 } 322 323 // All attributes are not mutable 324 325 // Then inserting all the composed ClassificationNode 326 // Firstly fix the ids and parent attributes of composed ClassificationNode 327 LifeCycleManagerImpl lcm = LifeCycleManagerImpl.getInstance(); 328 ArrayList nodeList = new ArrayList(); 329 nodeList.add(classificationNode); 330 lcm.fixTemporaryIds(nodeList, idMap); 331 332 // Get the nested ClassificationNodes 333 ClassificationNode [] childrenNodes = classificationNode.getClassificationNode(); 334 for (int i=0; i < childrenNodes.length; i++) { 335 childrenNodesList.add(childrenNodes[i]); 336 } 337 338 } // end looping all classificationNodes 339 if (classificationNodes.size() > 0) { 340 // Updated composed Name, Descrption, Slot, ExternalIdentifier and Classification 341 super.update(user, connection, classificationNodes); 342 // Now generate the AE for updating ClassificationNode 343 generateAuditbleEvent(connection, classificationNodes, "Updated" 344 , user); 345 346 // Firstly delete the composed ClassificationNode 347 deleteByParentIds(user, connection, nodesIds); 348 349 // Now insert the composed ClassificationNode 350 if (childrenNodesList.size() > 0){ 351 insert(user, connection, childrenNodesList); 352 } 353 } 354 } 355 356 357 // Should we make index on ClassifcationNode in Classification???? 358 protected String checkClassificationReferences(java.sql.Connection conn, String nodeId) throws RegistryException { 359 String classId = null; 360 Statement stmt = null; 361 try { 362 stmt = conn.createStatement(); 363 String sql = "SELECT id FROM Classification WHERE " 364 + "classificationNode='" + nodeId + "' AND classificationNode IS NOT NULL"; 365 ResultSet rs = stmt.executeQuery(sql); 366 if(rs.next()) { 367 classId = rs.getString("id"); 368 } 369 //stmt.close(); 370 return classId; 371 } 372 catch (SQLException e){ 373 throw new RegistryException(e); 374 } finally { 375 try { 376 if (stmt != null) 377 stmt.close(); 378 } catch (SQLException sqle) { 379 sqle.printStackTrace(); 380 } 381 } 382 383 } 384 385 // Should we make index on parent in ClassificationNode???? 386 protected String checkClassificationNodeReferences(java.sql.Connection conn, String nodeId) throws RegistryException { 387 String referencingNodeId = null; 388 Statement stmt = null; 389 try { 390 stmt = conn.createStatement(); 391 String sql = "SELECT id FROM ClassificationNode WHERE " 392 + "parent='" + nodeId + "' AND parent IS NOT NULL"; 393 ResultSet rs = stmt.executeQuery(sql); 394 System.err.println(sql); 395 if (rs.next()) { 396 referencingNodeId = rs.getString("id"); 397 } 398 //stmt.close(); 399 return referencingNodeId; 400 } 401 catch (SQLException e){ 402 throw new RegistryException(e); 403 } finally { 404 try { 405 if (stmt != null) 406 stmt.close(); 407 } catch (SQLException sqle) { 408 sqle.printStackTrace(); 409 } 410 } 411 412 } 413 414 public void delete(User user, java.sql.Connection connection, ArrayList nodesIds) throws RegistryException { 415 416 Iterator iter = nodesIds.iterator(); 417 // Check whether this ClassificationNode is used in any Classification 418 while(iter.hasNext()) { 419 String nodeId = (String)iter.next(); 420 String classId = checkClassificationReferences(connection, nodeId); 421 if (classId != null) { 422 throw new ReferencesExistException("Classification " + classId + " is referencing " + nodeId); 423 } 424 String referencingNodeId = checkClassificationNodeReferences(connection, nodeId); 425 if (referencingNodeId != null) { 426 throw new ReferencesExistException("ClassificationNode " + referencingNodeId + " is referencing " + nodeId); 427 } 428 } 429 super.delete(user, connection, nodesIds); 430 } 431 432 public void loadObjectFromResultSet(java.sql.Connection conn, Object obj, ResultSet rs, ResponseOption responseOption, ArrayList objectRefs) throws RegistryException { 433 try { 434 if (!(obj instanceof org.oasis.ebxml.registry.bindings.rim.ClassificationNode)) { 435 throw new RegistryException("Unexpected object " + obj + ". Was expecting org.oasis.ebxml.registry.bindings.rim.ClassificationNode."); 436 } 437 438 ClassificationNode node = (ClassificationNode)obj; 439 super.loadObjectFromResultSet(conn, obj, rs, responseOption, objectRefs); 440 441 String code = rs.getString("code"); 442 node.setCode(code); 443 444 String parent = rs.getString("parent"); 445 ObjectRef or = null; 446 if (parent != null) { 447 or = new ObjectRef(); 448 or.setId(parent); 449 objectRefs.add(or); 450 } 451 node.setParent(or); 452 453 String path = rs.getString("path"); 454 node.setPath(path); 455 } 456 catch (SQLException e) { 457 e.printStackTrace(); 458 throw new RegistryException(e); 459 } 460 } 461 462 public ArrayList getLeafObjectList(java.sql.Connection conn, ResultSet rs, ResponseOption responseOption, ArrayList objectRefs) throws RegistryException { 463 ArrayList res = new ArrayList(); 464 465 try { 466 while(rs.next()) { 467 ClassificationNode obj = new ClassificationNode(); 468 loadObjectFromResultSet(conn, obj, rs, responseOption, objectRefs); 469 470 res.add(obj); 471 } 472 } 473 catch (SQLException e) { 474 e.printStackTrace(); 475 throw new RegistryException(e); 476 } 477 478 479 return res; 480 } 481 }

This page was automatically generated by Maven