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/12/27 15:54:37 UTC
cvs commit: jakarta-slide/src/share/org/apache/slide/store/tlock TLock.java TLockedException.java TLockManager.java
pnever 2003/12/27 06:54:37
Added: src/share/org/apache/slide/store ParentStore.java
ResourceId.java
src/share/org/apache/slide/store/tlock TLock.java
TLockedException.java TLockManager.java
Log:
New parent store implementation supporting
- t.locking
- resolving
Revision Changes Path
1.1 jakarta-slide/src/share/org/apache/slide/store/ParentStore.java
Index: ParentStore.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/ParentStore.java,v 1.1 2003/12/27 14:54:37 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/12/27 14:54:37 $
*
* ====================================================================
*
* 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.store;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.transaction.xa.XAException;
import javax.transaction.xa.Xid;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.Uri;
import org.apache.slide.common.UriPath;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionAlreadyExistException;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.lock.LockTokenNotFoundException;
import org.apache.slide.lock.NodeLock;
import org.apache.slide.macro.ConflictException;
import org.apache.slide.store.tlock.TLock;
import org.apache.slide.store.tlock.TLockManager;
import org.apache.slide.store.tlock.TLockedException;
import org.apache.slide.security.NodePermission;
import org.apache.slide.store.ExtendedStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.Configuration;
import org.apache.slide.util.XMLValue;
import org.jdom.Element;
/**
* Store implementation supporting binding-resolution and t-locking.
* By extending ExtendedStore, this store implementation inherits also
* caching.
*
* @author michael.hartmeier@softwareag.com
* @author peter.nevermann@softwareag.com
* @version $Revision: 1.1 $
*/
public class ParentStore extends /*AbstractStore*/ ExtendedStore {
private static final int TLOCK_TIMEOUT = 5000; // TODO
private static TLockManager tlockManager = new TLockManager(TLOCK_TIMEOUT);
// overwrites inherited
public void initialize(NamespaceAccessToken token)
throws ServiceInitializationFailedException {
super.initialize(token);
}
// overwrites inherited
public void commit(Xid xid, boolean onePhase) throws XAException {
try {
super.commit(xid, onePhase);
}
finally {
tlockManager.releaseLocks();
}
}
// overwrites inherited
public void rollback(Xid xid) throws XAException {
try {
super.rollback(xid);
}
finally {
tlockManager.releaseLocks();
}
}
// overwrites inherited
public ObjectNode retrieveObject(Uri uri)
throws ServiceAccessException, ObjectNotFoundException {
return doRetrieveObjectNode(uri);
}
// overwrites inherited
public void storeObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
ResourceId resourceId = obtainResourceId(uri, object);
ObjectNode objectClone = object.cloneObject();
objectClone.setUri(resourceId.getUuri()); // switch to uuri
super.storeObject(resourceId, objectClone);
}
// overwrites inherited
public void createObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectAlreadyExistsException {
ResourceId resourceId = ResourceId.createNew(uri);
object.setUuri(resourceId.getUuri());
ObjectNode objectClone = object.cloneObject();
objectClone.setUri(resourceId.getUuri()); // switch to uuri
tlockManager.create(TLock.WRITE_LOCK, uri.toString(), resourceId);
cacheResolve(uri, resourceId);
super.createObject(resourceId, objectClone);
}
// overwrites inherited
public void removeObject(Uri uri, ObjectNode object)
throws ServiceAccessException, ObjectNotFoundException {
ResourceId resourceId = obtainResourceId(uri, object);
ObjectNode objectClone = object.cloneObject();
objectClone.setUri(resourceId.getUuri()); // switch to uuri
super.removeObject(resourceId, objectClone);
}
// overwrites inherited
public void grantPermission(Uri uri, NodePermission permission)
throws ServiceAccessException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodePermission permissionClone = permission.cloneObject();
permissionClone.setObject(resourceId.getUuri()); // switch to uuri
super.grantPermission(resourceId, permissionClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void revokePermission(Uri uri, NodePermission permission)
throws ServiceAccessException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodePermission permissionClone = permission.cloneObject();
permissionClone.setObject(resourceId.getUuri()); // switch to uuri
super.revokePermission(resourceId, permissionClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void revokePermissions(Uri uri)
throws ServiceAccessException {
try {
super.revokePermissions(obtainResourceId(uri));
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public Enumeration enumeratePermissions(Uri uri)
throws ServiceAccessException {
try {
Enumeration permissions = super.enumeratePermissions(obtainResourceId(uri));
Vector result = new Vector();
while (permissions.hasMoreElements()) {
NodePermission p = ((NodePermission)permissions.nextElement()).cloneObject();
p.setObject(uri.toString()); // switch to uri
result.add(p);
}
return result.elements();
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void putLock(Uri uri, NodeLock lock)
throws ServiceAccessException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeLock lockClone = lock.cloneObject();
lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
super.putLock(resourceId, lockClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void renewLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeLock lockClone = lock.cloneObject();
lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
super.renewLock(resourceId, lockClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void removeLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeLock lockClone = lock.cloneObject();
lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
super.removeLock(resourceId, lockClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void killLock(Uri uri, NodeLock lock)
throws ServiceAccessException, LockTokenNotFoundException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeLock lockClone = lock.cloneObject();
lockClone.setObjectUri(resourceId.getUuri()); // switch to uuri
super.killLock(resourceId, lockClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public Enumeration enumerateLocks(Uri uri)
throws ServiceAccessException {
try {
Enumeration locks = super.enumerateLocks(obtainResourceId(uri));
Vector result = new Vector();
while (locks.hasMoreElements()) {
NodeLock l = ((NodeLock)locks.nextElement()).cloneObject();
l.setObjectUri(uri.toString()); // switch to uri
result.add(l);
}
return result.elements();
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
NodeRevisionDescriptors nrdsClone =
super.retrieveRevisionDescriptors(obtainResourceId(uri)).cloneObject();
nrdsClone.setUri(uri.toString());
return nrdsClone;
}
catch (ObjectNotFoundException e) {
// TODO: throw RevisionDescriptorsNotFoundException???
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void createRevisionDescriptors
(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeRevisionDescriptors nrdsClone = revisionDescriptors.cloneObject();
nrdsClone.setUri(resourceId.getUuri()); // switch to uuri
super.createRevisionDescriptors(resourceId, nrdsClone);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void storeRevisionDescriptors
(Uri uri, NodeRevisionDescriptors revisionDescriptors)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
ResourceId resourceId = obtainResourceId(uri);
NodeRevisionDescriptors nrdsClone = revisionDescriptors.cloneObject();
nrdsClone.setUri(resourceId.getUuri()); // switch to uuri
super.storeRevisionDescriptors(resourceId, nrdsClone);
}
catch (ObjectNotFoundException e) {
// TODO: throw RevisionDescriptorsNotFoundException???
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void removeRevisionDescriptors(Uri uri)
throws ServiceAccessException {
try {
super.removeRevisionDescriptors(obtainResourceId(uri));
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public NodeRevisionDescriptor retrieveRevisionDescriptor
(Uri uri, NodeRevisionNumber revisionNumber)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
ObjectNode objectNode = doRetrieveObjectNode(uri);
ResourceId resourceId = obtainResourceId(uri, objectNode);
NodeRevisionDescriptor nrd = super.retrieveRevisionDescriptor(resourceId, revisionNumber);
nrd.setProperty("resource-id", resourceId.asXml());
nrd.setProperty("parent-set", getXmlParentSet(uri, objectNode));
return nrd;
}
catch (ObjectNotFoundException e) {
// TODO: throw RevisionDescriptorNotFoundException???
throw new ServiceAccessException(this, e);
}
}
public String getXmlParentSet(Uri uri, ObjectNode objectNode) throws ServiceAccessException, ObjectNotFoundException {
ResourceId resourceId = obtainResourceId(uri, objectNode);
// if objectNode is the root of a store, parent-uuri.equals(""),
// thus we cannot call getOneParentUri because
// we cannot resolve the uuri
boolean useBinding = Configuration.useBinding(this) && !resourceId.isStoreRoot();
XMLValue result = new XMLValue();
Enumeration parentBindings = objectNode.enumerateParentBindings();
while (parentBindings.hasMoreElements()) {
ObjectNode.Binding parentBinding = (ObjectNode.Binding) parentBindings.nextElement();
Element parentElm = new Element("parent", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
Element hrefElm = new Element("href", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
String parentUriStr = new UriPath(objectNode.getUri()).parent().toString();
Uri parentUri = new Uri(uri.getToken(), uri.getNamespace(), parentUriStr);
String uriStr;
if (useBinding) {
ResourceId parentResourceId = ResourceId.create(parentUri, parentBinding.getUuri());
uriStr = getOneUri(parentResourceId);
}
else {
uriStr = parentUriStr;
}
hrefElm.setText(uriStr);
parentElm.addContent(hrefElm);
Element segmentElm = new Element("segment", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
segmentElm.setText(parentBinding.getName());
parentElm.addContent(segmentElm);
result.add(parentElm);
}
return result.toString();
}
public String getOneUri(ResourceId resourceId) throws ServiceAccessException, ObjectNotFoundException {
String result = "";
while (!resourceId.isStoreRoot()) {
ObjectNode objectNode = super.retrieveObject(resourceId);
Enumeration enum = objectNode.enumerateParentBindings();
if (!enum.hasMoreElements()) {
throw new IllegalStateException();
}
ObjectNode.Binding parentBinding = (ObjectNode.Binding) enum.nextElement();
String parentSegment = parentBinding.getName();
result = "/" + parentSegment + result;
resourceId = ResourceId.create(resourceId, parentBinding.getUuri());
}
return "/".equals(resourceId.getScope().toString())
? result
: resourceId.getScope()+result;
}
// overwrites inherited
public void createRevisionDescriptor
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
try {
revisionDescriptor.removeProperty("resource-id");
revisionDescriptor.removeProperty("parent-set");
super.createRevisionDescriptor(obtainResourceId(uri), revisionDescriptor);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void storeRevisionDescriptor
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionDescriptorNotFoundException {
try {
revisionDescriptor.removeProperty("resource-id");
revisionDescriptor.removeProperty("parent-set");
super.storeRevisionDescriptor(obtainResourceId(uri), revisionDescriptor);
}
catch (ObjectNotFoundException e) {
// TODO: throw RevisionDescriptorNotFoundException???
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber number)
throws ServiceAccessException {
try {
super.removeRevisionDescriptor(obtainResourceId(uri), number);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public NodeRevisionContent retrieveRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException, RevisionNotFoundException {
try {
// TODO: throw RevisionNotFoundException???
return super.retrieveRevisionContent(obtainResourceId(uri), revisionDescriptor);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void createRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionAlreadyExistException {
try {
super.createRevisionContent(obtainResourceId(uri), revisionDescriptor, revisionContent);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void storeRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent)
throws ServiceAccessException, RevisionNotFoundException {
try {
// TODO: throw RevisionNotFoundException???
super.storeRevisionContent(obtainResourceId(uri), revisionDescriptor, revisionContent);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// overwrites inherited
public void removeRevisionContent
(Uri uri, NodeRevisionDescriptor revisionDescriptor)
throws ServiceAccessException {
try {
super.removeRevisionContent(obtainResourceId(uri), revisionDescriptor);
}
catch (ObjectNotFoundException e) {
throw new ServiceAccessException(this, e);
}
}
// ================================================================
/**
* NodeStore accessor
*/
public NodeStore getNodeStore() {
return nodeStore;
}
/**
* Always returns false. Default implementation for this method
* Stores that support binding should override this method.
*/
public boolean useBinding() {
return "true".equalsIgnoreCase((String)getParameter("useBinding"));
}
/**
* Worker method to retrieve the ObjectNode. Resolve if binding is enabled.
*
* @param uri an Uri
* @return an ObjectNode
* @throws ServiceAccessException
* @throws ObjectNotFoundException
*/
private ObjectNode doRetrieveObjectNode( Uri uri ) throws ServiceAccessException, ObjectNotFoundException {
try {
if (isForceStoreEnlistment(uri)) {
return doRetrieveObjectNode( uri, TLock.WRITE_LOCK, TLock.READ_LOCK);
} else {
// we cannot be sure there's a transaction. Locks could get lost
// if there's no commit
return doRetrieveObjectNode( uri, TLock.NO_LOCK, TLock.NO_LOCK);
}
}
catch (TLockedException e) {
throw new ServiceAccessException(this, new ConflictException(uri.toString()));
}
}
private ObjectNode doRetrieveObjectNode(Uri uri, int lockType, int parentLockType)
throws TLockedException, ServiceAccessException, ObjectNotFoundException {
ObjectNode result;
synchronized (tlockManager) {
if (Configuration.useBinding(this)) {
result = doResolve(uri, lockType, parentLockType);
result.setUuri(result.getUri());
result.setUri(uri.toString()); // switch to uri
} else {
ResourceId resourceId = ResourceId.create(uri, uri.toString());
tlockManager.lock(resourceId, uri.toString(), lockType);
// call super such that e.g. caching can take place
result = super.retrieveObject(uri);
result.setUuri(result.getUri());
}
}
return result;
}
/**
* Worker method that actually resolves the uri.
*/
private ObjectNode doResolve(Uri uri, int lockType, int parentLockType) throws TLockedException, ObjectNotFoundException, ServiceAccessException {
// check resolve cache first
ResourceId resourceId = checkResolveCache(uri);
if (resourceId == null) {
UriPath uriPath = new UriPath(uri.toString());
String[] segments = uriPath.tokens();
String rootUriStr = uri.getScope().toString();
String currentUriStr = rootUriStr;
Uri currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
ResourceId currentResourceId = ResourceId.create(currentUri, currentUriStr);
int start = new UriPath(rootUriStr).tokens().length;
for (int i = start; i < segments.length; i++) {
tlockManager.lock(currentResourceId, currentUriStr, parentLockType);
// cacheResolve(currentUri, currentResourceId);
// TODO: make it work with caching here :-(
// call super such that e.g. caching can take place
ObjectNode objectNode = super.retrieveObject(currentResourceId);
currentUriStr = uriPath.subUriPath(0, i + 1).toString();
currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
String currentUuri = objectNode.getBindingUuri(segments[i]);
if (currentUuri == null) {
throw new ObjectNotFoundException(currentUriStr);
}
currentResourceId = ResourceId.create(currentUri, currentUuri);
}
resourceId = currentResourceId;
// cache resolve result
// cacheResolve(uri, resourceId);
// TODO: make it work with caching here :-(
}
// else {
// doTLock(uri, resourceId, lockType, parentLockType);
// }
// TODO: make it work with caching here :-(
tlockManager.lock(resourceId, uri.toString(), lockType);
// call super such that e.g. caching can take place
return super.retrieveObject(resourceId);
}
private void doTLock(Uri uri, ResourceId resourceId, int lockType, int parentLockType) throws TLockedException, ObjectNotFoundException, ServiceAccessException {
UriPath uriPath = new UriPath(uri.toString());
String[] segments = uriPath.tokens();
int start = new UriPath(uri.getScope().toString()).tokens().length;
for (int i = start; i < segments.length; i++) {
String currentUriStr = uriPath.subUriPath(0, i).toString();
Uri currentUri = new Uri(uri.getToken(), uri.getNamespace(), currentUriStr);
// ResourceId currentResourceId = obtainResourceId(currentUri);
ResourceId currentResourceId = checkResolveCache(currentUri);
if (currentResourceId == null) {
currentResourceId = obtainResourceId(currentUri);
}
tlockManager.lock(currentResourceId, currentUriStr, parentLockType);
}
tlockManager.lock(resourceId, uri.toString(), lockType);
}
private void cacheResolve(Uri uri, ResourceId resourceId) {
if (uri.getToken() != null) {
uri.getToken().cacheResolve(uri, resourceId);
// System.out.println("@@@ >>> "+uri+"->"+resourceId);
}
}
private ResourceId checkResolveCache(Uri uri) {
ResourceId resourceId = null;
if (uri.getToken() != null) {
resourceId = uri.getToken().checkResolveCache(uri);
}
return resourceId;
}
private ResourceId obtainResourceId(Uri uri) throws ServiceAccessException, ObjectNotFoundException {
ObjectNode objectNode = doRetrieveObjectNode(uri);
ResourceId resourceId = ResourceId.create(uri, objectNode.getUuri());
return resourceId;
}
private ResourceId obtainResourceId(Uri uri, ObjectNode objectNode) throws ServiceAccessException, ObjectNotFoundException {
ResourceId resourceId = ResourceId.create(uri, objectNode.getUuri());
return resourceId;
}
}
1.1 jakarta-slide/src/share/org/apache/slide/store/ResourceId.java
Index: ResourceId.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/ResourceId.java,v 1.1 2003/12/27 14:54:37 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/12/27 14:54:37 $
*
* ====================================================================
*
* 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.store;
import java.util.Enumeration;
import org.apache.slide.common.Namespace;
import org.apache.slide.common.Scope;
import org.apache.slide.common.SlideToken;
import org.apache.slide.common.Uri;
import org.apache.slide.common.UriPath;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.store.Store;
import org.apache.slide.util.Configuration;
import org.apache.slide.util.XMLValue;
import org.jdom.Element;
/**
* Uniquely identifies a resource. The main operation with ResourceIds is equals. Immutable.
*
* Technically, ResourceId extends Uri, but the only reason to do so is compatibility with
* existing store interfaces. Logically, a ResourceId is *not* an Uri: Uris have a structure,
* resourceId have not. Consequently, almost all Uri methods in this class throw
* UnsupportedOperation exceptions.
*
* @author michael.hartmeier@softwareag.com
* @author peter.nevermann@softwareag.com
* @version $Revision: 1.1 $
*/
public final class ResourceId extends Uri {
public static String RESOURCE_ID_SCHEMA = "urn:uuid:";
/**
** There are probably no two jvm's working on the same database that initialitzing this
** class at the same mill second
**/
private static final String TIMESTAMP = String.valueOf(System.currentTimeMillis());
/**
** Number of uuri created in this JVM session
**/
private static int counter = 0;
/**
* @pre uriStr has to contain store prefix, i.e. extractStoreUri has to succeed
*/
public static ResourceId createNew(Uri uri) {
String newUuri;
boolean useBinding = Configuration.useBinding(uri.getStore());
if (useBinding) {
String scopeSlash = uri.getScope().toString();
if (!"/".equals(scopeSlash)) {
scopeSlash += "/";
}
synchronized (ResourceId.class) {
newUuri = uri.isStoreRoot()
? scopeSlash
: scopeSlash+TIMESTAMP+"."+counter++;
}
} else {
newUuri = uri.toString();
}
return new ResourceId(uri, newUuri);
}
public static ResourceId create(Uri uri, String uuri) {
return new ResourceId(uri, uuri);
}
private static String resourceIdSchema(Store store) {
if (Configuration.useBinding(store)) {
return RESOURCE_ID_SCHEMA;
}
else {
return "";
}
}
private final String uuri;
/**
* Constructor
*
* @param uri an Uri
* @param id /scope/identifier
*
*/
private ResourceId(Uri uri, String uuri) {
super(uri.getToken(), uri.getNamespace(), uri.toString());
this.uuri = uuri;
}
/**
* Tests equivalence of two ResourceIds.
*
* @param obj Object to test
* @return boolean
*/
public boolean equals(Object obj) {
ResourceId resourceId;
if (obj instanceof ResourceId) {
resourceId = (ResourceId) obj;
return getNamespace() == resourceId.getNamespace() &&
getStore() == resourceId.getStore() && uuri.equals(resourceId.uuri);
} else {
return false;
}
}
public String toString() {
return uuri;
}
/**
* Intentionally does not return anything like the origianl uri.
*
* @return String
*/
public String getUuri() {
return uuri;
}
/**
* Hash code.
*
* @return int hash code
*/
public int hashCode() {
return super.hashCode();
}
public Scope getScope() {
return super.getScope();
}
public Store getStore() {
return super.getStore();
}
public SlideToken getToken() {
return super.getToken();
}
public Namespace getNamespace() {
return super.getNamespace();
}
public boolean isStoreRoot() {
UriPath thisPath = new UriPath(uuri);
UriPath scopePath = new UriPath(scope.toString());
return thisPath.equals(scopePath);
}
// -------------------------------------------------------------
public void setUri(String uri) {
throw new UnsupportedOperationException();
}
public Enumeration getScopes() {
throw new UnsupportedOperationException();
}
public void setToken(SlideToken token) {
throw new UnsupportedOperationException();
}
public Uri getParentUri() {
throw new UnsupportedOperationException();
}
public void invalidateServices() {
throw new UnsupportedOperationException();
}
public void reconnectServices() {
throw new UnsupportedOperationException();
}
public String getRelative() {
throw new UnsupportedOperationException();
}
/**
* Do not clone ResourceId's, use aliasing.
*/
public Uri cloneObject() {
throw new UnsupportedOperationException();
}
public boolean isParent(Uri uri) {
throw new UnsupportedOperationException();
}
public String asXml() {
XMLValue r = new XMLValue();
Element hrefElm = new Element("href", NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
hrefElm.setText(resourceIdSchema(getStore())+getUuri());
r.add(hrefElm);
return r.toString();
}
}
1.1 jakarta-slide/src/share/org/apache/slide/store/tlock/TLock.java
Index: TLock.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/tlock/TLock.java,v 1.1 2003/12/27 14:54:37 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/12/27 14:54:37 $
*
* ====================================================================
*
* 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.store.tlock;
import org.apache.slide.store.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Transient locking which persists until commit/rollback. ResourceLock is a shared lock (aka
* 'ReadWriteLock'), it permits any number of readers as long as there is no writer.
* Writer have exclusive access. Acquired before an aspect of a given ResourceId is accessed.
* Released once during commit or abort. ResourceLock is a helper class for LockManager - nobody
* else should know about it.
*
* @author michael.hartmeier@softwareag.com
* @author peter.nevermann@softwareag.com
* @version $Revision: 1.1 $
*/
public class TLock {
// lock types
// Caution: the lock type is relative to the current thread. E.g. if thread A holds a
// write Lock W, W's lock type releated to thread B is NO_LOCK.
public static final int NO_LOCK = 0;
public static final int READ_LOCK = 1;
public static final int WRITE_LOCK = 2;
//--
private final long timeout;
private final Object sync;
private final ResourceId resourceId;
private int waitingWriter;
/** List of threads. Never contains activeWriter **/
private final List activeReader;
private Thread activeWriter;
public TLock(Object sync, long timeout, ResourceId resourceId) {
if (resourceId == null) {
throw new IllegalArgumentException();
}
this.timeout = timeout;
this.sync = sync;
this.resourceId = resourceId;
this.waitingWriter = 0;
this.activeReader = new ArrayList();
this.activeWriter = null;
}
public Thread getActiveWriter() {
return activeWriter;
}
public ResourceId getResourceId() {
return resourceId;
}
/**
** Obtains read or write lock for the current thread.
** The lock will persist til end of transaction.
**
** @return current thread's lock type previously hold by current thread
**/
public int acquire(int type) throws TLockedException {
switch (type) {
case NO_LOCK:
return getType();
case READ_LOCK:
return acquireReader();
case WRITE_LOCK:
return acquireWriter();
default:
throw new IllegalArgumentException("acquire failed." + type + " is invalid");
}
}
public int getType() {
return getType(Thread.currentThread());
}
public int getType(Thread current) {
if (activeWriter == current) {
return WRITE_LOCK;
}
if (activeReader.contains(current)) {
return READ_LOCK;
}
return NO_LOCK;
}
/**
** @return current thread's lock type that has been released by this method.
**/
public int release() {
Thread current;
current = Thread.currentThread();
if (current == activeWriter) {
activeWriter = null;
logSuccess("-w");
sync.notifyAll();
return WRITE_LOCK;
}
if (activeReader.remove(current)) {
logSuccess("-r");
sync.notifyAll();
return READ_LOCK;
}
return NO_LOCK;
}
/**
** @return true if there is any thread with lock type != NO_LOCK
**/
public boolean isLocked() {
return activeWriter != null || activeReader.size() > 0;
}
public String toString() {
String activeWriterName = (activeWriter!=null)?activeWriter.getName():"NULL";
return "TLock[uuri=" + resourceId+", hashCode=" + Integer.toHexString(hashCode())
+ ", writer=" + activeWriterName + ", reader=" + activeReader + ", waiting=" + waitingWriter
+ "]";
}
//--
/**
** Obtains a read lock for the current thread.
** The lock will persist till end of transaction.
**
** @return lock type previously hold by current thread
**/
private int acquireReader() throws TLockedException {
Thread current;
current = Thread.currentThread();
if (current == activeWriter) {
//logSuccess("acquireReader: already write locked");
return WRITE_LOCK;
}
if (activeReader.contains(current)) {
//logSuccess("acquireReader: already read locked");
return READ_LOCK;
}
awaitReader();
activeReader.add(current);
logSuccess("+r");
return NO_LOCK;
}
/**
** Obtains a write lock for the current thread.
** The lock will persist til end of transaction.
**
** @return lock type previously hold by current thread
**/
private int acquireWriter() throws TLockedException {
Thread current;
current = Thread.currentThread();
if (current == activeWriter) {
//logSuccess("acquireWriter: already write locked");
return WRITE_LOCK;
}
waitingWriter++;
try {
awaitWriter();
} finally {
waitingWriter--;
}
activeWriter = current;
if (activeReader.remove(current)) {
logSuccess("!w");
return READ_LOCK;
} else {
logSuccess("+w");
return NO_LOCK;
}
}
private void awaitReader() throws TLockedException {
long started;
long remaining;
if (allowReader()) {
return;
}
started = System.currentTimeMillis();
for (remaining = timeout; remaining > 0; remaining -= System.currentTimeMillis() - started) {
logSuccess("?r");
try {
sync.wait(remaining);
} catch (InterruptedException e) {
// fall through
}
if (allowReader()) {
return;
}
}
throw timedOut();
}
private void awaitWriter() throws TLockedException {
long started;
long remaining;
if (allowWriter()) {
return;
}
started = System.currentTimeMillis();
for (remaining = timeout; remaining > 0; remaining -= System.currentTimeMillis() - started) {
logSuccess("?w");
try {
sync.wait(remaining);
} catch (InterruptedException e) {
// fall through
}
if (allowWriter()) {
return;
}
}
throw timedOut();
}
private boolean allowReader() {
return activeWriter == null && waitingWriter == 0;
}
private boolean allowWriter() {
if (activeWriter != null) {
return false;
}
switch (activeReader.size()) {
case 0:
return true;
case 1:
return activeReader.get(0) == Thread.currentThread();
default:
return false;
}
}
private TLockedException timedOut() {
logSuccess("##");
return new TLockedException("ResourceLock wait timed out: " + toString());
}
private void logSuccess(String operation) {
// printlnSuccess(operation);
}
private void printlnSuccess(String operation) {
String activeWriterName = (activeWriter != null)? activeWriter.getName() : "NULL";
List activeReaderList = new ArrayList(activeReader){
public String toString(){
String result = "[";
Iterator iter = this.iterator();
while (iter.hasNext()) {
result = result + ((Thread)iter.next()).getName() + ",";
}
return result + "]";
}};
String uuri = resourceId.getUuri();
// try { uri = XNodeRevisionDescriptor.getOneUri((IDescriptorsHandler)sync, readerDesc.getUuri()); }
// catch (Throwable e) { }
if (operation.equals("##")) {
System.out.println(" *** " +
Thread.currentThread().getName() + " \t" +
operation + " " +
"uuri=" + uuri
+ ", writer=" + activeWriterName + ", reader=" + activeReaderList + ", waiting=" + waitingWriter
);
// if (operation.equals("##")) {
// TODO: do some more reporting [in the future]
}
}
}
1.1 jakarta-slide/src/share/org/apache/slide/store/tlock/TLockedException.java
Index: TLockedException.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/tlock/TLockedException.java,v 1.1 2003/12/27 14:54:37 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/12/27 14:54:37 $
*
* ====================================================================
*
* 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.store.tlock;
/**
* This exception signals that a thread cannot obtain a resource for write
* because it is t-locked by another thread.
*
* @author michael.hartmeier@softwareag.com
* @author peter.nevermann@softwareag.com
* @version $Revision: 1.1 $
*/
public class TLockedException extends Exception {
/**
* Constructor with message and descriptors.
* @param msg the message
* @param d the descriptors
*/
public TLockedException(String msg) {
super(msg);
}
}
1.1 jakarta-slide/src/share/org/apache/slide/store/tlock/TLockManager.java
Index: TLockManager.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/store/tlock/TLockManager.java,v 1.1 2003/12/27 14:54:37 pnever Exp $
* $Revision: 1.1 $
* $Date: 2003/12/27 14:54:37 $
*
* ====================================================================
*
* 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.store.tlock;
import org.apache.slide.store.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Handles t-locks (transient locks) for multi-thread synchronization in the stores.
*
* @author michael.hartmeier@softwareag.com
* @author peter.nevermann@softwareag.com
* @version $Revision: 1.1 $
*/
public class TLockManager {
private final Map threadMap; // thread-name -> list-of-locks
private final Map lockMap; // resource-id -> lock
private final long timeout;
/**
* Default constructor.
*
* @pre childStore != null
* @post globalCache != null
* @post deltas != null
*/
public TLockManager(long timeout) {
this.timeout = timeout;
this.threadMap = new HashMap();
this.lockMap = new HashMap();
}
public synchronized void lock(ResourceId resourceId, String uri, int lockType) throws TLockedException {
TLock lock;
int oldLockType;
if (lockType != TLock.NO_LOCK) {
if (uri == null) {
throw new IllegalArgumentException();
}
}
lock = (TLock)lockMap.get(resourceId);
if (lock != null) {
oldLockType = lock.acquire(lockType);
if (oldLockType == TLock.NO_LOCK) {
if (lockType != TLock.NO_LOCK) {
addLock(lock);
// System.out.println("@@@ L "+uri+","+lockType);
}
}
} else {
create(lockType, uri, resourceId);
}
}
public synchronized void releaseLocks() {
List locks = (List)threadMap.get(Thread.currentThread());
if (locks != null) {
Iterator i = locks.iterator();
while( i.hasNext() ) {
TLock lock = (TLock) i.next();
lockMap.remove(lock.getResourceId());
lock.release();
}
threadMap.remove(Thread.currentThread());
}
}
/**
* Creates an aquires a new ResourceLock.
*/
public TLock create(int lockType, String uri, ResourceId resourceId) {
TLock lock = new TLock(this, timeout, resourceId);
try {
if (lock.acquire(lockType) != TLock.NO_LOCK) {
// we've just created the TLock object - nobody else can see/look ip
throw new IllegalStateException();
}
} catch (TLockedException e) {
// we've just created the TLock object - nobody else can see/look ip
throw new IllegalStateException(e.getMessage());
}
if (lockType != TLock.NO_LOCK) {
addLock(lock);
// System.out.println("@@@ C "+uri+","+lockType);
}
return lock;
}
private void addLock(TLock lock) {
List locks = (List)threadMap.get(Thread.currentThread());
if (locks == null) {
locks = new ArrayList();
threadMap.put(Thread.currentThread(), locks);
}
locks.add(lock);
lockMap.put(lock.getResourceId(), lock);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org