1 23 24 package org.apache.slide.structure; 25 26 import java.util.ArrayList; 27 import java.util.Date; 28 import java.util.Enumeration; 29 import java.util.List; 30 import java.util.Vector; 31 32 import org.apache.slide.common.Namespace; 33 import org.apache.slide.common.NamespaceConfig; 34 import org.apache.slide.common.ServiceAccessException; 35 import org.apache.slide.common.SlideToken; 36 import org.apache.slide.common.Uri; 37 import org.apache.slide.common.UriPath; 38 import org.apache.slide.common.UriTokenizer; 39 import org.apache.slide.content.NodeRevisionDescriptor; 40 import org.apache.slide.content.NodeRevisionNumber; 41 import org.apache.slide.content.RevisionDescriptorNotFoundException; 42 import org.apache.slide.event.EventDispatcher; 43 import org.apache.slide.event.StructureEvent; 44 import org.apache.slide.event.VetoException; 45 import org.apache.slide.lock.Lock; 46 import org.apache.slide.lock.ObjectLockedException; 47 import org.apache.slide.security.AccessDeniedException; 48 import org.apache.slide.security.Security; 49 import org.apache.slide.store.Store; 50 import org.apache.slide.util.Configuration; 51 52 57 public final class StructureImpl implements Structure { 58 59 60 62 63 71 public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig, 72 Security securityHelper, Lock lockHelper) { 73 this.namespace = namespace; 74 this.namespaceConfig = namespaceConfig; 75 this.securityHelper = securityHelper; 76 this.lockHelper = lockHelper; 77 } 78 79 80 82 83 86 private Namespace namespace; 87 88 89 92 private NamespaceConfig namespaceConfig; 93 94 95 98 private Security securityHelper; 99 100 101 104 private Lock lockHelper; 105 106 107 109 public String generateUniqueUri(SlideToken token, String parentUri) throws ServiceAccessException { 110 String sequenceName = parentUri.replace('/', '-'); 111 112 Uri uri = namespace.getUri(token, parentUri); 113 Store store = uri.getStore(); 114 if (!store.isSequenceSupported()) { 115 return null; 116 } else { 117 if (!store.sequenceExists(sequenceName)) { 118 store.createSequence(sequenceName); 119 } 120 long next = store.nextSequenceValue(sequenceName); 121 String uniqueUri = parentUri + "/" + next; 122 return uniqueUri; 123 } 124 } 125 126 public Enumeration getChildren(SlideToken token, ObjectNode object) 127 throws ServiceAccessException, ObjectNotFoundException, 128 LinkedObjectNotFoundException, VetoException { 129 Enumeration childrenUri = object.enumerateChildren(); 130 Vector result = new Vector(); 131 while (childrenUri.hasMoreElements()) { 132 String childUri = (String) childrenUri.nextElement(); 133 try { 134 ObjectNode child = retrieve(token, childUri, false); 135 result.addElement(child); 136 } catch (AccessDeniedException e) { 137 } 138 } 139 return result.elements(); 140 } 141 142 143 public ObjectNode getParent(SlideToken token, ObjectNode object) 144 throws ServiceAccessException, ObjectNotFoundException, 145 LinkedObjectNotFoundException, AccessDeniedException, VetoException { 146 String objectUriStr = object.getUri(); 147 Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri(); 148 if (parentUri == null) { 149 return null; 150 } 151 String parentUriStr = parentUri.toString(); 152 ObjectNode parent = retrieve(token, parentUriStr); 153 return parent; 154 } 155 156 157 public ObjectNode retrieve(SlideToken token, String strUri) 158 throws ServiceAccessException, ObjectNotFoundException, 159 LinkedObjectNotFoundException, AccessDeniedException, VetoException { 160 return retrieve(token, strUri, true); 161 } 162 163 164 public ObjectNode retrieve(SlideToken token, String strUri, 165 boolean translateLastUriElement) 166 throws ServiceAccessException, ObjectNotFoundException, 167 LinkedObjectNotFoundException, AccessDeniedException, VetoException { 168 169 Uri uri = namespace.getUri(token, strUri); 170 171 ObjectNode result = null; 172 173 if ( StructureEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.RETRIEVE, new StructureEvent(this, token, namespace, strUri)); 175 176 try { 178 result = uri.getStore().retrieveObject(uri); 179 securityHelper.checkCredentials 180 (token, result, namespaceConfig.getReadObjectAction()); 181 if ((translateLastUriElement) && (result instanceof LinkNode)) { 182 LinkNode link = (LinkNode) result; 183 Uri linkedUri = namespace.getUri(token, link.getLinkedUri()); 184 result = linkedUri.getStore() 185 .retrieveObject(linkedUri); 186 securityHelper.checkCredentials 187 (token, result, namespaceConfig.getReadObjectAction()); 188 } 189 } catch (ObjectNotFoundException e) { 190 } 191 192 if (result == null) { 196 197 String resolvedUri = uri.toString(); 198 199 UriTokenizer uriTokenizer = new UriTokenizer(token, uri.getNamespace(), 201 resolvedUri); 202 203 Uri courUri = null; 205 ObjectNode courObject = null; 206 while (uriTokenizer.hasMoreElements()) { 207 208 courUri = uriTokenizer.nextUri(); 211 courObject = courUri.getStore() 212 .retrieveObject(courUri); 213 214 securityHelper.checkCredentials 217 (token, courObject, namespaceConfig.getReadObjectAction()); 218 219 if (((translateLastUriElement) 222 && (courObject instanceof LinkNode)) || 223 ((!translateLastUriElement) 224 && (uriTokenizer.hasMoreElements()) 225 && (courObject instanceof LinkNode)) 226 ) { 227 228 Uri linkedUri = namespace 233 .getUri(token, ((LinkNode) courObject).getLinkedUri()); 234 235 String courStrUri = courUri.toString(); 237 resolvedUri = linkedUri.toString() 238 + resolvedUri.substring(courStrUri.length()); 239 240 uriTokenizer = new UriTokenizer(token, uri.getNamespace(), 242 resolvedUri); 243 244 boolean isUriFound = false; 247 while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { 248 if (linkedUri.equals(uriTokenizer.nextUri())) { 249 isUriFound = true; 250 } 251 } 252 if (!isUriFound) { 253 throw new LinkedObjectNotFoundException(courUri, 254 resolvedUri); 255 } 256 257 } 258 259 } 261 262 264 result = courObject; 265 } 266 267 return result; 268 269 } 270 271 272 public void create(SlideToken token, ObjectNode object, 273 String strUri) 274 throws ServiceAccessException, ObjectAlreadyExistsException, 275 ObjectNotFoundException, LinkedObjectNotFoundException, 276 AccessDeniedException, ObjectLockedException, VetoException { 277 278 if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE, new StructureEvent(this, token, namespace, strUri)); 280 281 Enumeration roles = securityHelper.getRoles(object); 283 while (roles.hasMoreElements()) { 284 if (!securityHelper.hasRole(token, (String)roles.nextElement())) { 285 Uri rootUri = namespace.getUri(token, "/"); 288 ObjectNode rootObject = 289 rootUri.getStore().retrieveObject(rootUri); 290 securityHelper.checkCredentials 291 (token, rootObject, 292 namespaceConfig.getGrantPermissionAction()); 293 break; 294 } 295 } 296 297 String resolvedUri = strUri; 298 299 UriTokenizer uriTokenizer = new UriTokenizer(token, namespace, resolvedUri); 301 302 Uri courUri = null; 304 ObjectNode courObject = null; 305 ObjectNode parentObject = null; 306 307 boolean alreadyExists = false; 308 309 while (uriTokenizer.hasMoreElements()) { 310 311 parentObject = courObject; 312 313 courUri = uriTokenizer.nextUri(); 316 try { 317 courObject = courUri.getStore() 318 .retrieveObject(courUri); 319 securityHelper 320 .checkCredentials(token, courObject, 321 namespaceConfig.getReadObjectAction()); 322 if (!uriTokenizer.hasMoreElements()) { 323 alreadyExists = true; 325 } 326 } catch (ObjectNotFoundException e) { 327 ObjectNode newObject = null; 333 if (uriTokenizer.hasMoreElements()) { 334 throw new ObjectNotFoundException(courUri); 335 } else { 336 newObject = object; 337 } 338 if (parentObject != null) { 339 340 if (!token.isExternalTransaction()) { 344 namespace.getUri(token, parentObject.getUri()).getStore().exclusiveTransientLock( 345 parentObject.getUri().toString()); 346 } 347 348 securityHelper 349 .checkCredentials(token, courObject, namespaceConfig 350 .getBindMemberAction()); 351 352 newObject.setUri(courUri.toString()); 354 courUri.getStore().createObject(courUri, newObject); 355 356 359 Uri parentUri = namespace.getUri(token, parentObject.getUri()); 361 parentObject = parentUri.getStore().retrieveObject(parentUri); 362 ObjectNode oldChild = null; 365 if (Configuration.useBinding(parentUri.getStore())) { 367 String bindingName = newObject.getPath().lastSegment(); 368 if (parentObject.hasBinding(bindingName)) { 369 oldChild = retrieve(token, parentObject.getUri()+"/"+bindingName, false); 370 parentObject.removeChild(oldChild); 371 store(token, oldChild); 372 } 373 } 374 lockHelper.checkLock 375 (token, parentObject, namespaceConfig.getCreateObjectAction()); 376 parentObject.addChild(newObject); 377 store(token, parentObject, true); 380 store(token, newObject); 381 382 } else { 383 throw new ObjectNotFoundException(courUri); 384 } 385 courObject = newObject; 386 } 387 388 if ((uriTokenizer.hasMoreElements()) 391 && (courObject instanceof LinkNode)) { 392 393 Uri linkedUri = namespace 398 .getUri(token, ((LinkNode) courObject).getLinkedUri()); 399 400 String courStrUri = courUri.toString(); 402 resolvedUri = linkedUri.toString() 403 + resolvedUri.substring(courStrUri.length()); 404 405 uriTokenizer = new UriTokenizer(token, namespace, resolvedUri); 407 408 boolean isUriFound = false; 411 while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { 412 if (linkedUri.equals(uriTokenizer.nextUri())) { 413 isUriFound = true; 414 } 415 } 416 if (!isUriFound) { 417 throw new LinkedObjectNotFoundException 418 (courUri, resolvedUri); 419 } 420 421 } 422 423 } 425 426 if (alreadyExists) { 427 if (courUri.isStoreRoot()) { 428 if (parentObject != null && !parentObject.hasChild(courObject)) { 432 parentObject.addChild(courObject); 433 store(token, parentObject, true); 434 } 435 } 436 throw new ObjectAlreadyExistsException(strUri); 437 } 438 } 439 440 public void createLink(SlideToken token, LinkNode link, 441 String linkUri, ObjectNode linkedObject) 442 throws ServiceAccessException, ObjectAlreadyExistsException, 443 ObjectNotFoundException, LinkedObjectNotFoundException, 444 AccessDeniedException, ObjectLockedException, VetoException { 445 link.setLinkedUri(linkedObject.getUri()); 446 447 if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE_LINK, new StructureEvent(this, token, link, linkUri)); 449 450 create(token, link, linkUri); 451 } 452 453 454 public void store(SlideToken token, ObjectNode object) 455 throws ServiceAccessException, ObjectNotFoundException, 456 AccessDeniedException, LinkedObjectNotFoundException, VetoException { 457 458 store(token, object, false); 459 } 460 461 462 protected void store(SlideToken token, ObjectNode object, boolean setModificationDate) 463 throws ServiceAccessException, ObjectNotFoundException, 464 AccessDeniedException, LinkedObjectNotFoundException, VetoException { 465 466 if ( StructureEvent.STORE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.STORE, new StructureEvent(this, token, namespace, object)); 468 469 Enumeration roles = securityHelper.getRoles(object); 471 while (roles.hasMoreElements()) { 472 if (!securityHelper.hasRole(token, (String)roles.nextElement())) { 473 Uri rootUri = namespace.getUri(token, "/"); 476 ObjectNode rootObject = 477 rootUri.getStore().retrieveObject(rootUri); 478 securityHelper.checkCredentials 479 (token, rootObject, 480 namespaceConfig.getGrantPermissionAction()); 481 break; 482 } 483 } 484 485 securityHelper 489 .checkCredentials(token, object, 490 namespaceConfig.getCreateObjectAction()); 491 Uri uri = namespace.getUri(token, object.getUri()); 492 Store store = uri.getStore(); 493 store.storeObject(uri, object); 494 495 if (setModificationDate) { 496 try { 497 NodeRevisionDescriptor revisionDescriptor = store.retrieveRevisionDescriptor(uri, new NodeRevisionNumber()); 498 revisionDescriptor.setModificationDate(new Date()); 499 revisionDescriptor.setModificationUser( 500 securityHelper.getPrincipal(token).getPath().lastSegment()); 501 store.storeRevisionDescriptor(uri, revisionDescriptor ); 502 } 503 catch (RevisionDescriptorNotFoundException e) { 504 } 506 } 507 } 508 509 510 524 public void remove(SlideToken token, ObjectNode object) 525 throws ServiceAccessException, ObjectNotFoundException, 526 ObjectHasChildrenException, AccessDeniedException, 527 LinkedObjectNotFoundException, ObjectLockedException, VetoException { 528 529 ObjectNode nodeToDelete = retrieve(token, object.getUri(), false); 530 Uri uri = namespace.getUri(token, nodeToDelete.getUri()); 531 532 if ( StructureEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE, new StructureEvent(this, token, object, uri.toString())); 534 535 if (!object.getUri().equals("/")) { 536 Uri curUri = namespace.getUri(token, nodeToDelete.getUri()); 537 Uri parentUri = curUri.getParentUri(); 538 539 if (!token.isExternalTransaction()) { 543 parentUri.getStore().exclusiveTransientLock(parentUri.toString()); 544 } 545 546 ObjectNode parentNode = parentUri.getStore().retrieveObject(parentUri); 547 548 securityHelper.checkCredentials 549 (token, nodeToDelete, namespaceConfig.getRemoveObjectAction()); 550 securityHelper.checkCredentials 551 (token, parentNode, namespaceConfig.getUnbindMemberAction()); 552 lockHelper.checkLock 553 (token, nodeToDelete, namespaceConfig.getRemoveObjectAction()); 554 lockHelper.checkLock 555 (token, parentNode, namespaceConfig.getUnbindMemberAction()); 556 557 parentNode.removeChild(nodeToDelete); 558 store(token, parentNode, true); 559 560 if (Configuration.useBinding(curUri.getStore()) && nodeToDelete.numberOfParentBindings() > 0) { 561 store(token, nodeToDelete); 562 } 563 else { 564 Enumeration enum = nodeToDelete.enumerateChildren(); 565 if (enum.hasMoreElements()) { 566 throw new ObjectHasChildrenException(uri); 567 } 568 uri.getStore().removeObject(uri, nodeToDelete); 569 } 570 } 571 } 572 573 574 590 public void addBinding(SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException, VetoException { 591 if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) { 592 collectionNode = retrieve(token, collectionNode.getUri(), false); 593 sourceNode = retrieve(token, sourceNode.getUri(), false); 594 Uri collectionUri = namespace.getUri(token, collectionNode.getUri()); 595 597 if ( StructureEvent.ADD_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.ADD_BINDING, new StructureEvent(this, token, sourceNode, collectionUri.toString())); 599 600 604 lockHelper.checkLock 605 (token, collectionNode, namespaceConfig.getCreateObjectAction()); 606 607 ObjectNode oldChild = null; 608 if (collectionNode.hasBinding(segment)) { 609 oldChild = retrieve(token, collectionNode.getUri()+"/"+segment, false); 610 lockHelper.checkLock 611 (token, oldChild, namespaceConfig.getCreateObjectAction()); 612 collectionNode.removeChild(oldChild); 613 store( token, oldChild ); 614 } 615 collectionNode.addBinding( segment, sourceNode ); 616 617 store( token, collectionNode, true ); 618 store( token, sourceNode ); 619 } 620 } 621 622 623 638 public void removeBinding(SlideToken token, ObjectNode collectionNode, String segment) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, VetoException { 639 if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) { 640 collectionNode = retrieve(token, collectionNode.getUri(), false); 641 ObjectNode childNode = retrieve(token, collectionNode.getUri()+"/"+segment, false); 642 643 if ( StructureEvent.REMOVE_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE_BINDING, new StructureEvent(this, token, childNode, collectionNode.getUri())); 645 646 lockHelper.checkLock 647 (token, collectionNode, namespaceConfig.getCreateObjectAction()); 648 lockHelper.checkLock 649 (token, childNode, namespaceConfig.getCreateObjectAction()); 650 651 collectionNode.removeChild( childNode ); 652 653 store( token, childNode ); 654 store( token, collectionNode, true ); 655 } 656 } 657 658 659 685 public List getParents(SlideToken token, ObjectNode object, boolean pathOnly, boolean storeOnly, boolean includeSelf) throws ServiceAccessException, ObjectNotFoundException, LinkedObjectNotFoundException, AccessDeniedException, VetoException { 686 List result = new ArrayList(); 687 688 if (pathOnly) { 689 String[] uriTokens = object.getPath().tokens(); 690 UriPath path = new UriPath("/"); 691 Uri currentUri = namespace.getUri(token, path.toString()); 692 Uri objectUri = namespace.getUri(token, object.getUri()); 693 if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { 694 result.add( retrieve(token, path.toString()) ); 695 } 696 697 for (int i = 0; i < uriTokens.length; i++) { 698 path = path.child( uriTokens[i] ); 699 currentUri = namespace.getUri(token, path.toString()); 700 if (i == uriTokens.length - 1 && !includeSelf) { 701 break; 702 } 703 if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { 704 result.add( retrieve(token, path.toString()) ); 705 } 706 } 707 } 708 else { 709 } 711 712 return result; 713 } 714 } 715 716 | Popular Tags |