001: package com.ibm.webdav.fileSystem;
002:
003: /*
004: * (C) Copyright IBM Corp. 2000 All rights reserved.
005: *
006: * The program is provided "AS IS" without any warranty express or
007: * implied, including the warranty of non-infringement and the implied
008: * warranties of merchantibility and fitness for a particular purpose.
009: * IBM will not be liable for any damages suffered by you as a result
010: * of using the Program. In no event will IBM be liable for any
011: * special, indirect or consequential damages or lost profits even if
012: * IBM has been advised of the possibility of their occurrence. IBM
013: * will not be liable for any third party claims against you.
014: *
015: * Portions Copyright (C) Simulacra Media Ltd, 2004.
016: */
017: import java.util.*;
018:
019: import javax.xml.parsers.*;
020:
021: import org.w3c.dom.*;
022:
023: import com.ibm.webdav.*;
024: import com.ibm.webdav.impl.*;
025:
026: /** Implement the LockManager interface using the resource's
027: * PropertiesManager to persist the DAV:lockdiscovery property.
028: * @author Jim Amsden <jamsden@us.ibm.com>
029: * @see PropertiesManager
030: * @see CachedPropertiesManager
031: */
032: public class LockManager implements com.ibm.webdav.impl.LockManager {
033: private ResourceImpl resource = null;
034: private com.ibm.webdav.impl.PropertiesManager propertiesManager = null;
035:
036: public LockManager() {
037: }
038:
039: /** Create a lock manager for the given resource.
040: * @param resource the resource to manage locks for
041: * @param namespaceManager its namespace manager
042: * @param propertiesManager and its properties manager
043: */
044: public LockManager(ResourceImpl resource,
045: com.ibm.webdav.impl.NamespaceManager namespaceManager,
046: com.ibm.webdav.impl.PropertiesManager propertiesManager) {
047: initialize(resource, namespaceManager, propertiesManager);
048: }
049:
050: /** Get the DAV:lockdiscovery property for the resource.
051: *
052: * @return an Element with tag name D:lockdiscovery
053: * @exception com.ibm.webdav.WebDAVException
054: */
055: public Element getLockDiscovery() throws WebDAVException {
056: // get the raw properties from the property manager
057: Document propertiesDocument = propertiesManager
058: .loadProperties();
059: Element properties = propertiesDocument.getDocumentElement();
060: Element lockdiscovery = (Element) ((Element) properties)
061: .getElementsByTagNameNS("DAV:", "lockdiscovery")
062: .item(0);
063:
064: // timeout any expired locks by
065: // deleting any locks that have timed out
066: boolean locksHaveChanged = false;
067: if (lockdiscovery != null) {
068: NodeList locks = ((Element) lockdiscovery)
069: .getElementsByTagNameNS("DAV:", "activelock");
070: Element lock = null;
071: Date now = new Date();
072: for (int i = 0; i < locks.getLength(); i++) {
073: lock = (Element) locks.item(i);
074: ActiveLock activeLock = new ActiveLock(lock);
075: // see if the lock has timed out
076: Date expiration = activeLock.getExpiration();
077: if (expiration != null && expiration.before(now)) {
078: // has timed out, remove the lock
079: locksHaveChanged = true;
080: try {
081: lockdiscovery.removeChild(lock);
082: } catch (Exception exc) {
083: exc.printStackTrace();
084: }
085: }
086: }
087: }
088: if (locksHaveChanged) {
089: propertiesManager.saveProperties(propertiesDocument);
090: }
091: return lockdiscovery;
092: }
093:
094: /** Get the locks that exist on this resource. May be null if the resource
095: * is not locked. Get the locks from the DAV:lockdiscovery property
096: *
097: * @return a Vector of ActiveLock objects
098: * @exception com.ibm.webdav.WebDAVException
099: */
100: public Vector getLocks() throws WebDAVException {
101: Element lockdiscovery = (Element) getLockDiscovery();
102: Vector allLocks = new Vector();
103: if (lockdiscovery != null) {
104: NodeList activeLocks = ((Element) lockdiscovery)
105: .getElementsByTagNameNS("DAV:", "activelock");
106: Element activeLock = null;
107: for (int i = 0; i < activeLocks.getLength(); i++) {
108: activeLock = (Element) activeLocks.item(i);
109: allLocks.addElement(new ActiveLock(activeLock));
110: }
111: }
112: return allLocks;
113: }
114:
115: /** Get information about locks supported by this resource.
116: * The file system supports shared and exclusive write locks.
117: *
118: * @return an Element with tag name D:supportedlock
119: */
120: public Element getSupportedLock() {
121: Document document = null;
122:
123: try {
124: document = DocumentBuilderFactory.newInstance()
125: .newDocumentBuilder().newDocument();
126: } catch (Exception e) {
127: e.printStackTrace(System.err);
128: }
129:
130: Element supportedlock = document
131: .createElement("D:supportedlock");
132: Element lockentry = document.createElement("D:lockentry");
133: supportedlock.appendChild(lockentry);
134: Element lockscope = document.createElement("D:lockscope");
135: lockscope.appendChild(document.createElement("D:exclusive"));
136: lockentry.appendChild(lockscope);
137: Element locktype = document.createElement("D:locktype");
138: locktype.appendChild(document.createElement("D:write"));
139: lockentry.appendChild(locktype);
140: lockentry = document.createElement("D:lockentry");
141: supportedlock.appendChild(lockentry);
142: lockscope = document.createElement("D:lockscope");
143: lockscope.appendChild(document.createElement("D:shared"));
144: lockentry.appendChild(lockscope);
145: locktype = document.createElement("D:locktype");
146: locktype.appendChild(document.createElement("D:write"));
147: lockentry.appendChild(locktype);
148:
149: return supportedlock;
150: }
151:
152: /** Initialize this lock manager
153: * @param resource the resource to manage locks for
154: * @param namespaceManager its namespace manager
155: * @param propertiesManager and its properties manager
156: */
157: public void initialize(ResourceImpl resource,
158: com.ibm.webdav.impl.NamespaceManager namespaceManager,
159: com.ibm.webdav.impl.PropertiesManager propertiesManager) {
160: this .resource = resource;
161: this .propertiesManager = propertiesManager;
162: }
163:
164: /** Lock this resource Using the given activeLock. Create the
165: * lock by adding a new active lock to the lock discovery property.
166: *
167: * @param activeLock the lock to activate (i.e., persist)
168: *
169: * @return a MultiStatus containing a lockdiscovery property indicating
170: * the results of the lock operation.
171: * @exception com.ibm.webdav.WebDAVException
172: */
173: public MultiStatus lock(ActiveLock activeLock)
174: throws WebDAVException {
175: Element activeLockEl = activeLock.asXML();
176: Document xmlDoc = activeLockEl.getOwnerDocument();
177: MultiStatus result = new MultiStatus();
178: PropertyResponse propertyResponse = new PropertyResponse(
179: resource.getURL().toString());
180: result.addResponse(propertyResponse);
181:
182: PropertyValue l = resource
183: .getProperty(PropertyName.pnLockdiscovery);
184: Element lockdiscovery = null;
185: if (l == null) {
186: lockdiscovery = xmlDoc.createElement("D:lockdiscovery");
187: lockdiscovery.setAttribute("xmlns:D", "DAV:");
188: } else {
189: lockdiscovery = (Element) ((Element) l.value)
190: .cloneNode(true);
191: }
192: lockdiscovery.appendChild(activeLockEl);
193: propertiesManager.setProperty("DAV:lockdiscovery",
194: lockdiscovery);
195:
196: // all lock methods return the lockdiscovery property, even if the lock failed
197: PropertyName propname = PropertyName
198: .createPropertyNameQuietly("DAV:lockdiscovery");
199:
200: propertyResponse.addProperty(propname,
201: (Element) ((Element) lockdiscovery).cloneNode(true),
202: WebDAVStatus.SC_OK);
203: return result;
204: }
205:
206: /** Refresh the lock on this resource by resetting the lock timeout.
207: * The context must contain the proper authorization for the requesting
208: * principal. Refresh the lock by updating the timeout element of the
209: * active lock in the lock discovery property.
210: *
211: * @param activeLock the lock to refresh. Contains the updated timeout
212: * and expiration date.
213: *
214: * @return updated information about the lock status of this resource
215: * @exception com.ibm.webdav.WebDAVException
216: */
217: public MultiStatus refreshLock(ActiveLock activeLock)
218: throws WebDAVException {
219: Element activeLockEl = activeLock.asXML();
220: Document xmlDoc = activeLockEl.getOwnerDocument();
221: MultiStatus result = new MultiStatus();
222: PropertyResponse propertyResponse = new PropertyResponse(
223: resource.getURL().toString());
224: result.addResponse(propertyResponse);
225:
226: // get the locks on this resource
227: PropertyValue l = resource
228: .getProperty(PropertyName.pnLockdiscovery);
229: Element lockdiscovery = null;
230: if (l == null) {
231: lockdiscovery = xmlDoc.createElement("D:lockdiscovery");
232: lockdiscovery.setAttribute("xmlns:D", "DAV:");
233: } else {
234: lockdiscovery = (Element) ((Element) l.value)
235: .cloneNode(true);
236: }
237:
238: // find the lock
239: boolean lockFound = false;
240: NodeList locks = ((Element) lockdiscovery)
241: .getElementsByTagNameNS("DAV:", "activelock");
242: Element lock = null;
243: for (int i = 0; i < locks.getLength(); i++) {
244: lock = (Element) locks.item(i);
245: ActiveLock aLock = new ActiveLock(lock);
246: if (aLock.getLockToken().equals(activeLock.getLockToken())) {
247: lockFound = true;
248: lockdiscovery.removeChild(lock);
249: break;
250: }
251: }
252: if (!lockFound) {
253: throw new WebDAVException(
254: WebDAVStatus.SC_PRECONDITION_FAILED,
255: "principal does not own a lock");
256: }
257: lockdiscovery.appendChild(activeLockEl);
258: propertiesManager.setProperty("DAV:lockdiscovery",
259: lockdiscovery);
260:
261: PropertyName propname = PropertyName
262: .createPropertyNameQuietly("DAV:lockdiscovery");
263: // all lock methods return the lockdiscovery property, even if the lock failed
264: propertyResponse.addProperty(propname,
265: (Element) ((Element) lockdiscovery).cloneNode(true),
266: WebDAVStatus.SC_OK);
267: return result;
268: }
269:
270: /** Unlock the lock identified by the lockToken on this resource by
271: * removing the active lock from the lock discovery property.
272: *
273: * @param activeLock the lock to unlock
274: *
275: * @return a MultiStatus containing any responses on resources that could not
276: * be unlocked.
277: * @exception com.ibm.webdav.WebDAVException
278: */
279: public MultiStatus unlock(ActiveLock activeLock)
280: throws WebDAVException {
281: Element activeLockEl = activeLock.asXML();
282: Document xmlDoc = activeLockEl.getOwnerDocument();
283: MultiStatus result = new MultiStatus();
284: PropertyResponse propertyResponse = new PropertyResponse(
285: resource.getURL().toString());
286: result.addResponse(propertyResponse);
287:
288: // get the locks on this resource
289: PropertyValue l = resource
290: .getProperty(PropertyName.pnLockdiscovery);
291: Element lockdiscovery = null;
292: if (l == null) {
293: lockdiscovery = xmlDoc.createElement("D:lockdiscovery");
294: lockdiscovery.setAttribute("xmlns:D", "DAV:");
295: } else {
296: lockdiscovery = (Element) ((Element) l.value)
297: .cloneNode(true);
298: }
299:
300: // find the lock
301: ActiveLock lockToRemove = null;
302: NodeList locks = ((Element) lockdiscovery)
303: .getElementsByTagNameNS("DAV:", "activelock");
304: Element lock = null;
305: for (int i = 0; i < locks.getLength(); i++) {
306: lock = (Element) locks.item(i);
307: ActiveLock aLock = new ActiveLock(lock);
308: if (aLock.getLockToken().equals(activeLock.getLockToken())) {
309: lockToRemove = aLock;
310: lockdiscovery.removeChild(lock);
311: break;
312: }
313: }
314: if (lockToRemove == null) {
315: throw new WebDAVException(
316: WebDAVStatus.SC_PRECONDITION_FAILED,
317: "resource is not locked with the given lock token");
318: } else {
319: propertiesManager.setProperty("DAV:lockdiscovery",
320: lockdiscovery);
321: }
322:
323: // all lock methods return the lockdiscovery property, even if the lock failed
324: PropertyName propname = PropertyName
325: .createPropertyNameQuietly("DAV:lockdiscovery");
326: propertyResponse.addProperty(propname,
327: (Element) ((Element) lockdiscovery).cloneNode(true),
328: WebDAVStatus.SC_OK);
329: return result;
330: }
331: }
|