Author: dflorey Date: Mon Dec 12 06:22:02 2005 New Revision: 356256 URL: http://svn.apache.org/viewcvs?rev=356256&view=rev Log: Minor modifications to enable DASL with binding store
Modified: jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java Modified: jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java URL: http://svn.apache.org/viewcvs/jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java?rev=356256&r1=356255&r2=356256&view=diff ============================================================================== --- jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java (original) +++ jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java Mon Dec 12 06:22:02 2005 @@ -47,652 +47,701 @@ import org.apache.slide.lock.ObjectLockedException; import org.apache.slide.security.AccessDeniedException; import org.apache.slide.security.Security; +import org.apache.slide.store.ResourceId; import org.apache.slide.store.Store; import org.apache.slide.util.Configuration; /** * Default implementation of the Structure interface. - * + * * @version $Revision$ */ public class StructureImpl implements Structure { - - - // ----------------------------------------------------------- Constructors - - - /** - * Constructor. - * - * @param namespace the namespace associated with the helper object - * @param namespaceConfig configuration of the namespace - * @param securityHelper the associated security helper - * @param lockHelper the associated lock helper - */ - public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig, - Security securityHelper, Lock lockHelper) { - this.namespace = namespace; - this.namespaceConfig = namespaceConfig; - this.securityHelper = securityHelper; - this.lockHelper = lockHelper; - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * Namespace. - */ - private Namespace namespace; - - - /** - * Namespace configuration. - */ - private NamespaceConfig namespaceConfig; - - - /** - * Security helper. - */ - private Security securityHelper; - - - /** - * Lock helper. - */ - private Lock lockHelper; - - - // ------------------------------------------------------ Structure Methods - - public String generateUniqueUri(SlideToken token, String parentUri) throws ServiceAccessException { - String sequenceName = parentUri.replace('/', '-'); - - Uri uri = namespace.getUri(token, parentUri); - Store store = uri.getStore(); - if (!store.isSequenceSupported()) { - return null; - } else { - if (!store.sequenceExists(sequenceName)) { - store.createSequence(sequenceName); - } - long next = store.nextSequenceValue(sequenceName); - String uniqueUri = parentUri + "/" + next; - return uniqueUri; - } - } - - public Enumeration getChildren(SlideToken token, ObjectNode object) - throws ServiceAccessException, ObjectNotFoundException, - LinkedObjectNotFoundException, VetoException { - Enumeration childrenUri = object.enumerateChildren(); - Vector result = new Vector(); - while (childrenUri.hasMoreElements()) { - String childUri = (String) childrenUri.nextElement(); - try { - ObjectNode child = retrieve(token, childUri, false); - result.addElement(child); - } catch (AccessDeniedException e) { - } - } - return result.elements(); - } - - - public ObjectNode getParent(SlideToken token, ObjectNode object) - throws ServiceAccessException, ObjectNotFoundException, - LinkedObjectNotFoundException, AccessDeniedException, VetoException { - String objectUriStr = object.getUri(); - Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri(); - if (parentUri == null) { - return null; - } - String parentUriStr = parentUri.toString(); - ObjectNode parent = retrieve(token, parentUriStr); - return parent; - } - - - public ObjectNode retrieve(SlideToken token, String strUri) - throws ServiceAccessException, ObjectNotFoundException, - LinkedObjectNotFoundException, AccessDeniedException, VetoException { - return retrieve(token, strUri, true); - } - - - public ObjectNode retrieve(SlideToken token, String strUri, - boolean translateLastUriElement) - throws ServiceAccessException, ObjectNotFoundException, - LinkedObjectNotFoundException, AccessDeniedException, VetoException { - - Uri uri = namespace.getUri(token, strUri); - - ObjectNode result = null; - - // Fire event - if ( StructureEvent.RETRIEVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.RETRIEVE, new StructureEvent(this, token, namespace, strUri)); - - // First of all, we try to load the object directly from the given Uri. - try { - result = uri.getStore().retrieveObject(uri); - securityHelper.checkCredentials(token, result, - namespaceConfig.getReadObjectAction()); - if ((translateLastUriElement) && (result instanceof LinkNode)) { - LinkNode link = (LinkNode) result; - Uri linkedUri = namespace.getUri(token, link.getLinkedUri()); - result = linkedUri.getStore().retrieveObject(linkedUri); - securityHelper.checkCredentials(token, result, - namespaceConfig.getReadObjectAction()); - } - } catch (ObjectNotFoundException e) { - } - - // If the attempt to load the uri failed, it means there is at least - // one link in the uri (or that the uri doe'sn't have any associated - // object). - if (result == null) { - - String resolvedUri = uri.toString(); - - // 1 - Tokemization of the Uri - UriTokenizer uriTokenizer = new UriTokenizer(token, uri.getNamespace(), - resolvedUri); - - // 2 - For each element of the Uri - Uri courUri = null; - ObjectNode courObject = null; - while (uriTokenizer.hasMoreElements()) { - - // 3 - Load object's class from the uri. If the object - // does not exist, a DataException is thrown. - courUri = uriTokenizer.nextUri(); - courObject = courUri.getStore().retrieveObject(courUri); - - // We check to see if the credentials gives access to - //the current object - if (Domain.getParameter("ancestors-read-permissions-required", "true").equals("true")) { - securityHelper.checkCredentials(token, courObject, - namespaceConfig.getReadObjectAction()); - } - - // 4 - Test if object is a link, ie if it is an instance - // of LinkNode or one of its subclasses - if (((translateLastUriElement) - && (courObject instanceof LinkNode)) || - ((!translateLastUriElement) - && (uriTokenizer.hasMoreElements()) - && (courObject instanceof LinkNode)) - ) { - - // 5 - If the object is a link, we get the uri of - // the linked object - // Note : courUri still IS the Uri of the link, and so, - // in a way courUri is the parent of linkedUri. - Uri linkedUri = namespace.getUri(token, - ((LinkNode) courObject).getLinkedUri()); - - // 6 - We replace the courUri scope in the original uri - String courStrUri = courUri.toString(); - resolvedUri = linkedUri.toString() - + resolvedUri.substring(courStrUri.length()); - - // 7 - We tokenize again the uri - uriTokenizer = new UriTokenizer(token, uri.getNamespace(), - resolvedUri); - - // 8 - We parse it till we get back to the point - // where we stopped - boolean isUriFound = false; - while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { - if (linkedUri.equals(uriTokenizer.nextUri())) { - isUriFound = true; - } - } - if (!isUriFound) { - throw new LinkedObjectNotFoundException(courUri, - resolvedUri); - } - - } - - // 9 - We continue to go down in the Uri tree - } - - // 10 - We return the last object which has been found - - result = courObject; - } - - return result; - - } - - - public void create(SlideToken token, ObjectNode object, String strUri) - throws ServiceAccessException, ObjectAlreadyExistsException, - ObjectNotFoundException, LinkedObjectNotFoundException, - AccessDeniedException, ObjectLockedException, VetoException { - - // Fire event - if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE, new StructureEvent(this, token, namespace, strUri)); - - // Checking roles - Enumeration roles = securityHelper.getRoles(object); - while (roles.hasMoreElements()) { - if (!securityHelper.hasRole(token, (String)roles.nextElement())) { - // Allow only the namespace admin to create roles - // he doesn't have - Uri rootUri = namespace.getUri(token, "/"); - ObjectNode rootObject = rootUri.getStore().retrieveObject(rootUri); - securityHelper.checkCredentials(token, rootObject, - namespaceConfig.getGrantPermissionAction()); - break; - } - } - - String resolvedUri = strUri; - - // 1 - Tokenization of the Uri - UriTokenizer uriTokenizer = new UriTokenizer(token, namespace, resolvedUri); - - // 2 - For each element of the Uri - Uri courUri = null; - ObjectNode courObject = null; - ObjectNode parentObject = null; - - boolean alreadyExists = false; - - while (uriTokenizer.hasMoreElements()) { - - parentObject = courObject; - - // 3 - Load object's class from the uri. If the object does - // not exist, a DataException is thrown. - courUri = uriTokenizer.nextUri(); - try { - courObject = courUri.getStore().retrieveObject(courUri); - if (Domain.getParameter("ancestors-read-permissions-required", "true").equals("true")) { - securityHelper.checkCredentials(token, courObject, - namespaceConfig.getReadObjectAction()); - } - if (!uriTokenizer.hasMoreElements()) { - // The object already exists - alreadyExists = true; - } - } catch (ObjectNotFoundException e) { - // Load failed, probably because object was not found - // We try to create a new one. - // We have to test if the uri is the last in the list, - // we must create the requested element. - // By default, we create a SubjectNode. - ObjectNode newObject = null; - if (uriTokenizer.hasMoreElements()) { - throw new ObjectNotFoundException(courUri); - } else { - newObject = object; - } - if (parentObject != null) { - - securityHelper.checkCredentials(token, courObject, - namespaceConfig.getBindMemberAction()); - - // Now creating the new object - newObject.setUri(courUri.toString()); - courUri.getStore().createObject(courUri, newObject); - - // re-read to obtain UURI - // newObject = courUri.getStore().retrieveObject(courUri); - - // re-read the parent taking the forceEnlistment flag into account - Uri parentUri = namespace.getUri(token, parentObject.getUri()); - parentObject = parentUri.getStore().retrieveObject(parentUri); - // Add the newly created object to its parent's - // children list - ObjectNode oldChild = null; - // we can check the parentUri, it's in the same store as newObject - if (Configuration.useBinding(parentUri.getStore())) { - String bindingName = newObject.getPath().lastSegment(); - if (parentObject.hasBinding(bindingName)) { - oldChild = retrieve(token, parentObject.getUri()+"/"+bindingName, false); - parentObject.removeChild(oldChild); - store(token, oldChild); - } - } - lockHelper.checkLock - (token, parentObject, namespaceConfig.getCreateObjectAction()); - parentObject.addChild(newObject); - //namespace.getUri(token, parentObject.getUri()) - //.getDataSource().storeObject(parentObject, false); - store(token, parentObject, true); - store(token, newObject); - - } else { - throw new ObjectNotFoundException(courUri); - } - courObject = newObject; - } - - // 4 - Test if object is a link, ie if it is an instance of - // LinkNode or one of its subclasses - if ((uriTokenizer.hasMoreElements()) - && (courObject instanceof LinkNode)) { - - // 5 - If the object is a link, we get the uri of the - // linked object - // Note : courUri still IS the Uri of the link, and so, - // in a way courUri is the parent of linkedUri. - Uri linkedUri = namespace - .getUri(token, ((LinkNode) courObject).getLinkedUri()); - - // 6 - We replace the courUri scope in the original uri - String courStrUri = courUri.toString(); - resolvedUri = linkedUri.toString() - + resolvedUri.substring(courStrUri.length()); - - // 7 - We tokenize again the uri - uriTokenizer = new UriTokenizer(token, namespace, resolvedUri); - - // 8 - We parse it till we get back to the point - // where we stopped - boolean isUriFound = false; - while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { - if (linkedUri.equals(uriTokenizer.nextUri())) { - isUriFound = true; - } - } - if (!isUriFound) { - throw new LinkedObjectNotFoundException - (courUri, resolvedUri); - } - - } - - // 9 - We continue to go down in the Uri tree - } - - if (alreadyExists) { - if (courUri.isStoreRoot()) { - // if the object already exists map it anyway into - // the node hierarchy, to prevent loose of nodes - // during start up - if (parentObject != null && !parentObject.hasChild(courObject)) { - parentObject.addChild(courObject); - store(token, parentObject, true); - } - } - throw new ObjectAlreadyExistsException(strUri); - } - } - - public void createLink(SlideToken token, LinkNode link, - String linkUri, ObjectNode linkedObject) - throws ServiceAccessException, ObjectAlreadyExistsException, - ObjectNotFoundException, LinkedObjectNotFoundException, - AccessDeniedException, ObjectLockedException, VetoException { - link.setLinkedUri(linkedObject.getUri()); - - // Fire event - if ( StructureEvent.CREATE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.CREATE_LINK, new StructureEvent(this, token, link, linkUri)); - - create(token, link, linkUri); - } - - - public void store(SlideToken token, ObjectNode object) - throws ServiceAccessException, ObjectNotFoundException, - AccessDeniedException, LinkedObjectNotFoundException, VetoException { - - store(token, object, false); - } - - - protected void store(SlideToken token, ObjectNode object, boolean setModificationDate) - throws ServiceAccessException, ObjectNotFoundException, - AccessDeniedException, LinkedObjectNotFoundException, VetoException { - - // Fire event - if ( StructureEvent.STORE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.STORE, new StructureEvent(this, token, namespace, object)); - - // Checking roles - Enumeration roles = securityHelper.getRoles(object); - while (roles.hasMoreElements()) { - if (!securityHelper.hasRole(token, (String)roles.nextElement())) { - // Allow only the namespace admin to create roles - // he doesn't have - Uri rootUri = namespace.getUri(token, "/"); - ObjectNode rootObject = rootUri.getStore().retrieveObject(rootUri); - securityHelper.checkCredentials(token, rootObject, - namespaceConfig.getGrantPermissionAction()); - break; - } - } - - // working on realObject, we will lose changes immediatly done before call of store - // i observerd this with some BIND testcases - //ObjectNode realObject = retrieve(token, object.getUri(), false); - securityHelper.checkCredentials(token, object, - namespaceConfig.getCreateObjectAction()); - Uri uri = namespace.getUri(token, object.getUri()); - Store store = uri.getStore(); - store.storeObject(uri, object); - - if (setModificationDate) { - try { - NodeRevisionDescriptor revisionDescriptor = store.retrieveRevisionDescriptor(uri, new NodeRevisionNumber()); - revisionDescriptor.setModificationDate(new Date()); - revisionDescriptor.setModificationUser( - securityHelper.getPrincipal(token).getPath().lastSegment()); - store.storeRevisionDescriptor(uri, revisionDescriptor ); - } - catch (RevisionDescriptorNotFoundException e) { - // ignore silently - } - } - } - - - /** - * Method remove - * - * @param token a SlideToken - * @param object an ObjectNode - * - * @throws ServiceAccessException - * @throws ObjectNotFoundException - * @throws ObjectHasChildrenException - * @throws AccessDeniedException - * @throws LinkedObjectNotFoundException - * @throws ObjectLockedException - * - */ - public void remove(SlideToken token, ObjectNode object) - throws ServiceAccessException, ObjectNotFoundException, - ObjectHasChildrenException, AccessDeniedException, - LinkedObjectNotFoundException, ObjectLockedException, VetoException { - - ObjectNode nodeToDelete = retrieve(token, object.getUri(), false); - Uri uri = namespace.getUri(token, nodeToDelete.getUri()); - - // Fire event - if ( StructureEvent.REMOVE.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE, new StructureEvent(this, token, object, uri.toString())); - - if (!object.getUri().equals("/")) { - Uri curUri = namespace.getUri(token, nodeToDelete.getUri()); - Uri parentUri = curUri.getParentUri(); - - ObjectNode parentNode = parentUri.getStore().retrieveObject(parentUri); - - securityHelper.checkCredentials(token, nodeToDelete, - namespaceConfig.getRemoveObjectAction()); - securityHelper.checkCredentials(token, parentNode, - namespaceConfig.getUnbindMemberAction()); - lockHelper.checkLock(token, nodeToDelete, - namespaceConfig.getRemoveObjectAction()); - lockHelper.checkLock(token, parentNode, - namespaceConfig.getUnbindMemberAction()); - - parentNode.removeChild(nodeToDelete); - store(token, parentNode, true); - - if (Configuration.useBinding(curUri.getStore()) && nodeToDelete.numberOfParentBindings() > 0) { - store(token, nodeToDelete); - } - else { - Enumeration children = nodeToDelete.enumerateChildren(); - if (children.hasMoreElements()) { - throw new ObjectHasChildrenException(uri); - } - uri.getStore().removeObject(uri, nodeToDelete); - } - } - } - - - /** - * Modifies the collection identified by <b>collectionNode</b>, by adding a new binding - * from the specified segment to the resource identified by <b>sourceNode</b>. - * - * @param token a SlideToken - * @param collectionNode an ObjectNode - * @param segment a String - * @param sourceNode an ObjectNode - * - * @throws ServiceAccessException - * @throws ObjectNotFoundException - * @throws AccessDeniedException - * @throws LinkedObjectNotFoundException - * @throws ObjectLockedException - * - */ - public void addBinding(SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException, VetoException { - if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) { - collectionNode = retrieve(token, collectionNode.getUri(), false); - sourceNode = retrieve(token, sourceNode.getUri(), false); - Uri collectionUri = namespace.getUri(token, collectionNode.getUri()); -// Uri sourceUri = namespace.getUri(token, sourceNode.getUri()); - - // Fire event - if ( StructureEvent.ADD_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.ADD_BINDING, new StructureEvent(this, token, sourceNode, collectionUri.toString())); - -// if (collectionUri.getStore() != sourceUri.getStore()) { -// throw new CrossServerBindingException(collectionNode.getUri(), sourceNode.getUri()); -// } - - lockHelper.checkLock - (token, collectionNode, namespaceConfig.getCreateObjectAction()); - - ObjectNode oldChild = null; - if (collectionNode.hasBinding(segment)) { - oldChild = retrieve(token, collectionNode.getUri()+"/"+segment, false); - lockHelper.checkLock - (token, oldChild, namespaceConfig.getCreateObjectAction()); - collectionNode.removeChild(oldChild); - store( token, oldChild ); - } - collectionNode.addBinding( segment, sourceNode ); - - store( token, collectionNode, true ); - store( token, sourceNode ); - } - } - - - /** - * Modifies the collection identified by <b>collectionNode</b>, by removing the binding - * for the specified segment. - * - * @param token a SlideToken - * @param collectionNode an ObjectNode - * @param segment a String - * - * @throws ServiceAccessException - * @throws ObjectNotFoundException - * @throws AccessDeniedException - * @throws LinkedObjectNotFoundException - * @throws ObjectLockedException - * - */ - public void removeBinding(SlideToken token, ObjectNode collectionNode, String segment) throws ServiceAccessException, ObjectNotFoundException, AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, VetoException { - if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) { - collectionNode = retrieve(token, collectionNode.getUri(), false); - ObjectNode childNode = retrieve(token, collectionNode.getUri()+"/"+segment, false); - - // Fire event - if ( StructureEvent.REMOVE_BINDING.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(StructureEvent.REMOVE_BINDING, new StructureEvent(this, token, childNode, collectionNode.getUri())); - - lockHelper.checkLock - (token, collectionNode, namespaceConfig.getCreateObjectAction()); - lockHelper.checkLock - (token, childNode, namespaceConfig.getCreateObjectAction()); - - collectionNode.removeChild( childNode ); - - store( token, childNode ); - store( token, collectionNode, true ); - } - } - - - /** - * Return all parents of this object node. If pathOnly=true, only parents - * on the path of the specified ObjectNode are returned, all parents (binding!) - * otherwise. If storeOnly=true, only parents within the scope of the store - * in charge of the specified ObjectNode are returned, parents up to the root - * ObjectNode (uri="/") otherwise. - * - * @param token a SlideToken - * @param object an ObjectNode - * @param pathOnly if true, only parents on the path of the specified - * ObjectNode are returned, all parents (binding!) - * otherwise - * @param storeOnly if true, only parents within the scope of the store - * in charge of the specified ObjectNode are returned, - * parents up to the root ObjectNode (uri="/") otherwise - * @param includeSelf if true, the ObjectNode specified by object is included, - * otherwise, it is excluded - * - * @return a List of ObjectNode instances - * - * @throws ServiceAccessException - * @throws ObjectNotFoundException - * @throws LinkedObjectNotFoundException - * @throws AccessDeniedException - * - */ - public List getParents(SlideToken token, ObjectNode object, - boolean pathOnly, boolean storeOnly, boolean includeSelf) - throws ServiceAccessException, ObjectNotFoundException, - LinkedObjectNotFoundException, AccessDeniedException, VetoException - { - List result = new ArrayList(); - - if (pathOnly) { - String[] uriTokens = object.getPath().tokens(); - UriPath path = new UriPath("/"); - Uri currentUri = namespace.getUri(token, path.toString()); - Uri objectUri = namespace.getUri(token, object.getUri()); - if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { - result.add( retrieve(token, path.toString()) ); - } - - for (int i = 0; i < uriTokens.length; i++) { - path = path.child( uriTokens[i] ); - currentUri = namespace.getUri(token, path.toString()); - if (i == uriTokens.length - 1 && !includeSelf) { - break; - } - if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { - result.add( retrieve(token, path.toString()) ); - } - } - } - else { - // TODO - } - - return result; - } -} + // ----------------------------------------------------------- Constructors + + /** + * Constructor. + * + * @param namespace + * the namespace associated with the helper object + * @param namespaceConfig + * configuration of the namespace + * @param securityHelper + * the associated security helper + * @param lockHelper + * the associated lock helper + */ + public StructureImpl(Namespace namespace, NamespaceConfig namespaceConfig, + Security securityHelper, Lock lockHelper) { + this.namespace = namespace; + this.namespaceConfig = namespaceConfig; + this.securityHelper = securityHelper; + this.lockHelper = lockHelper; + } + + // ----------------------------------------------------- Instance Variables + + /** + * Namespace. + */ + private Namespace namespace; + + /** + * Namespace configuration. + */ + private NamespaceConfig namespaceConfig; + + /** + * Security helper. + */ + private Security securityHelper; + + /** + * Lock helper. + */ + private Lock lockHelper; + + // ------------------------------------------------------ Structure Methods + + public String generateUniqueUri(SlideToken token, String parentUri) + throws ServiceAccessException { + String sequenceName = parentUri.replace('/', '-'); + + Uri uri = namespace.getUri(token, parentUri); + Store store = uri.getStore(); + if (!store.isSequenceSupported()) { + return null; + } else { + if (!store.sequenceExists(sequenceName)) { + store.createSequence(sequenceName); + } + long next = store.nextSequenceValue(sequenceName); + String uniqueUri = parentUri + "/" + next; + return uniqueUri; + } + } + + public Enumeration getChildren(SlideToken token, ObjectNode object) + throws ServiceAccessException, ObjectNotFoundException, + LinkedObjectNotFoundException, VetoException { + Enumeration childrenUri = object.enumerateChildren(); + Vector result = new Vector(); + while (childrenUri.hasMoreElements()) { + String childUri = (String) childrenUri.nextElement(); + try { + ObjectNode child = retrieve(token, childUri, false); + result.addElement(child); + } catch (AccessDeniedException e) { + } + } + return result.elements(); + } + + public ObjectNode getParent(SlideToken token, ObjectNode object) + throws ServiceAccessException, ObjectNotFoundException, + LinkedObjectNotFoundException, AccessDeniedException, VetoException { + String objectUriStr = object.getUri(); + Uri parentUri = namespace.getUri(token, objectUriStr).getParentUri(); + if (parentUri == null) { + return null; + } + String parentUriStr = parentUri.toString(); + ObjectNode parent = retrieve(token, parentUriStr); + return parent; + } + + public ObjectNode retrieve(SlideToken token, String strUri) + throws ServiceAccessException, ObjectNotFoundException, + LinkedObjectNotFoundException, AccessDeniedException, VetoException { + return retrieve(token, strUri, true); + } + + public ObjectNode retrieve(SlideToken token, String strUri, + boolean translateLastUriElement) throws ServiceAccessException, + ObjectNotFoundException, LinkedObjectNotFoundException, + AccessDeniedException, VetoException { + Uri uri = namespace.getUri(token, strUri); + /* + * if (strUri.startsWith("UURI:")) { String uuri = strUri.substring(6); + * uri = ResourceId.create(uri, uuri); } else { uri = + * namespace.getUri(token, strUri); } + */ + ObjectNode result = null; + + // Fire event + if (StructureEvent.RETRIEVE.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.RETRIEVE, + new StructureEvent(this, token, namespace, strUri)); + + // First of all, we try to load the object directly from the given Uri. + try { + result = uri.getStore().retrieveObject(uri); + securityHelper.checkCredentials(token, result, namespaceConfig + .getReadObjectAction()); + if ((translateLastUriElement) && (result instanceof LinkNode)) { + LinkNode link = (LinkNode) result; + Uri linkedUri = namespace.getUri(token, link.getLinkedUri()); + result = linkedUri.getStore().retrieveObject(linkedUri); + securityHelper.checkCredentials(token, result, namespaceConfig + .getReadObjectAction()); + } + } catch (ObjectNotFoundException e) { + } + + // If the attempt to load the uri failed, it means there is at least + // one link in the uri (or that the uri doe'sn't have any associated + // object). + if (result == null) { + + String resolvedUri = uri.toString(); + + // 1 - Tokemization of the Uri + UriTokenizer uriTokenizer = new UriTokenizer(token, uri + .getNamespace(), resolvedUri); + + // 2 - For each element of the Uri + Uri courUri = null; + ObjectNode courObject = null; + while (uriTokenizer.hasMoreElements()) { + + // 3 - Load object's class from the uri. If the object + // does not exist, a DataException is thrown. + courUri = uriTokenizer.nextUri(); + courObject = courUri.getStore().retrieveObject(courUri); + + // We check to see if the credentials gives access to + // the current object + if (Domain.getParameter("ancestors-read-permissions-required", + "true").equals("true")) { + securityHelper.checkCredentials(token, courObject, + namespaceConfig.getReadObjectAction()); + } + + // 4 - Test if object is a link, ie if it is an instance + // of LinkNode or one of its subclasses + if (((translateLastUriElement) && (courObject instanceof LinkNode)) + || ((!translateLastUriElement) + && (uriTokenizer.hasMoreElements()) && (courObject instanceof LinkNode))) { + + // 5 - If the object is a link, we get the uri of + // the linked object + // Note : courUri still IS the Uri of the link, and so, + // in a way courUri is the parent of linkedUri. + Uri linkedUri = namespace.getUri(token, + ((LinkNode) courObject).getLinkedUri()); + + // 6 - We replace the courUri scope in the original uri + String courStrUri = courUri.toString(); + resolvedUri = linkedUri.toString() + + resolvedUri.substring(courStrUri.length()); + + // 7 - We tokenize again the uri + uriTokenizer = new UriTokenizer(token, uri.getNamespace(), + resolvedUri); + + // 8 - We parse it till we get back to the point + // where we stopped + boolean isUriFound = false; + while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { + if (linkedUri.equals(uriTokenizer.nextUri())) { + isUriFound = true; + } + } + if (!isUriFound) { + throw new LinkedObjectNotFoundException(courUri, + resolvedUri); + } + + } + + // 9 - We continue to go down in the Uri tree + } + + // 10 - We return the last object which has been found + + result = courObject; + } + + return result; + + } + + public void create(SlideToken token, ObjectNode object, String strUri) + throws ServiceAccessException, ObjectAlreadyExistsException, + ObjectNotFoundException, LinkedObjectNotFoundException, + AccessDeniedException, ObjectLockedException, VetoException { + + // Fire event + if (StructureEvent.CREATE.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.CREATE, + new StructureEvent(this, token, namespace, strUri)); + + // Checking roles + Enumeration roles = securityHelper.getRoles(object); + while (roles.hasMoreElements()) { + if (!securityHelper.hasRole(token, (String) roles.nextElement())) { + // Allow only the namespace admin to create roles + // he doesn't have + Uri rootUri = namespace.getUri(token, "/"); + ObjectNode rootObject = rootUri.getStore().retrieveObject( + rootUri); + securityHelper.checkCredentials(token, rootObject, + namespaceConfig.getGrantPermissionAction()); + break; + } + } + + String resolvedUri = strUri; + + // 1 - Tokenization of the Uri + UriTokenizer uriTokenizer = new UriTokenizer(token, namespace, + resolvedUri); + + // 2 - For each element of the Uri + Uri courUri = null; + ObjectNode courObject = null; + ObjectNode parentObject = null; + + boolean alreadyExists = false; + + while (uriTokenizer.hasMoreElements()) { + + parentObject = courObject; + + // 3 - Load object's class from the uri. If the object does + // not exist, a DataException is thrown. + courUri = uriTokenizer.nextUri(); + try { + courObject = courUri.getStore().retrieveObject(courUri); + if (Domain.getParameter("ancestors-read-permissions-required", + "true").equals("true")) { + securityHelper.checkCredentials(token, courObject, + namespaceConfig.getReadObjectAction()); + } + if (!uriTokenizer.hasMoreElements()) { + // The object already exists + alreadyExists = true; + } + } catch (ObjectNotFoundException e) { + // Load failed, probably because object was not found + // We try to create a new one. + // We have to test if the uri is the last in the list, + // we must create the requested element. + // By default, we create a SubjectNode. + ObjectNode newObject = null; + if (uriTokenizer.hasMoreElements()) { + throw new ObjectNotFoundException(courUri); + } else { + newObject = object; + } + if (parentObject != null) { + + securityHelper.checkCredentials(token, courObject, + namespaceConfig.getBindMemberAction()); + + // Now creating the new object + newObject.setUri(courUri.toString()); + courUri.getStore().createObject(courUri, newObject); + + // re-read to obtain UURI + // newObject = courUri.getStore().retrieveObject(courUri); + + // re-read the parent taking the forceEnlistment flag into + // account + Uri parentUri = namespace.getUri(token, parentObject + .getUri()); + parentObject = parentUri.getStore().retrieveObject( + parentUri); + // Add the newly created object to its parent's + // children list + ObjectNode oldChild = null; + // we can check the parentUri, it's in the same store as + // newObject + if (Configuration.useBinding(parentUri.getStore())) { + String bindingName = newObject.getPath().lastSegment(); + if (parentObject.hasBinding(bindingName)) { + oldChild = retrieve(token, parentObject.getUri() + + "/" + bindingName, false); + parentObject.removeChild(oldChild); + store(token, oldChild); + } + } + lockHelper.checkLock(token, parentObject, namespaceConfig + .getCreateObjectAction()); + parentObject.addChild(newObject); + // namespace.getUri(token, parentObject.getUri()) + // .getDataSource().storeObject(parentObject, false); + store(token, parentObject, true); + store(token, newObject); + + } else { + throw new ObjectNotFoundException(courUri); + } + courObject = newObject; + } + + // 4 - Test if object is a link, ie if it is an instance of + // LinkNode or one of its subclasses + if ((uriTokenizer.hasMoreElements()) + && (courObject instanceof LinkNode)) { + + // 5 - If the object is a link, we get the uri of the + // linked object + // Note : courUri still IS the Uri of the link, and so, + // in a way courUri is the parent of linkedUri. + Uri linkedUri = namespace.getUri(token, ((LinkNode) courObject) + .getLinkedUri()); + + // 6 - We replace the courUri scope in the original uri + String courStrUri = courUri.toString(); + resolvedUri = linkedUri.toString() + + resolvedUri.substring(courStrUri.length()); + + // 7 - We tokenize again the uri + uriTokenizer = new UriTokenizer(token, namespace, resolvedUri); + + // 8 - We parse it till we get back to the point + // where we stopped + boolean isUriFound = false; + while ((!isUriFound) && (uriTokenizer.hasMoreElements())) { + if (linkedUri.equals(uriTokenizer.nextUri())) { + isUriFound = true; + } + } + if (!isUriFound) { + throw new LinkedObjectNotFoundException(courUri, + resolvedUri); + } + + } + + // 9 - We continue to go down in the Uri tree + } + + if (alreadyExists) { + if (courUri.isStoreRoot()) { + // if the object already exists map it anyway into + // the node hierarchy, to prevent loose of nodes + // during start up + if (parentObject != null && !parentObject.hasChild(courObject)) { + parentObject.addChild(courObject); + store(token, parentObject, true); + } + } + throw new ObjectAlreadyExistsException(strUri); + } + } + + public void createLink(SlideToken token, LinkNode link, String linkUri, + ObjectNode linkedObject) throws ServiceAccessException, + ObjectAlreadyExistsException, ObjectNotFoundException, + LinkedObjectNotFoundException, AccessDeniedException, + ObjectLockedException, VetoException { + link.setLinkedUri(linkedObject.getUri()); + + // Fire event + if (StructureEvent.CREATE.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.CREATE_LINK, + new StructureEvent(this, token, link, linkUri)); + + create(token, link, linkUri); + } + + public void store(SlideToken token, ObjectNode object) + throws ServiceAccessException, ObjectNotFoundException, + AccessDeniedException, LinkedObjectNotFoundException, VetoException { + + store(token, object, false); + } + + protected void store(SlideToken token, ObjectNode object, + boolean setModificationDate) throws ServiceAccessException, + ObjectNotFoundException, AccessDeniedException, + LinkedObjectNotFoundException, VetoException { + + // Fire event + if (StructureEvent.STORE.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.STORE, + new StructureEvent(this, token, namespace, object)); + + // Checking roles + Enumeration roles = securityHelper.getRoles(object); + while (roles.hasMoreElements()) { + if (!securityHelper.hasRole(token, (String) roles.nextElement())) { + // Allow only the namespace admin to create roles + // he doesn't have + Uri rootUri = namespace.getUri(token, "/"); + ObjectNode rootObject = rootUri.getStore().retrieveObject( + rootUri); + securityHelper.checkCredentials(token, rootObject, + namespaceConfig.getGrantPermissionAction()); + break; + } + } + + // working on realObject, we will lose changes immediatly done before + // call of store + // i observerd this with some BIND testcases + // ObjectNode realObject = retrieve(token, object.getUri(), false); + securityHelper.checkCredentials(token, object, namespaceConfig + .getCreateObjectAction()); + Uri uri = namespace.getUri(token, object.getUri()); + Store store = uri.getStore(); + store.storeObject(uri, object); + + if (setModificationDate) { + try { + NodeRevisionDescriptor revisionDescriptor = store + .retrieveRevisionDescriptor(uri, + new NodeRevisionNumber()); + revisionDescriptor.setModificationDate(new Date()); + revisionDescriptor.setModificationUser(securityHelper + .getPrincipal(token).getPath().lastSegment()); + store.storeRevisionDescriptor(uri, revisionDescriptor); + } catch (RevisionDescriptorNotFoundException e) { + // ignore silently + } + } + } + + /** + * Method remove + * + * @param token + * a SlideToken + * @param object + * an ObjectNode + * + * @throws ServiceAccessException + * @throws ObjectNotFoundException + * @throws ObjectHasChildrenException + * @throws AccessDeniedException + * @throws LinkedObjectNotFoundException + * @throws ObjectLockedException + * + */ + public void remove(SlideToken token, ObjectNode object) + throws ServiceAccessException, ObjectNotFoundException, + ObjectHasChildrenException, AccessDeniedException, + LinkedObjectNotFoundException, ObjectLockedException, VetoException { + + ObjectNode nodeToDelete = retrieve(token, object.getUri(), false); + Uri uri = namespace.getUri(token, nodeToDelete.getUri()); + + // Fire event + if (StructureEvent.REMOVE.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.REMOVE, + new StructureEvent(this, token, object, uri.toString())); + + if (!object.getUri().equals("/")) { + Uri curUri = namespace.getUri(token, nodeToDelete.getUri()); + Uri parentUri = curUri.getParentUri(); + + ObjectNode parentNode = parentUri.getStore().retrieveObject( + parentUri); + + securityHelper.checkCredentials(token, nodeToDelete, + namespaceConfig.getRemoveObjectAction()); + securityHelper.checkCredentials(token, parentNode, namespaceConfig + .getUnbindMemberAction()); + lockHelper.checkLock(token, nodeToDelete, namespaceConfig + .getRemoveObjectAction()); + lockHelper.checkLock(token, parentNode, namespaceConfig + .getUnbindMemberAction()); + + parentNode.removeChild(nodeToDelete); + store(token, parentNode, true); + + if (Configuration.useBinding(curUri.getStore()) + && nodeToDelete.numberOfParentBindings() > 0) { + store(token, nodeToDelete); + } else { + Enumeration children = nodeToDelete.enumerateChildren(); + if (children.hasMoreElements()) { + throw new ObjectHasChildrenException(uri); + } + uri.getStore().removeObject(uri, nodeToDelete); + } + } + } + + /** + * Modifies the collection identified by <b>collectionNode</b>, by adding a + * new binding from the specified segment to the resource identified by + * <b>sourceNode</b>. + * + * @param token + * a SlideToken + * @param collectionNode + * an ObjectNode + * @param segment + * a String + * @param sourceNode + * an ObjectNode + * + * @throws ServiceAccessException + * @throws ObjectNotFoundException + * @throws AccessDeniedException + * @throws LinkedObjectNotFoundException + * @throws ObjectLockedException + * + */ + public void addBinding(SlideToken token, ObjectNode collectionNode, + String segment, ObjectNode sourceNode) + throws ServiceAccessException, ObjectNotFoundException, + AccessDeniedException, LinkedObjectNotFoundException, + ObjectLockedException, CrossServerBindingException, VetoException { + if (Configuration.useBinding(namespace.getUri(token, + collectionNode.getUri()).getStore())) { + collectionNode = retrieve(token, collectionNode.getUri(), false); + sourceNode = retrieve(token, sourceNode.getUri(), false); + Uri collectionUri = namespace + .getUri(token, collectionNode.getUri()); + // Uri sourceUri = namespace.getUri(token, sourceNode.getUri()); + + // Fire event + if (StructureEvent.ADD_BINDING.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.ADD_BINDING, + new StructureEvent(this, token, sourceNode, + collectionUri.toString())); + + // if (collectionUri.getStore() != sourceUri.getStore()) { + // throw new CrossServerBindingException(collectionNode.getUri(), + // sourceNode.getUri()); + // } + + lockHelper.checkLock(token, collectionNode, namespaceConfig + .getCreateObjectAction()); + + ObjectNode oldChild = null; + if (collectionNode.hasBinding(segment)) { + oldChild = retrieve(token, collectionNode.getUri() + "/" + + segment, false); + lockHelper.checkLock(token, oldChild, namespaceConfig + .getCreateObjectAction()); + collectionNode.removeChild(oldChild); + store(token, oldChild); + } + collectionNode.addBinding(segment, sourceNode); + + store(token, collectionNode, true); + store(token, sourceNode); + } + } + + /** + * Modifies the collection identified by <b>collectionNode</b>, by removing + * the binding for the specified segment. + * + * @param token + * a SlideToken + * @param collectionNode + * an ObjectNode + * @param segment + * a String + * + * @throws ServiceAccessException + * @throws ObjectNotFoundException + * @throws AccessDeniedException + * @throws LinkedObjectNotFoundException + * @throws ObjectLockedException + * + */ + public void removeBinding(SlideToken token, ObjectNode collectionNode, + String segment) throws ServiceAccessException, + ObjectNotFoundException, AccessDeniedException, + LinkedObjectNotFoundException, ObjectLockedException, VetoException { + if (Configuration.useBinding(namespace.getUri(token, + collectionNode.getUri()).getStore())) { + collectionNode = retrieve(token, collectionNode.getUri(), false); + ObjectNode childNode = retrieve(token, collectionNode.getUri() + + "/" + segment, false); + + // Fire event + if (StructureEvent.REMOVE_BINDING.isEnabled()) + EventDispatcher.getInstance().fireVetoableEvent( + StructureEvent.REMOVE_BINDING, + new StructureEvent(this, token, childNode, + collectionNode.getUri())); + + lockHelper.checkLock(token, collectionNode, namespaceConfig + .getCreateObjectAction()); + lockHelper.checkLock(token, childNode, namespaceConfig + .getCreateObjectAction()); + + collectionNode.removeChild(childNode); + + store(token, childNode); + store(token, collectionNode, true); + } + } + + /** + * Return all parents of this object node. If pathOnly=true, only parents on + * the path of the specified ObjectNode are returned, all parents (binding!) + * otherwise. If storeOnly=true, only parents within the scope of the store + * in charge of the specified ObjectNode are returned, parents up to the + * root ObjectNode (uri="/") otherwise. + * + * @param token + * a SlideToken + * @param object + * an ObjectNode + * @param pathOnly + * if true, only parents on the path of the specified ObjectNode + * are returned, all parents (binding!) otherwise + * @param storeOnly + * if true, only parents within the scope of the store in charge + * of the specified ObjectNode are returned, parents up to the + * root ObjectNode (uri="/") otherwise + * @param includeSelf + * if true, the ObjectNode specified by object is included, + * otherwise, it is excluded + * + * @return a List of ObjectNode instances + * + * @throws ServiceAccessException + * @throws ObjectNotFoundException + * @throws LinkedObjectNotFoundException + * @throws AccessDeniedException + * + */ + public List getParents(SlideToken token, ObjectNode object, + boolean pathOnly, boolean storeOnly, boolean includeSelf) + throws ServiceAccessException, ObjectNotFoundException, + LinkedObjectNotFoundException, AccessDeniedException, VetoException { + List result = new ArrayList(); + + if (pathOnly) { + String[] uriTokens = object.getPath().tokens(); + UriPath path = new UriPath("/"); + Uri currentUri = namespace.getUri(token, path.toString()); + Uri objectUri = namespace.getUri(token, object.getUri()); + if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { + result.add(retrieve(token, path.toString())); + } + + for (int i = 0; i < uriTokens.length; i++) { + path = path.child(uriTokens[i]); + currentUri = namespace.getUri(token, path.toString()); + if (i == uriTokens.length - 1 && !includeSelf) { + break; + } + if (!storeOnly || currentUri.getStore() == objectUri.getStore()) { + result.add(retrieve(token, path.toString())); + } + } + } else { + // TODO + } + + return result; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]