}
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);
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) {
// lock exclusively before anyone can get a read lock
// do not lock in external transaction because this might lead to distributed deadlocks
// between Slide and store
if (!token.isExternalTransaction()) {
namespace.getUri(token, parentObject.getUri()).getStore().exclusiveTransientLock(
parentObject.getUri().toString());
}
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