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 pn...@apache.org on 2003/08/18 08:51:05 UTC
cvs commit: jakarta-slide/src/share/org/apache/slide/structure CrossServerBindingException.java ObjectNode.java Structure.java StructureImpl.java SubjectNode.java
pnever 2003/08/17 23:51:05
Modified: src/share/org/apache/slide/structure ObjectNode.java
Structure.java StructureImpl.java SubjectNode.java
Added: src/share/org/apache/slide/structure
CrossServerBindingException.java
Log:
Added stuff for binding
Revision Changes Path
1.9 +457 -94 jakarta-slide/src/share/org/apache/slide/structure/ObjectNode.java
Index: ObjectNode.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/ObjectNode.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ObjectNode.java 25 Feb 2003 16:43:37 -0000 1.8
+++ ObjectNode.java 18 Aug 2003 06:51:05 -0000 1.9
@@ -7,7 +7,7 @@
*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
+ * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -15,7 +15,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -23,15 +23,15 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
- * any, must include the following acknowlegement:
- * "This product includes software developed by the
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
- * from this software without prior written permission. For written
+ * from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
@@ -59,26 +59,25 @@
*
* [Additional notices, if required by prior licensing conditions]
*
- */
+ */
package org.apache.slide.structure;
+import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;
-import java.util.Hashtable;
-import java.io.Serializable;
-import org.apache.slide.common.*;
+import org.apache.slide.common.ObjectValidationFailedException;
import org.apache.slide.util.Messages;
/**
* Represents any kind of object node.
* <p/>
* This includes actors, activities and collections.
- *
+ *
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @version $Revision$
*/
-public abstract class ObjectNode
+public abstract class ObjectNode
implements Serializable, Cloneable {
@@ -91,7 +90,6 @@
public ObjectNode() {
}
-
/**
* Default constructor.
*/
@@ -99,7 +97,6 @@
this.uri = uri;
}
-
/**
* Default constructor.
*/
@@ -107,25 +104,46 @@
this.uri = uri;
this.children = children;
this.links = links;
+ this.bindings = new BindingList();
+ this.parentBindings = new ParentBindingList();
}
+ /**
+ * Contructor to be used by stores supporting binding.
+ */
+ public ObjectNode(String uuri, Vector bindings, Vector parentBindings, Vector links) {
+ this.uuri = uuri;
+ this.bindings = new BindingList(bindings);
+ this.parentBindings = new ParentBindingList(parentBindings);
+ this.links = links;
+ computeChildren();
+ }
- // ----------------------------------------------------- Instance Variables
+ // ----------------------------------------------------- Instance Variables
/**
- * Unique ressource identifier of the object.
+ * Uniform ressource identifier (URI) of the object.
*/
protected String uri;
/**
+ * Unique URI of the object. Enables clients to determine
+ * whether two bindings are to the same resource.
+ * The UURI is a URI and may use any registered URI scheme.
+ * If binding is enabled, several object URIs may represent the same resource,
+ * while the UURI must be really unique.
+ */
+ protected String uuri;
+
+ /**
* Vector of children's Uris. Before modifying this vector you must check
* wheter {@link #childrenShared} is true. In this case clone the vector
* and set the shared state to false.
*/
private Vector children = new Vector();
-
+
/**
* If true then the {@link #children} vector is shared between multiple
* ObjectNode-instances and thus must not be modified.
@@ -138,16 +156,29 @@
* and set the shared state to false.
*/
private Vector links = new Vector();
-
+
/**
* If true then the {@link #links} vector is shared between multiple
* ObjectNode-instances and thus must not be modified.
*/
private boolean linksShared;
- // ------------------------------------------------------------- Properties
+ /**
+ * Vector of bindings. Before modifying this vector you must check
+ * whether {@link #bindingsShared} is true. In this case clone the vector
+ * and set the shared state to false.
+ */
+ private BindingList bindings = new BindingList();
+ private ParentBindingList parentBindings = new ParentBindingList();
+
+ /**
+ * If true then the {@link #bindings} vector is shared between multiple
+ * ObjectNode-instances and thus must not be modified.
+ */
+ private boolean bindingsShared;
+ // ------------------------------------------------------------- Properties
/**
* Get object's unique resource identifier.
*
@@ -157,113 +188,110 @@
return this.uri;
}
-
/**
* Set object's unique identifier.
*
* @param uri Object Uri
*/
- void setUri(String uri) {
+ public void setUri(String uri) {
this.uri = uri;
+ computeChildren();
}
-
/**
- * Return this object's children
+ * Get the unique URI.
+ *
+ * @return an URI
*
- * @return Enumeration Children's uris
- * @deprecated
*/
- public Enumeration getChildren() {
- return enumerateChildren();
+ public String getUuri() {
+ if (uuri != null) {
+ return uuri;
+ } else {
+ if (uri == null) {
+ throw new IllegalStateException(toString());
+ }
+ return uri;
+ }
}
+ /**
+ * Set the unique URI.
+ */
+ public void setUuri(String uuri) {
+ if (uuri == null) {
+ throw new IllegalArgumentException();
+ }
+ this.uuri = uuri;
+ }
/**
* Return this object's children
*
* @return Enumeration Children's uris
*/
- public Enumeration enumerateChildren() {
- return children.elements();
+ public Vector getChildren() {
+ return (Vector)children.clone();
}
-
/**
- * Add a new child.
- *
- * @param object Child
+ * Return this object's children
+ *
+ * @return Enumeration Children's uris
*/
- void addChild(ObjectNode child) {
- addChild(child.getUri());
+ public Enumeration enumerateChildren() {
+ return children.elements();
}
-
/**
- * Add a new child to this object.
+ * Return this object's bindings
*
- * @param uri Child's uri
+ * @return Enumeration of the bindings (Binding instances)
*/
- void addChild(String uri) {
- if ((uri != null) && (!hasChild(uri))) {
- // We put a dummy object in the hashtable
- if(childrenShared)
- {
- // Lazy cloning on first write access
- children=(Vector)children.clone();
- childrenShared=false;
- }
- children.addElement(uri);
- }
+ public Enumeration enumerateBindings() {
+ return bindings.elements();
}
-
/**
- * Remove all children.
+ * Return this object's binding parent-set
+ *
+ * @return Enumeration of the binding parent-set (Binding instances)
*/
- void removeChildren() {
- if(childrenShared)
- {
- children=new Vector();
- childrenShared=false;
- }
- else children.removeAllElements();
+ public Enumeration enumerateParentBindings() {
+ return parentBindings.elements();
}
-
/**
- * Remove child.
- *
- * @param uri Child's Uri
+ * Return the UURI of the specified binding.
+ *
+ * @param bindingName a String
+ * @return UURI of the bound member
*/
- void removeChild(String uri) {
- if(childrenShared)
- {
- // Lazy cloning on first write access
- children=(Vector)children.clone();
- childrenShared=false;
+ public String getBindingUuri( String bindingName ) {
+ String result = null;
+ Binding b = bindings.get(bindingName);
+ if (b != null) {
+ result = b.getUuri();
}
- children.removeElement(uri);
+ return result;
}
-
/**
* Test if object has the specified child.
- *
+ *
* @param object Child's uri
- * @return boolean true if this object has the specified child,
+ * @return boolean true if this object has the specified child,
* false otherwise
*/
public boolean hasChild(String uri) {
return children.contains(uri);
}
-
/**
* Test if this object has the specified child.
*
* @param child Child object
- * @return boolean true if this object has the specified child,
+ * @return boolean true if this object has the specified child,
* false otherwise
*/
public boolean hasChild(ObjectNode child) {
@@ -274,17 +302,73 @@
return result;
}
+ /**
+ * Test if this object has the specified binding.
+ *
+ * @param bindingName the binding name
+ * @return boolean true if this object has the specified binding,
+ * false otherwise
+ */
+ public boolean hasBinding( String bindingName ) {
+ boolean result = false;
+ if (bindingName != null) {
+ result = (bindings.get(bindingName) != null);
+ }
+ return result;
+ }
+
+ /**
+ * Test if this object has the specified parent binding.
+ *
+ * @param bindingName the binding name
+ * @return boolean true if this object has the specified binding,
+ * false otherwise
+ */
+ public boolean hasParentBinding( String bindingName ) {
+ boolean result = false;
+ if (bindingName != null) {
+ result = (parentBindings.get(bindingName) != null);
+ }
+ return result;
+ }
+
+ /**
+ * Test if this object has the specified binding.
+ *
+ * @param child an ObjectNode
+ *
+ * @return true if this object has the specified binding,
+ * false otherwise
+ */
+ public boolean hasBinding( ObjectNode child ) {
+ if (child != null) {
+ Enumeration benum = enumerateBindings();
+ while (benum.hasMoreElements()) {
+ Binding b = (Binding)benum.nextElement();
+ if (b.getUuri().equals(child.getUuri())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the number of binding parents (i.e. of nodes having a binding to this node)
+ */
+ public int numberOfParentBindings() {
+ return parentBindings.size();
+ }
/**
* Test if object has children.
- *
+ *
* @return boolean true if this object has children, false otherwise
*/
public boolean hasChildren() {
return !(children.isEmpty());
}
-
/**
* Return this object's inbound links
*
@@ -296,11 +380,9 @@
// --------------------------------------------------------- Object Methods
-
-
/**
* Equals.
- *
+ *
* @param obj Object to test
* @return boolean True if the two object are equal :
* <li>obj is of type ObjectNode and is not null</li>
@@ -315,10 +397,9 @@
return result;
}
-
/**
* Clone.
- *
+ *
* @return Object clone
*/
public ObjectNode cloneObject() {
@@ -328,10 +409,11 @@
// init the shared fields to let clone() copy them
this.childrenShared=true;
this.linksShared=true;
+ this.bindingsShared=true;
result = (ObjectNode) super.clone();
/* Old code removed because of lazy cloning
- result.children = (Vector) this.children.clone();
- result.links = (Vector) this.links.clone();*/
+ result.children = (Vector) this.children.clone();
+ result.links = (Vector) this.links.clone();*/
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
@@ -339,10 +421,9 @@
return result;
}
-
/**
* Copy.
- *
+ *
* @return Object copy
*/
public ObjectNode copyObject() {
@@ -352,8 +433,11 @@
result = (ObjectNode) super.clone();
result.childrenShared=false;
result.linksShared=false;
+ result.bindingsShared=false;
result.children = new Vector();
result.links = new Vector();
+ result.bindings = new BindingList();
+ result.parentBindings = new ParentBindingList();
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
@@ -361,10 +445,9 @@
return result;
}
-
/**
* Validate an ObjectNode.
- *
+ *
* @param expectedUri Uri
*/
public void validate(String expectedUri) {
@@ -372,24 +455,304 @@
if (uri == null)
throw new ObjectValidationFailedException
(expectedUri, Messages.message
- (ObjectNode.class.getName() + ".nullUri"));
+ (ObjectNode.class.getName() + ".nullUri"));
if (!uri.equals(expectedUri))
throw new ObjectValidationFailedException
(expectedUri, Messages.message
- (ObjectNode.class.getName() + ".incorrectUri"));
+ (ObjectNode.class.getName() + ".incorrectUri"));
if (children == null)
throw new ObjectValidationFailedException
(uri, Messages.message
- (ObjectNode.class.getName() + ".nullChildrenVector"));
+ (ObjectNode.class.getName() + ".nullChildrenVector"));
+
+ if (bindings == null || parentBindings == null)
+ throw new ObjectValidationFailedException
+ (uri, Messages.message
+ (ObjectNode.class.getName() + ".nullBindingsVector"));
if (links == null)
throw new ObjectValidationFailedException
(uri, Messages.message
- (ObjectNode.class.getName() + ".nullLinksVector"));
+ (ObjectNode.class.getName() + ".nullLinksVector"));
+
+ }
+
+ /**
+ * Add a child.
+ * @param child an ObjectNode
+ */
+ public void addChild( ObjectNode child ) {
+ addBinding( child.lastUriSegment(), child );
+ }
+
+ /**
+ * Add a new binding.
+ * @param bindingName a String
+ * @param child an ObjectNode
+ */
+ public void addBinding( String bindingName, ObjectNode source ) {
+ String childUri = this.uri+"/"+bindingName;
+ if (!hasChild(childUri)) {
+ if(childrenShared) {
+ // Lazy cloning on first write access
+ children=(Vector)children.clone();
+ childrenShared=false;
+ }
+ children.addElement(childUri);
+ }
+ if(bindingsShared) {
+ // Lazy cloning on first write access
+ bindings=(BindingList)bindings.clone();
+ parentBindings=(ParentBindingList)parentBindings.clone();
+ bindingsShared=false;
+ }
+ Binding oldBinding = bindings.put(bindingName, source);
+ source.addParentBinding(bindingName, this);
+ if (oldBinding != null) {
+ throw new IllegalStateException(
+ "Existing binding "+bindingName+" at "+this.uri+" has to be removed first");
+ }
+ }
+
+ /**
+ * Remove child.
+ *
+ * @param uri Child's Uri
+ */
+ public void removeChild(ObjectNode child) {
+ if (child == null) {
+ return;
+ }
+
+ if(childrenShared) {
+ // Lazy cloning on first write access
+ children=(Vector)children.clone();
+ childrenShared=false;
+ }
+ children.removeElement( child.getUri() );
+
+ if(bindingsShared) {
+ // Lazy cloning on first write access
+ bindings=(BindingList)bindings.clone();
+ bindingsShared=false;
+ }
+ String bindingName = lastUriSegment( child.getUri() );
+ bindings.remove(bindingName);
+ child.removeParentBinding(bindingName, this);
+ }
+
+ /**
+ * Get the last segment of the specified uri.
+ *
+ * @param uri a String
+ *
+ * @return a String
+ *
+ */
+ String lastUriSegment() {
+ return lastUriSegment(this.uri);
+ }
+
+ String lastUriSegment( String uri ) {
+ return uri.substring(uri.lastIndexOf('/') + 1);
+ }
+
+ private void computeChildren() {
+ this.children = new Vector();
+ Enumeration e = bindings.elements();
+ while (e.hasMoreElements()) {
+ Binding b = (Binding)e.nextElement();
+ children.add( uri+"/"+b.getName() );
+ }
+ }
+
+ public void addParentBinding( String bindingName, ObjectNode parent ) {
+ if(bindingsShared) {
+ // Lazy cloning on first write access
+ bindings=(BindingList)bindings.clone();
+ parentBindings=(ParentBindingList)parentBindings.clone();
+ bindingsShared=false;
+ }
+ parentBindings.put(bindingName, parent);
+ }
+
+
+ private void removeParentBinding( String bindingName, ObjectNode parent ) {
+ if(bindingsShared) {
+ // Lazy cloning on first write access
+ bindings=(BindingList)bindings.clone();
+ parentBindings=(ParentBindingList)parentBindings.clone();
+ bindingsShared=false;
+ }
+ parentBindings.remove(bindingName, parent.getUuri() );
+ }
+
+ /**
+ * Represents an binding bindingName -> UURI
+ */
+ public static class Binding {
+
+ final String bName;
+ final String bUuri;
+
+ public Binding(String bindingName, String bindingUuri) {
+ this.bName = bindingName;
+ this.bUuri = bindingUuri;
+ }
+
+ public String getName() {
+ return bName;
+ }
+
+ public String getUuri() {
+ return bUuri;
+ }
+
+ public boolean equals( Object o ) {
+ boolean result = false;
+ if (o instanceof Binding) {
+ Binding b = (Binding)o;
+ result = getName().equals( b.getName() );
+ }
+ return result;
+ }
+
+ public String toString() {
+ return bName+"->"+bUuri;
+ }
+ }
+
+ /**
+ * Represents an binding bindingName -> UURI
+ */
+ public static class ParentBinding extends Binding {
+
+ public ParentBinding(String bindingName, String bindingUuri) {
+ super(bindingName, bindingUuri);
+ }
+ public boolean equals( Object o ) {
+ boolean result = false;
+ if (o instanceof ParentBinding) {
+ ParentBinding b = (ParentBinding)o;
+ result =
+ getName().equals(b.getName()) &&
+ this.getUuri().equals(b.getUuri());
+ }
+ return result;
+ }
+
+ public String toString() {
+ return bName+":"+bUuri;
+ }
}
+ public static class ParentBindingList extends BindingList {
+
+ private ParentBindingList() {
+ super();
+ }
+
+ public ParentBindingList(Vector container) {
+ super(container);
+ }
+
+ private Enumeration elements() {
+ return container.elements();
+ }
+
+ private ParentBinding put(String bindingName, ObjectNode source) {
+ String uuri = "";
+ if (source != null && source.getUuri() != null) {
+ uuri = source.getUuri();
+ }
+ int i = container.indexOf( new ParentBinding(bindingName, uuri) );
+ ParentBinding result = null;
+ if (i >= 0) {
+ result = (ParentBinding)container.get(i);
+ container.set( i, new ParentBinding(bindingName, uuri) );
+ }
+ else {
+ container.add( new ParentBinding(bindingName, uuri) );
+ }
+ return result;
+ }
+
+ private void remove(String bindingName, String uuri) {
+ container.removeElement( new ParentBinding(bindingName, uuri) );
+ }
+
+ public synchronized Object clone() {
+ return new ParentBindingList( (Vector)container.clone() );
+ }
+
+ public String toString() {
+ return String.valueOf(container);
+ }
+
+ public int size() {
+ return container.size();
+ }
+ }
+ public static class BindingList {
+
+ protected Vector container;
+
+ private BindingList() {
+ this.container = new Vector();
+ }
+
+ public BindingList(Vector container) {
+ this.container = container;
+ }
+
+ private Enumeration elements() {
+ return container.elements();
+ }
+
+ public Binding get(String bindingName) {
+ Binding b = null;
+ int i = container.indexOf( new Binding(bindingName, null) );
+ if (i >= 0) {
+ b = (Binding)container.get(i);
+ }
+ return b;
+ }
+
+ private Binding put(String bindingName, ObjectNode source) {
+ int i = container.indexOf( new Binding(bindingName, null) );
+ Binding result = null;
+ String uuri = "";
+ if (source != null && source.getUuri() != null) {
+ uuri = source.getUuri();
+ }
+ if (i >= 0) {
+ result = (Binding)container.get(i);
+ container.set( i, new Binding(bindingName, uuri) );
+ }
+ else {
+ container.add( new Binding(bindingName, uuri) );
+ }
+ return result;
+ }
+
+ private void remove(String bindingName) {
+ container.removeElement( new Binding(bindingName, null) );
+ }
+
+ public synchronized Object clone() {
+ return new BindingList( (Vector)container.clone() );
+ }
+
+ public String toString() {
+ return String.valueOf(container);
+ }
+
+ public int size() {
+ return container.size();
+ }
+ }
}
1.11 +41 -4 jakarta-slide/src/share/org/apache/slide/structure/Structure.java
Index: Structure.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/Structure.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Structure.java 25 Apr 2002 21:15:14 -0000 1.10
+++ Structure.java 18 Aug 2003 06:51:05 -0000 1.11
@@ -271,5 +271,42 @@
LinkedObjectNotFoundException, ObjectLockedException;
+ /**
+ * 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
+ */
+ void addBinding( SlideToken token, ObjectNode collectionNode, String segment, ObjectNode sourceNode )
+ throws ServiceAccessException, ObjectNotFoundException,
+ AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException, CrossServerBindingException;
+
+ /**
+ * 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
+ *
+ */
+ void removeBinding( SlideToken token, ObjectNode collectionNode, String segment )
+ throws ServiceAccessException, ObjectNotFoundException,
+ AccessDeniedException, LinkedObjectNotFoundException, ObjectLockedException;
}
1.27 +205 -77 jakarta-slide/src/share/org/apache/slide/structure/StructureImpl.java
Index: StructureImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/StructureImpl.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- StructureImpl.java 25 Apr 2002 21:15:14 -0000 1.26
+++ StructureImpl.java 18 Aug 2003 06:51:05 -0000 1.27
@@ -63,16 +63,22 @@
package org.apache.slide.structure;
-import java.io.*;
import java.util.Enumeration;
-import java.util.Stack;
import java.util.Vector;
-import java.util.Hashtable;
-import java.util.Date;
-import org.apache.slide.common.*;
-import org.apache.slide.lock.*;
-import org.apache.slide.security.*;
-import org.apache.slide.authenticate.CredentialsToken;
+import org.apache.slide.common.Domain;
+import org.apache.slide.common.Namespace;
+import org.apache.slide.common.NamespaceConfig;
+import org.apache.slide.common.ServiceAccessException;
+import org.apache.slide.common.SlideToken;
+import org.apache.slide.common.Uri;
+import org.apache.slide.common.UriTokenizer;
+import org.apache.slide.lock.Lock;
+import org.apache.slide.lock.ObjectLockedException;
+import org.apache.slide.security.AccessDeniedException;
+import org.apache.slide.security.NodePermission;
+import org.apache.slide.security.Security;
+import org.apache.slide.store.Store;
+import org.apache.slide.util.Configuration;
/**
* Default implementation of the Structure interface.
@@ -226,11 +232,11 @@
// 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))
- ) {
+ && (courObject instanceof LinkNode)) ||
+ ((!translateLastUriElement)
+ && (uriTokenizer.hasMoreElements())
+ && (courObject instanceof LinkNode))
+ ) {
// 5 - If the object is a link, we get the uri of
// the linked object
@@ -342,7 +348,7 @@
if (parentObject != null) {
securityHelper
.checkCredentials(token, courObject, namespaceConfig
- .getCreateObjectAction());
+ .getCreateObjectAction());
// The role who creates the new object should have
// read/write access permissions
@@ -364,68 +370,80 @@
+ token.getCredentialsToken().getPublicCredentials();
Domain.debug("Checking basic permissions on new object");
/*
- try {
- securityHelper.checkCredentials
- (token, courObject,
- namespaceConfig.getReadPropertiesAction());
- } catch (AccessDeniedException excep) {
- grantedPermission = new NodePermission
- (courUri.toString(), userUri,
- namespaceConfig.getReadPropertiesAction().getUri(),
- false);
- securityHelper.grantPermission ...
- //newObject.addPermission(grantedPermission);
- }
- try {
- securityHelper.checkCredentials
- (token, courObject,
- namespaceConfig.getModifyRevisionsAction());
- } catch (AccessDeniedException excep) {
- grantedPermission = new NodePermission
- (courUri.toString(), userUri,
- namespaceConfig.getModifyRevisionsAction().getUri(),
- false);
- newObject.addPermission(grantedPermission);
- }
- try {
- securityHelper.checkCredentials
- (token, courObject,
- namespaceConfig.getDeleteObjectAction());
- } catch (AccessDeniedException excep) {
- grantedPermission = new NodePermission
- (courUri.toString(), userUri,
- namespaceConfig.getDeleteObjectAction().getUri(), false);
- newObject.addPermission(grantedPermission);
- }
- try {
- securityHelper.checkCredentials
- (token, courObject, namespaceConfig.getPutLockAction());
- } catch (AccessDeniedException excep) {
- grantedPermission = new NodePermission
- (courUri.toString(), userUri,
- namespaceConfig.getPutLockAction().getUri(), false);
- newObject.addPermission(grantedPermission);
- }
- */
+ try {
+ securityHelper.checkCredentials
+ (token, courObject,
+ namespaceConfig.getReadPropertiesAction());
+ } catch (AccessDeniedException excep) {
+ grantedPermission = new NodePermission
+ (courUri.toString(), userUri,
+ namespaceConfig.getReadPropertiesAction().getUri(),
+ false);
+ securityHelper.grantPermission ...
+ //newObject.addPermission(grantedPermission);
+ }
+ try {
+ securityHelper.checkCredentials
+ (token, courObject,
+ namespaceConfig.getModifyRevisionsAction());
+ } catch (AccessDeniedException excep) {
+ grantedPermission = new NodePermission
+ (courUri.toString(), userUri,
+ namespaceConfig.getModifyRevisionsAction().getUri(),
+ false);
+ newObject.addPermission(grantedPermission);
+ }
+ try {
+ securityHelper.checkCredentials
+ (token, courObject,
+ namespaceConfig.getDeleteObjectAction());
+ } catch (AccessDeniedException excep) {
+ grantedPermission = new NodePermission
+ (courUri.toString(), userUri,
+ namespaceConfig.getDeleteObjectAction().getUri(), false);
+ newObject.addPermission(grantedPermission);
+ }
+ try {
+ securityHelper.checkCredentials
+ (token, courObject, namespaceConfig.getPutLockAction());
+ } catch (AccessDeniedException excep) {
+ grantedPermission = new NodePermission
+ (courUri.toString(), userUri,
+ namespaceConfig.getPutLockAction().getUri(), false);
+ newObject.addPermission(grantedPermission);
+ }
+ */
Domain.debug
("Basic permissions granted for user "
- + token.getCredentialsToken().getPublicCredentials());
+ + token.getCredentialsToken().getPublicCredentials());
// 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 takink the forceEnlistment flag into account
+ // 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.lastUriSegment();
+ if (parentObject.hasBinding(bindingName)) {
+ oldChild = retrieve(token, parentObject.getUri()+"/"+bindingName, false);
+ parentObject.removeChild(oldChild);
+ store(token, oldChild);
+ }
+ }
parentObject.addChild(newObject);
//namespace.getUri(token, parentObject.getUri())
//.getDataSource().storeObject(parentObject, false);
store(token, parentObject);
+ store(token, newObject);
} else {
throw new ObjectNotFoundException(courUri);
@@ -472,14 +490,30 @@
}
if (alreadyExists) {
- // if the object already exists map it anyway into
- // the node hierarchy, to prevent loose of nodes
- // during start up
- parentObject.addChild(courObject);
- store(token, parentObject);
+ if (isStoreRoot(courUri)) {
+ // if the object already exists map it anyway into
+ // the node hierarchy, to prevent loose of nodes
+ // during start up
+ parentObject.addChild(courObject);
+ store(token, parentObject);
+ }
throw new ObjectAlreadyExistsException(strUri);
}
-
+ }
+
+ // TODO: move into Uri class?
+ private static boolean isStoreRoot(Uri uri) {
+ return uri.getRelative().length() == 0;
+ }
+
+ // TODO: move somewhere else?
+ private boolean isSameStore(SlideToken token, String leftUri, String rightUri) {
+ Store leftStore = namespace.getUri(token, leftUri).getStore();
+ Store rightStore = namespace.getUri(token, rightUri).getStore();
+ if (leftStore == null || rightStore == null) {
+ throw new IllegalStateException("Got null store: leftStore="+leftStore+", rightStore="+rightStore);
+ }
+ return leftStore == rightStore;
}
@@ -519,34 +553,128 @@
namespaceConfig.getCreateObjectAction());
Uri realObjectUri = namespace.getUri(token, realObject.getUri());
realObjectUri.getStore().storeObject(realObjectUri, object);
-
}
+ /**
+ * 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 {
ObjectNode realObject = retrieve(token, object.getUri(), false);
- Enumeration enum = realObject.enumerateChildren();
Uri uri = namespace.getUri(token, realObject.getUri());
- if (enum.hasMoreElements()) {
- throw new ObjectHasChildrenException(uri);
- }
if (!object.getUri().equals("/")) {
Uri curUri = namespace.getUri(token, realObject.getUri());
Uri parentUri = curUri.getParentUri();
ObjectNode obj = parentUri.getStore().retrieveObject(parentUri);
- obj.removeChild(realObject.getUri());
+ obj.removeChild(realObject);
securityHelper.checkCredentials
(token, realObject, namespaceConfig.getRemoveObjectAction());
lockHelper.checkLock
(token, realObject, namespaceConfig.getRemoveObjectAction());
+ if (Configuration.useBinding(curUri.getStore()) && realObject.numberOfParentBindings() > 0) {
+ store(token, realObject);
+ }
+ else {
+ Enumeration enum = realObject.enumerateChildren();
+ if (enum.hasMoreElements()) {
+ throw new ObjectHasChildrenException(uri);
+ }
+ uri.getStore().removeObject(uri, realObject);
+ }
store(token, obj);
- uri.getStore().removeObject(uri, realObject);
}
}
+
+ /**
+ * 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 {
+ if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
+ collectionNode = retrieve(token, collectionNode.getUri(), false);
+ sourceNode = retrieve(token, sourceNode.getUri(), false);
+
+ if (!isSameStore(token, collectionNode.getUri(), sourceNode.getUri())) {
+ 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 );
+ 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 {
+ if (Configuration.useBinding(namespace.getUri(token, collectionNode.getUri()).getStore())) {
+ collectionNode = retrieve(token, collectionNode.getUri(), false);
+ ObjectNode childNode = retrieve(token, collectionNode.getUri()+"/"+segment, false);
+
+ lockHelper.checkLock
+ (token, collectionNode, namespaceConfig.getCreateObjectAction());
+ lockHelper.checkLock
+ (token, childNode, namespaceConfig.getCreateObjectAction());
+
+ collectionNode.removeChild( childNode );
+
+ store( token, childNode );
+ store( token, collectionNode );
+ }
+ }
}
1.5 +12 -4 jakarta-slide/src/share/org/apache/slide/structure/SubjectNode.java
Index: SubjectNode.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/SubjectNode.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SubjectNode.java 25 Apr 2002 21:15:14 -0000 1.4
+++ SubjectNode.java 18 Aug 2003 06:51:05 -0000 1.5
@@ -102,4 +102,12 @@
super(uri, children, links);
}
+
+ /**
+ * Contructor to be used by stores supporting binding.
+ */
+ public SubjectNode(String uuri, Vector bindings, Vector parentset, Vector links) {
+ super(uuri, bindings, parentset, links);
+ }
+
}
1.1 jakarta-slide/src/share/org/apache/slide/structure/CrossServerBindingException.java
Index: CrossServerBindingException.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/CrossServerBindingException.java,v 1.1 2003/08/18 06:51:05 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/08/18 06:51:05 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Slide", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.structure;
import org.apache.slide.common.Uri;
import org.apache.slide.util.Messages;
/**
* Linked object not found.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @version $Revision: 1.1 $
*/
public class CrossServerBindingException extends StructureException {
private String sourceUri;
private String collectionUri;
/**
* Constructor.
*
* @param sourceUri binding source
* @param collectionUri binding collection
*/
public CrossServerBindingException(String sourceUri, String collectionUri) {
super(Messages.format(CrossServerBindingException.class.getName(),
sourceUri, collectionUri));
this.sourceUri = sourceUri;
this.collectionUri = collectionUri;
}
/**
* Return the source URI
*/
public String getSourceUri() {
if (sourceUri == null) {
return new String();
} else {
return sourceUri;
}
}
/**
* Return the collection URI
*/
public String getCollectionUri() {
if (collectionUri == null) {
return new String();
} else {
return collectionUri;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org