You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by df...@apache.org on 2005/12/12 15:22:08 UTC
svn commit: r356256 -
/jakarta/slide/trunk/src/share/org/apache/slide/structure/StructureImpl.java
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: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org