Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2005-2006 webdav-servlet group.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package net.sf.webdav;
 
some very simple locking management for concurrent data access, NOT the webdav locking. ( could that be used instead? )

Author(s):
re
 
 public class ResourceLocks {

after creating this much LockObjects, a cleanup delets unused LockObjects
 
 	private final int fCleanupLimit = 100000;
 
 	private int fCleanupCounter = 0;

keys: path value: LockObject from that path
 
 	private Hashtable fLocks = null;
 
 	// REMEMBER TO REMOVE UNUSED LOCKS FROM THE HASHTABLE AS WELL
 
 	private LockObject fRoot = null;
 
 	protected ResourceLocks() {
 		this. = new Hashtable();
 		 = new LockObject("/");
 	}

trys to lock the resource at "path".

Parameters:
path what resource to lock
owner the owner of the lock
exclusive if the lock should be exclusive (or shared)
Returns:
true if the resource at path was successfully locked, false if an existing lock prevented this
 
 	protected synchronized boolean lock(String pathString owner,
 			boolean exclusiveint depth) {
 
 		if (lo.checkLocks(exclusivedepth)) {
 			if (lo.addLockObjectOwner(owner)) {
 				lo.fExclusive = exclusive;
 				return true;
 			} else {
 				return false;
 			}
 		} else {
 			// can not lock
 			return false;
 		}
 	}

unlocks all resources at "path" (and all subfolders if existing)

that have the same owner

Parameters:
path what resource to unlock
owner who wants to unlock
 
 	protected synchronized void unlock(String pathString owner) {
 
 		if (this..containsKey(path)) {
 			LockObject lo = (LockObjectthis..get(path);
 			// System.out.println("number of LockObjects in the hashtable: "
 			//		+ fLocks.size());
 
 		}else{
 			// there is no lock at that path. someone tried to unlock it
 			// anyway. could point to a problem
			..println("net.sf.webdav.ResourceLocks.unlock(): no lock for path "+path);
		}
		}
	}

generates LockObjects for the resource at path and its parent folders. does not create new LockObjects if they already exist

Parameters:
path path to the (new) LockObject
Returns:
the LockObject for path.
		// System.out.println("generateLockObjects path: " + path + "<end>");
		if (!this..containsKey(path)) {
			LockObject parentLockObject = generateLockObjects(getParentPath(path));
			LockObject returnObject = new LockObject(path);
			parentLockObject.addChild(returnObject);
			returnObject.fParent = parentLockObject;
			return returnObject;
else {
			return (LockObjectthis..get(path);
		}
	}

deletes unused LockObjects and resets the counter
	private boolean cleanLockObjects(LockObject lo) {
		if (lo.fChildren == null) {
			if (lo.fOwner == null) {
				return true;
else {
				return false;
			}
else {
			boolean canDelete = true;
			int limit = lo.fChildren.length;
			for (int i = 0; i < limiti++) {
				if (!cleanLockObjects(lo.fChildren[i])) {
					canDelete = false;
				}else{
					// because the deleting shifts the array
					i--;
					limit--;
				}
			}
			if (canDelete) {
				if (lo.fOwner == null) {
					return true;
else {
					return false;
				}
else {
				return false;
			}
		}
	}
	private String getParentPath(String path) {
		int slash = path.lastIndexOf('/');
		if (slash == -1) {
			return null;
else {
			if (slash == 0) {
				// return "root" if parent path is empty string
				return "/";
else {
				return path.substring(0, slash);
			}
		}
	}
	// ----------------------------------------------------------------------------
	private class LockObject {
owner of the lock. shared locks can have multiple owners. is null if no owner is present
		String[] fOwner = null;

children of that lock
		LockObject[] fChildren = null;
		LockObject fParent = null;

weather the lock is exclusive or not. if owner=null the exclusive value doesn't matter
		boolean fExclusive = false;

Parameters:
path the path to the locked object
owner a String that represents the owner of the lock
exclusive true if the lock is exclusive, false otherwise
			this. = path;
			.put(paththis);
		}

adds a new owner to a lock

Parameters:
owner string that represents the owner
Returns:
true if the owner was added, false otherwise
		boolean addLockObjectOwner(String owner) {
			if (this. == null) {
				this. = new String[1];
else {
				int size = this..length;
				String[] newLockObjectOwner = new String[size + 1];
				// check if the owner is already here (that should actually not
				// happen)
				for (int i = 0; i < sizei++) {
					if (this.[i].equals(owner)) {
						return false;
					}
				}
				for (int i = 0; i < sizei++) {
					newLockObjectOwner[i] = this.[i];
				}
				this. = newLockObjectOwner;
			}
			this.[this..length - 1] = owner;
			return true;
		}

tries to remove the owner from the lock

Parameters:
owner string that represents the owner
			if (this. != null) {
				int size = this..length;
				for (int i = 0; i < sizei++) {
					// check every owner if it is the requested one
					if (this.[i].equals(owner)) {
						// remove the owner
						String[] newLockObjectOwner = new String[size - 1];
						for (int i2 = 0; i2 < (size - 1); i2++) {
							if (i2 < i) {
								newLockObjectOwner[i2] = this.[i2];
else {
								newLockObjectOwner[i2] = this.[i2 + 1];
							}
						}
						this. = newLockObjectOwner;
					}
				}
				if (this..length == 0) {
					this. = null;
				}
			}
		}
		void addChild(LockObject newChild) {
			if (this. == null) {
				this. = new LockObject[0];
			}
			int size = this..length;
			LockObject[] newChildren = new LockObject[size + 1];
			for (int i = 0; i < sizei++) {
				newChildren[i] = this.[i];
			}
			newChildren[size] = newChild;
			this. = newChildren;
		}

deletes this Lock object. assumes that it has no children and no owners (does not check this itself)
			if (this != ) {
				// removing from tree
				int size = this...length;
				for (int i = 0; i < sizei++) {
					if (this..[i].equals(this)) {
						LockObject[] newChildren = new LockObject[size - 1];
						for (int i2 = 0; i2 < (size - 1); i2++) {
							if (i2 < i) {
								newChildren[i2] = this..[i2];
else {
								newChildren[i2] = this..[i2 + 1];
							}
						}
						if (newChildren.length != 0) {
							this.. = newChildren;
else {
							this.. = null;
						}
						break;
					}
				}
				// removing from hashtable
				// now the garbage collector has some work to do
			}
		}

Parameters:
exclusive wheather the new lock should be exclusive
Returns:
true if the lock can be placed
		boolean checkLocks(boolean exclusiveint depth) {
			return (checkParents(exclusive) && checkChildren(exclusivedepth));
		}

Parameters:
exclusive wheather the new lock should be exclusive
Returns:
true if no locks at the parent path are forbidding a new lock
		private boolean checkParents(boolean exclusive) {
			if (this..equals("/")) {
				return true;
else {
				if (this. == null) {
					// no owner, checking parents
					return this..checkParents(exclusive);
else {
					// there already is a owner
					if (this. || exclusive) {
						// the new lock and/or the old lock are exclusive
						return false;
else {
						// new and old lock are shared
						return this..checkParents(exclusive);
					}
				}
			}
		}

Parameters:
exclusive wheather the new lock should be exclusive
Returns:
true if no locks at the children paths are forbidding a new lock
		private boolean checkChildren(boolean exclusiveint depth) {
			if (this. == null) {
				// a file
				if (this. == null) {
					// no owner
					return true;
else {
					// there already is a owner
					if (this. || exclusive) {
						// the new lock and/or the old lock are exclusive
						return false;
else {
						// new and old lock are shared
						return true;
					}
				}
else {
				// a folder
				if (this. == null) {
					// no owner, checking children
					if (depth!=0){
					boolean canLock = true;
					int limit = this..length;
					for (int i = 0; i < limiti++) {
						if (!this.[i].checkChildren(exclusive,depth-1)) {
							canLock = false;
						}
					}
					return canLock;
					}else{
						// depth == 0  -> we don't care for children
						return true;
					}
else {
					// there already is a owner
					if (this. || exclusive) {
						// the new lock and/or the old lock are exclusive
						return false;
else {
						// new and old lock are shared.
						// the old lock was successfully placed, so i can add
						// the new one as well, since it has the same requirements
						return true;
					}
				}
			}
		}
	}
New to GrepCode? Check out our FAQ X