You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2006/07/12 11:38:26 UTC
svn commit: r421206 - in /jackrabbit/trunk/jcr-server:
client/src/java/org/apache/jackrabbit/webdav/client/methods/
server/src/java/org/apache/jackrabbit/webdav/jcr/observation/
webdav/src/java/org/apache/jackrabbit/webdav/ webdav/src/java/org/apache/j...
Author: angela
Date: Wed Jul 12 02:38:25 2006
New Revision: 421206
URL: http://svn.apache.org/viewvc?rev=421206&view=rev
Log:
- add methods for observation to client
- minor improvements to observation impl in jcr-server
- fix client LockMethod and adjust LockDiscovery accordingly
- fix client MergeMethod adjust corresponding Info object accordingly
- improve UpdateInfo
- use CodedURLHeader instaed of building locktoken header manually
Added:
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java (with props)
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java (with props)
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java (with props)
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java (with props)
Modified:
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/DavMethodBase.java
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/LockMethod.java
jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/MergeMethod.java
jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/WebdavResponseImpl.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/header/TimeoutHeader.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/lock/LockDiscovery.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/EventDiscovery.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionDiscovery.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionInfo.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/MergeInfo.java
jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/UpdateInfo.java
Modified: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/DavMethodBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/DavMethodBase.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/DavMethodBase.java (original)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/DavMethodBase.java Wed Jul 12 02:38:25 2006
@@ -250,9 +250,7 @@
protected void processStatusLine(HttpState httpState, HttpConnection httpConnection) {
super.processStatusLine(httpState, httpConnection);
int code = getStatusCode();
- // default
- success = code < DavServletResponse.SC_BAD_REQUEST;
- // sub classes overwrites
+ // sub classes define if status code indicates success.
success = isSuccess(code);
}
@@ -265,7 +263,7 @@
* @param httpConnection
* @see HttpMethodBase#processResponseBody(HttpState, HttpConnection)
*/
- protected final void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
+ protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
// in case of multi-status response
if (getStatusCode() == DavServletResponse.SC_MULTI_STATUS) {
try {
Modified: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/LockMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/LockMethod.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/LockMethod.java (original)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/LockMethod.java Wed Jul 12 02:38:25 2006
@@ -18,17 +18,24 @@
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.DavMethods;
-import org.apache.jackrabbit.webdav.header.CodedUrlHeader;
import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.header.DepthHeader;
import org.apache.jackrabbit.webdav.header.IfHeader;
import org.apache.jackrabbit.webdav.header.TimeoutHeader;
-import org.apache.jackrabbit.webdav.lock.ActiveLock;
+import org.apache.jackrabbit.webdav.header.CodedUrlHeader;
import org.apache.jackrabbit.webdav.lock.LockInfo;
import org.apache.jackrabbit.webdav.lock.Scope;
import org.apache.jackrabbit.webdav.lock.Type;
+import org.apache.jackrabbit.webdav.lock.LockDiscovery;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.HttpConnection;
+import org.apache.commons.httpclient.Header;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
import java.io.IOException;
@@ -39,6 +46,9 @@
private static Logger log = LoggerFactory.getLogger(LockMethod.class);
+ private final boolean isRefresh;
+ private LockDiscovery lockDiscovery;
+
/**
* Creates a new <code>LockMethod</code>.
*
@@ -62,20 +72,21 @@
*/
public LockMethod(String uri, LockInfo lockInfo) throws IOException {
super(uri);
- if (lockInfo != null) {
+ if (lockInfo != null && !lockInfo.isRefreshLock()) {
TimeoutHeader th = new TimeoutHeader(lockInfo.getTimeout());
setRequestHeader(th);
- if (!lockInfo.isRefreshLock()) {
- DepthHeader dh = new DepthHeader(lockInfo.isDeep());
- setRequestHeader(dh);
- setRequestHeader(DavConstants.HEADER_CONTENT_TYPE, "text/xml; charset=UTF-8");
- setRequestBody(lockInfo);
- }
+ DepthHeader dh = new DepthHeader(lockInfo.isDeep());
+ setRequestHeader(dh);
+ setRequestHeader(DavConstants.HEADER_CONTENT_TYPE, "text/xml; charset=UTF-8");
+ setRequestBody(lockInfo);
+ isRefresh = false;
+ } else {
+ throw new IllegalArgumentException("Cannot create a LOCK request without lock info. Use the constructor taking lock tokens in order to build a LOCK request for refresh.");
}
}
/**
- * Create a new 'Refresh' lock method.
+ * Create a new Lock method used to 'REFRESH' an existing lock.
*
* @param uri
* @param timeout
@@ -88,18 +99,48 @@
setRequestHeader(th);
IfHeader ifh = new IfHeader(lockTokens);
setRequestHeader(ifh);
+ isRefresh = true;
}
- public ActiveLock getResponseAsLock() throws IOException {
+ /**
+ *
+ * @return
+ * @throws IOException
+ * @throws DavException
+ */
+ public LockDiscovery getResponseAsLockDiscovery() throws IOException, DavException {
checkUsed();
- // todo -> build lockdiscovery-prop -> retrieve activelock
- return null;
+ // lockDiscovery has been build while processing the response body.
+ // if its still null, this indicates that either the method failed
+ // or that the response body could not be parsed.
+ // in either case this is an error and will be reported to the caller.
+ if (lockDiscovery != null) {
+ return lockDiscovery;
+ } else {
+ DavException dx = getResponseException();
+ if (dx != null) {
+ throw dx;
+ } else {
+ throw new DavException(getStatusCode(), getName() + " resulted with unexpected status: " + getStatusLine());
+ }
+ }
}
+ /**
+ *
+ * @return
+ */
public String getLockToken() {
checkUsed();
- CodedUrlHeader cuh = new CodedUrlHeader(DavConstants.HEADER_LOCK_TOKEN, getResponseHeader(DavConstants.HEADER_LOCK_TOKEN).getValue());
- return cuh.getCodedUrl();
+ Header ltHeader = getResponseHeader(DavConstants.HEADER_LOCK_TOKEN);
+ if (ltHeader != null) {
+ CodedUrlHeader cuh = new CodedUrlHeader(DavConstants.HEADER_LOCK_TOKEN, ltHeader.getValue());
+ return cuh.getCodedUrl();
+ } else {
+ // not Lock-Token header must be sent in response to a 'refresh'.
+ // see the validation performed while processing the response.
+ return null;
+ }
}
//---------------------------------------------------------< HttpMethod >---
@@ -110,6 +151,17 @@
return DavMethods.METHOD_LOCK;
}
+ //----------------------------------------------------------< DavMethod >---
+ /**
+ * @return true, if the status code indicates success and if the response
+ * contains a Lock-Token header for a request used to create a new lock.
+ */
+ public boolean succeeded() {
+ checkUsed();
+ String lt = getLockToken();
+ boolean containsRequiredHeader = (isRefresh) ? lt == null : lt != null;
+ return getSuccess() && containsRequiredHeader;
+ }
//------------------------------------------------------< DavMethodBase >---
/**
*
@@ -118,5 +170,55 @@
*/
protected boolean isSuccess(int statusCode) {
return statusCode == DavServletResponse.SC_OK;
+ }
+
+ //-----------------------------------------------------< HttpMethodBase >---
+ /**
+ * Retrieves the DAV:lockdiscovery property present in the response body
+ * and builds 'ActiveLock' objects from the corresponding DAV:activelock
+ * child elements inside the lock discovery. If parsing the response body
+ * fails for whatever reason or if the DAV:lockdiscovery did not contain
+ * at least a single DAV:activelock entry (the one created by the LOCK
+ * call) this methods in addition resets the 'success' flag to false.
+ *
+ * @param httpState
+ * @param httpConnection
+ * @see HttpMethodBase#processResponseBody(HttpState, HttpConnection)
+ */
+ protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
+ // in case of successful response code -> parse xml body into lockDiscovery.
+ if (getSuccess()) {
+ try {
+ setSuccess(buildDiscoveryFromRoot(getRootElement()));
+ } catch (IOException e) {
+ log.error("Error while parsing multistatus response: " + e);
+ setSuccess(false);
+ }
+ }
+ }
+
+ //------------------------------------------------------------< private >---
+ /**
+ * Builds a new <code>LockDiscovery</code> object from the root XML
+ * present in the response body and returns true if the object could be
+ * created successfully.
+ *
+ * @param root
+ * @return if a <code>LockDiscovery</code> object could be created from the
+ * given XML, false otherwise.
+ */
+ private boolean buildDiscoveryFromRoot(Element root) {
+ if (DomUtil.matches(root, XML_PROP, NAMESPACE) && DomUtil.hasChildElement(root, PROPERTY_LOCKDISCOVERY, NAMESPACE)) {
+ Element lde = DomUtil.getChildElement(root, PROPERTY_LOCKDISCOVERY, NAMESPACE);
+ if (DomUtil.hasChildElement(lde, XML_ACTIVELOCK, NAMESPACE)) {
+ lockDiscovery = LockDiscovery.createFromXml(lde);
+ return true;
+ } else {
+ log.debug("The DAV:lockdiscovery must contain a least a single DAV:activelock in response to a successful LOCK request.");
+ }
+ } else {
+ log.debug("Missing DAV:prop response body in LOCK method.");
+ }
+ return false;
}
}
Modified: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/MergeMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/MergeMethod.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/MergeMethod.java (original)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/MergeMethod.java Wed Jul 12 02:38:25 2006
@@ -51,6 +51,7 @@
* @return true if status code is {@link DavServletResponse#SC_MULTI_STATUS 207 (Multi-Status)}.
*/
protected boolean isSuccess(int statusCode) {
+ // TODO: is this correct?
return statusCode == DavServletResponse.SC_MULTI_STATUS;
}
}
Added: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java?rev=421206&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java (added)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java Wed Jul 12 02:38:25 2006
@@ -0,0 +1,127 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* 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 org.apache.jackrabbit.webdav.client.methods;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavMethods;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.observation.ObservationConstants;
+import org.apache.jackrabbit.webdav.observation.EventDiscovery;
+import org.apache.jackrabbit.webdav.observation.EventBundle;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.HttpConnection;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.io.IOException;
+
+/**
+ * <code>PollMethod</code> imple
+ */
+public class PollMethod extends DavMethodBase implements ObservationConstants {
+
+ private static Logger log = LoggerFactory.getLogger(PollMethod.class);
+
+ private EventDiscovery eventDiscovery;
+
+ public PollMethod(String uri, String subscriptionId) {
+ super(uri);
+ setRequestHeader(ObservationConstants.HEADER_SUBSCRIPTIONID, subscriptionId);
+ }
+
+ public EventDiscovery getResponseAsEventDiscovery() throws IOException, DavException {
+ checkUsed();
+ if (eventDiscovery != null) {
+ return eventDiscovery;
+ } else {
+ DavException dx = getResponseException();
+ if (dx != null) {
+ throw dx;
+ } else {
+ throw new DavException(getStatusCode(), getName() + " resulted with unexpected status: " + getStatusLine());
+ }
+ }
+ }
+ //---------------------------------------------------------< HttpMethod >---
+ public String getName() {
+ return DavMethods.METHOD_POLL;
+ }
+
+ //------------------------------------------------------< DavMethodBase >---
+ protected boolean isSuccess(int statusCode) {
+ return DavServletResponse.SC_OK == statusCode;
+ }
+
+ //------------------------------------------------------< HttpMethodBase >---
+ /**
+ * Retrieves the DAV:subscriptiondiscovery property present in the response body
+ * and builds 'Subscription' objects from the corresponding DAV:subscription
+ * child elements inside the discovery. If parsing the response body
+ * fails for whatever reason or if the DAV:subscriptiondiscovery did not contain
+ * at least a single DAV:subscription entry (the one created by the SUBSCRIBE
+ * call) this methods in addition resets the 'success' flag to false.
+ *
+ * @param httpState
+ * @param httpConnection
+ * @see HttpMethodBase#processResponseBody(HttpState, HttpConnection)
+ */
+ protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
+ // in case of successful response code -> parse xml body discovery object
+ if (getSuccess()) {
+ try {
+ setSuccess(buildDiscoveryFromRoot(getRootElement()));
+ } catch (IOException e) {
+ log.error("Error while parsing multistatus response: " + e);
+ setSuccess(false);
+ }
+ }
+ }
+
+ //------------------------------------------------------------< private >---
+ /**
+ *
+ * @param root
+ * @return
+ */
+ private boolean buildDiscoveryFromRoot(Element root) {
+ if (DomUtil.matches(root, XML_PROP, DavConstants.NAMESPACE) &&
+ DomUtil.hasChildElement(root, XML_EVENTDISCOVERY, ObservationConstants.NAMESPACE)) {
+ Element ld = DomUtil.getChildElement(root, XML_EVENTDISCOVERY, ObservationConstants.NAMESPACE);
+ eventDiscovery = new EventDiscovery();
+
+ ElementIterator it = DomUtil.getChildren(ld, XML_SUBSCRIPTION, ObservationConstants.NAMESPACE);
+ while (it.hasNext()) {
+ final Element ebElement = it.nextElement();
+ EventBundle eb = new EventBundle() {
+ public Element toXml(Document document) {
+ return (Element) document.importNode(ebElement, true);
+ }
+ };
+ eventDiscovery.addEventBundle(eb);
+ }
+ return true;
+ } else {
+ log.debug("Missing DAV:prop response body in SUBSCRIBE method.");
+ }
+ return false;
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/PollMethod.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java?rev=421206&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java (added)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java Wed Jul 12 02:38:25 2006
@@ -0,0 +1,180 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* 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 org.apache.jackrabbit.webdav.client.methods;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavMethods;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.header.CodedUrlHeader;
+import org.apache.jackrabbit.webdav.header.DepthHeader;
+import org.apache.jackrabbit.webdav.header.TimeoutHeader;
+import org.apache.jackrabbit.webdav.observation.SubscriptionInfo;
+import org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery;
+import org.apache.jackrabbit.webdav.observation.ObservationConstants;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.HttpConnection;
+import org.w3c.dom.Element;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * <code>SubscribeMethod</code>...
+ */
+public class SubscribeMethod extends DavMethodBase implements ObservationConstants {
+
+ private static Logger log = LoggerFactory.getLogger(SubscribeMethod.class);
+
+ private SubscriptionDiscovery subscriptionDiscovery;
+
+ /**
+ * Create a new <code>SubscribeMethod</code> used to register to the
+ * observation events specified within the given <code>SubscriptionInfo</code>.
+ * See {@link #SubscribeMethod(String, SubscriptionInfo, String) for a
+ * constructor that allows to redefined an existing subscription.
+ *
+ * @param uri
+ * @param subscriptionInfo
+ * @throws IOException
+ */
+ public SubscribeMethod(String uri, SubscriptionInfo subscriptionInfo) throws IOException {
+ this(uri, subscriptionInfo, null);
+ }
+
+ /**
+ * Create a new <code>SubscribeMethod</code> used to register to the
+ * observation events specified within the given <code>SubscriptionInfo</code>.
+ * Note that in contrast to {@link #SubscribeMethod(String, SubscriptionInfo)}
+ * this constructor optionally takes a subscription id identifying a
+ * subscription made before. In this case the subscription will be modified
+ * according to the definitions present in the <code>SubscriptionInfo</code>.
+ * If the id is <code>null</code> this constructor is identical to
+ * {@link #SubscribeMethod(String, SubscriptionInfo)}.
+ *
+ * @param uri
+ * @param subscriptionInfo
+ * @throws IOException
+ */
+ public SubscribeMethod(String uri, SubscriptionInfo subscriptionInfo, String subscriptionId) throws IOException {
+ super(uri);
+ if (subscriptionInfo == null) {
+ throw new IllegalArgumentException("SubscriptionInfo must not be null.");
+ }
+ // optional subscriptionId (only required to modify an existing subscription)
+ if (subscriptionId != null) {
+ setRequestHeader(new CodedUrlHeader(HEADER_SUBSCRIPTIONID, subscriptionId));
+ }
+ // optional timeout header
+ long to = subscriptionInfo.getTimeOut();
+ if (to != DavConstants.UNDEFINED_TIMEOUT) {
+ setRequestHeader(new TimeoutHeader(subscriptionInfo.getTimeOut()));
+ }
+ // always set depth header since value is boolean flag
+ setRequestHeader(new DepthHeader(subscriptionInfo.isDeep()));
+
+ setRequestHeader(DavConstants.HEADER_CONTENT_TYPE, "text/xml; charset=UTF-8");
+ setRequestBody(subscriptionInfo);
+ }
+
+ public SubscriptionDiscovery getResponseAsSubscriptionDiscovery() throws IOException, DavException {
+ checkUsed();
+ if (subscriptionDiscovery != null) {
+ return subscriptionDiscovery;
+ } else {
+ DavException dx = getResponseException();
+ if (dx != null) {
+ throw dx;
+ } else {
+ throw new DavException(getStatusCode(), getName() + " resulted with unexpected status: " + getStatusLine());
+ }
+ }
+ }
+
+ public String getSubscriptionId() {
+ checkUsed();
+ Header sbHeader = getResponseHeader(HEADER_SUBSCRIPTIONID);
+ if (sbHeader != null) {
+ CodedUrlHeader cuh = new CodedUrlHeader(HEADER_SUBSCRIPTIONID, sbHeader.getValue());
+ return cuh.getCodedUrl();
+ }
+ return null;
+ }
+
+ //---------------------------------------------------------< HttpMethod >---
+ public String getName() {
+ return DavMethods.METHOD_SUBSCRIBE;
+ }
+
+ //------------------------------------------------------< DavMethodBase >---
+ protected boolean isSuccess(int statusCode) {
+ return DavServletResponse.SC_OK == statusCode;
+ }
+
+ //------------------------------------------------------< HttpMethodBase >---
+ /**
+ * Retrieves the DAV:subscriptiondiscovery property present in the response body
+ * and builds 'Subscription' objects from the corresponding DAV:subscription
+ * child elements inside the discovery. If parsing the response body
+ * fails for whatever reason or if the DAV:subscriptiondiscovery did not contain
+ * at least a single DAV:subscription entry (the one created by the SUBSCRIBE
+ * call) this methods in addition resets the 'success' flag to false.
+ *
+ * @param httpState
+ * @param httpConnection
+ * @see HttpMethodBase#processResponseBody(HttpState, HttpConnection)
+ */
+ protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
+ // in case of successful response code -> parse xml body discovery object
+ if (getSuccess()) {
+ try {
+ setSuccess(buildDiscoveryFromRoot(getRootElement()));
+ } catch (IOException e) {
+ log.error("Error while parsing multistatus response: " + e);
+ setSuccess(false);
+ }
+ }
+ }
+
+ //------------------------------------------------------------< private >---
+ /**
+ *
+ * @param root
+ * @return
+ */
+ private boolean buildDiscoveryFromRoot(Element root) {
+ if (DomUtil.matches(root, XML_PROP, DavConstants.NAMESPACE) &&
+ DomUtil.hasChildElement(root, SUBSCRIPTIONDISCOVERY.getName(), SUBSCRIPTIONDISCOVERY.getNamespace())) {
+ Element sdElem = DomUtil.getChildElement(root, SUBSCRIPTIONDISCOVERY.getName(), SUBSCRIPTIONDISCOVERY.getNamespace());
+
+ SubscriptionDiscovery sd = SubscriptionDiscovery.createFromXml(sdElem);
+ if (!((List)sd.getValue()).isEmpty()) {
+ subscriptionDiscovery = sd;
+ return true;
+ } else {
+ log.debug("Missing 'subscription' elements in SUBSCRIBE response body. At least a single subscription must be present if SUBSCRIBE was successful.");
+ }
+ } else {
+ log.debug("Missing DAV:prop response body in SUBSCRIBE method.");
+ }
+ return false;
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/SubscribeMethod.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java?rev=421206&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java (added)
+++ jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java Wed Jul 12 02:38:25 2006
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* 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 org.apache.jackrabbit.webdav.client.methods;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavMethods;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.observation.ObservationConstants;
+
+/**
+ * <code>UnSubscribeMethod</code>...
+ */
+public class UnSubscribeMethod extends DavMethodBase {
+
+ private static Logger log = LoggerFactory.getLogger(UnSubscribeMethod.class);
+
+ public UnSubscribeMethod(String uri, String subscriptionId) {
+ super(uri);
+ setRequestHeader(ObservationConstants.HEADER_SUBSCRIPTIONID, subscriptionId);
+ }
+
+ //---------------------------------------------------------< HttpMethod >---
+ public String getName() {
+ return DavMethods.METHOD_UNSUBSCRIBE;
+ }
+
+ //------------------------------------------------------< DavMethodBase >---
+ protected boolean isSuccess(int statusCode) {
+ return DavServletResponse.SC_NO_CONTENT == statusCode;
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jcr-server/client/src/java/org/apache/jackrabbit/webdav/client/methods/UnSubscribeMethod.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java (original)
+++ jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionImpl.java Wed Jul 12 02:38:25 2006
@@ -28,6 +28,7 @@
import org.apache.jackrabbit.webdav.observation.ObservationResource;
import org.apache.jackrabbit.webdav.observation.Subscription;
import org.apache.jackrabbit.webdav.observation.SubscriptionInfo;
+import org.apache.jackrabbit.webdav.observation.DefaultEventType;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -104,6 +105,7 @@
locator = resource.getLocator();
}
+ //-------------------------------------------------------< Subscription >---
/**
* Returns the id of this subscription.
*
@@ -113,6 +115,7 @@
return subscriptionId;
}
+ //----------------------------------------------------< XmlSerializable >---
/**
* Return the Xml representation of this <code>Subscription</code> as required
* for the {@link org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery}
@@ -130,8 +133,10 @@
subscr.appendChild(DomUtil.depthToXml(info.isDeep(), document));
subscr.appendChild(DomUtil.timeoutToXml(info.getTimeOut(), document));
- Element id = DomUtil.addChildElement(subscr, XML_SUBSCRIPTIONID, NAMESPACE);
- id.appendChild(DomUtil.hrefToXml(subscriptionId, document));
+ if (getSubscriptionId() != null) {
+ Element id = DomUtil.addChildElement(subscr, XML_SUBSCRIPTIONID, NAMESPACE);
+ id.appendChild(DomUtil.hrefToXml(getSubscriptionId(), document));
+ }
return subscr;
}
@@ -155,11 +160,11 @@
* @return JCR compliant integer representation of the event types defined
* for this {@link SubscriptionInfo}.
*/
- int getEventTypes() throws DavException {
+ int getJcrEventTypes() throws DavException {
EventType[] eventTypes = info.getEventTypes();
int events = 0;
for (int i = 0; i < eventTypes.length; i++) {
- events |= getEventType(eventTypes[i].getName());
+ events |= getJcrEventType(eventTypes[i]);
}
return events;
}
@@ -223,7 +228,7 @@
* resource.
*/
boolean isSubscribedToResource(ObservationResource resource) {
- return locator.equals(resource.getLocator());
+ return locator.getResourcePath().equals(resource.getResourcePath());
}
/**
@@ -274,47 +279,71 @@
//--------------------------------------------------------------------------
/**
- * Static utility method in order to convert the types defined by
- * {@link javax.jcr.observation.Event} into their Xml representation.
- *
- * @param eventType The jcr event type
- * @return Xml representation of the event type.
- */
- private static String getEventName(int eventType) {
- String eventName;
- switch (eventType) {
+ * Static utility method to convert the type defined by a
+ * {@link javax.jcr.observation.Event JCR event} into an <code>EventType</code>
+ * object.
+ *
+ * @param jcrEventType
+ * @return <code>EventType</code> representation of the given JCR event type.
+ * @throws IllegalArgumentException if the given int does not represent a
+ * valid type constants as defined by {@link Event}.<br>
+ * Valid values are
+ * <ul>
+ * <li>{@link Event#NODE_ADDED}</li>
+ * <li>{@link Event#NODE_REMOVED}</li>
+ * <li>{@link Event#PROPERTY_ADDED}</li>
+ * <li>{@link Event#PROPERTY_REMOVED}</li>
+ * <li>{@link Event#PROPERTY_CHANGED}</li>
+ * </ul>
+ */
+ public static EventType getEventType(int jcrEventType) {
+ String localName;
+ switch (jcrEventType) {
case Event.NODE_ADDED:
- eventName = EVENT_NODEADDED;
+ localName = EVENT_NODEADDED;
break;
case Event.NODE_REMOVED:
- eventName = EVENT_NODEREMOVED;
+ localName = EVENT_NODEREMOVED;
break;
case Event.PROPERTY_ADDED:
- eventName = EVENT_PROPERTYADDED;
+ localName = EVENT_PROPERTYADDED;
break;
case Event.PROPERTY_CHANGED:
- eventName = EVENT_PROPERTYCHANGED;
+ localName = EVENT_PROPERTYCHANGED;
break;
- default:
- //Event.PROPERTY_REMOVED:
- eventName = EVENT_PROPERTYREMOVED;
+ case Event.PROPERTY_REMOVED:
+ localName = EVENT_PROPERTYREMOVED;
break;
+ default: // no default
+ throw new IllegalArgumentException("Invalid JCR event type: " + jcrEventType);
}
- return eventName;
+ return DefaultEventType.create(localName, NAMESPACE);
}
/**
- * Static utility method to convert an event type name as present in the
- * Xml request body into the corresponding constant defined by
+ * Static utility method to convert an <code>EventType</code> as present in
+ * the Xml body into the corresponding JCR event constant defined by
* {@link javax.jcr.observation.Event}.
*
- * @param eventName
- * @return event type as defined by {@link javax.jcr.observation.Event}.
- * @throws DavException if the given element cannot be translated
- * to any of the events defined by {@link javax.jcr.observation.Event}.
- */
- private static int getEventType(String eventName) throws DavException {
+ * @param eventType
+ * @return Any of the event types defined by {@link Event}.<br>
+ * Possible values are
+ * <ul>
+ * <li>{@link Event#NODE_ADDED}</li>
+ * <li>{@link Event#NODE_REMOVED}</li>
+ * <li>{@link Event#PROPERTY_ADDED}</li>
+ * <li>{@link Event#PROPERTY_REMOVED}</li>
+ * <li>{@link Event#PROPERTY_CHANGED}</li>
+ * </ul>
+ * @throws DavException if the given event type does not define a valid
+ * JCR event type, such as returned by {@link #getEventType(int)}.
+ */
+ public static int getJcrEventType(EventType eventType) throws DavException {
+ if (eventType == null || !NAMESPACE.equals(eventType.getNamespace())) {
+ throw new DavException(DavServletResponse.SC_UNPROCESSABLE_ENTITY, "Invalid JCR event type: "+ eventType + ": Namespace mismatch.");
+ }
int eType;
+ String eventName = eventType.getName();
if (EVENT_NODEADDED.equals(eventName)) {
eType = Event.NODE_ADDED;
} else if (EVENT_NODEREMOVED.equals(eventName)) {
@@ -364,12 +393,11 @@
eventElem.appendChild(DomUtil.hrefToXml(eHref, document));
// eventtype
Element eType = DomUtil.addChildElement(eventElem, XML_EVENTTYPE, NAMESPACE);
- DomUtil.addChildElement(eType, getEventName(event.getType()), NAMESPACE);
+ eType.appendChild(getEventType(event.getType()).toXml(document));
// user id
DomUtil.addChildElement(eventElem, XML_EVENTUSERID, NAMESPACE, event.getUserID());
}
return bundle;
}
-
}
-}
\ No newline at end of file
+}
Modified: jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java (original)
+++ jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/webdav/jcr/observation/SubscriptionManagerImpl.java Wed Jul 12 02:38:25 2006
@@ -29,6 +29,8 @@
import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -54,14 +56,16 @@
private final SubscriptionMap subscriptions = new SubscriptionMap();
/**
- * Retrieve the {@link org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery} object for the given
- * resource. Note, that the discovery object will be empty if there are
- * no subscriptions present.
+ * Retrieve the {@link org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery}
+ * object for the given resource. Note, that the discovery object will be empty
+ * if there are no subscriptions present.<br>
+ * Note that all subscriptions present on the given resource are returned.
+ * However, the subscription id will not be visible in order to avoid abuse
+ * by clients not having registered the subscription originally.
*
* @param resource
*/
public SubscriptionDiscovery getSubscriptionDiscovery(ObservationResource resource) {
- // todo: is it correct to return subscriptions made by another session?
Subscription[] subsForResource = subscriptions.getByPath(resource.getLocator());
return new SubscriptionDiscovery(subsForResource);
}
@@ -80,20 +84,23 @@
ObservationResource resource)
throws DavException {
- SubscriptionImpl subscription;
+ Subscription subscription;
if (subscriptionId == null) {
// new subscription
- subscription = new SubscriptionImpl(info, resource);
- registerSubscription(subscription, resource);
+ SubscriptionImpl newSubs = new SubscriptionImpl(info, resource);
+ registerSubscription(newSubs, resource);
// ajust references to this subscription
- subscriptions.put(subscription.getSubscriptionId(), subscription);
- resource.getSession().addReference(subscription.getSubscriptionId());
+ subscriptions.put(newSubs.getSubscriptionId(), newSubs);
+ resource.getSession().addReference(newSubs.getSubscriptionId());
+ subscription = newSubs;
} else {
// refresh/modify existing one
- subscription = validate(subscriptionId, resource);
- subscription.setInfo(info);
- registerSubscription(subscription, resource);
+ SubscriptionImpl existing = validate(subscriptionId, resource);
+ existing.setInfo(info);
+ registerSubscription(existing, resource);
+
+ subscription = new WrappedSubscription(existing);
}
return subscription;
}
@@ -112,7 +119,7 @@
Session session = getRepositorySession(resource);
ObservationManager oMgr = session.getWorkspace().getObservationManager();
String itemPath = subscription.getLocator().getRepositoryPath();
- oMgr.addEventListener(subscription, subscription.getEventTypes(),
+ oMgr.addEventListener(subscription, subscription.getJcrEventTypes(),
itemPath, subscription.isDeep(),
subscription.getUuidFilters(),
subscription.getNodetypeNameFilters(),
@@ -220,6 +227,31 @@
return JcrDavSession.getRepositorySession(resource.getSession());
}
+ //----------------------------------------------< private inner classes >---
+ /**
+ * Private inner class wrapping around an <code>Subscription</code> as
+ * present in the internal map. This allows to hide the subscription Id
+ * from other sessions, that did create the subscription.
+ */
+ private class WrappedSubscription implements Subscription {
+
+ private final Subscription delegatee;
+
+ private WrappedSubscription(Subscription subsc) {
+ this.delegatee = subsc;
+ }
+
+ public String getSubscriptionId() {
+ // always return null, since the subscription id must not be exposed
+ // but to the client, that created the subscription.
+ return null;
+ }
+
+ public Element toXml(Document document) {
+ return delegatee.toXml(document);
+ }
+ }
+
/**
* Private inner class <code>SubscriptionMap</code> that allows for quick
* access by resource path as well as by subscription id.
@@ -264,7 +296,8 @@
Subscription[] subsForResource = new Subscription[idSet.size()];
int i = 0;
while (idIterator.hasNext()) {
- subsForResource[i] = (Subscription) subscriptions.get(idIterator.next());
+ SubscriptionImpl s = (SubscriptionImpl) subscriptions.get(idIterator.next());
+ subsForResource[i] = new WrappedSubscription(s);
}
return subsForResource;
} else {
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/WebdavResponseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/WebdavResponseImpl.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/WebdavResponseImpl.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/WebdavResponseImpl.java Wed Jul 12 02:38:25 2006
@@ -21,9 +21,12 @@
import org.apache.jackrabbit.webdav.observation.EventDiscovery;
import org.apache.jackrabbit.webdav.observation.Subscription;
import org.apache.jackrabbit.webdav.observation.SubscriptionDiscovery;
+import org.apache.jackrabbit.webdav.observation.ObservationConstants;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.xml.XmlSerializable;
import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.header.CodedUrlHeader;
+import org.apache.jackrabbit.webdav.header.Header;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.slf4j.Logger;
@@ -111,8 +114,10 @@
* @see DavServletResponse#sendLockResponse(org.apache.jackrabbit.webdav.lock.ActiveLock)
*/
public void sendLockResponse(ActiveLock lock) throws IOException {
- httpResponse.setHeader(DavConstants.HEADER_LOCK_TOKEN, "<" + lock.getToken() + ">");
- DavPropertySet propSet = new DavPropertySet();
+ CodedUrlHeader ltHeader = new CodedUrlHeader(DavConstants.HEADER_LOCK_TOKEN, lock.getToken());
+ httpResponse.setHeader(ltHeader.getHeaderName(), ltHeader.getHeaderValue());
+
+ DavPropertySet propSet = new DavPropertySet();
propSet.add(new LockDiscovery(lock));
sendXmlResponse(propSet, SC_OK);
}
@@ -172,7 +177,12 @@
* @see org.apache.jackrabbit.webdav.observation.ObservationDavServletResponse#sendSubscriptionResponse(org.apache.jackrabbit.webdav.observation.Subscription)
*/
public void sendSubscriptionResponse(Subscription subscription) throws IOException {
- DavPropertySet propSet = new DavPropertySet();
+ String id = subscription.getSubscriptionId();
+ if (id != null) {
+ Header h = new CodedUrlHeader(ObservationConstants.HEADER_SUBSCRIPTIONID, id);
+ httpResponse.setHeader(h.getHeaderName(), h.getHeaderValue());
+ }
+ DavPropertySet propSet = new DavPropertySet();
propSet.add(new SubscriptionDiscovery(subscription));
sendXmlResponse(propSet, SC_OK);
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/header/TimeoutHeader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/header/TimeoutHeader.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/header/TimeoutHeader.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/header/TimeoutHeader.java Wed Jul 12 02:38:25 2006
@@ -48,20 +48,34 @@
}
/**
- * Parse the request timeout header and convert the timeout value
+ * Parses the request timeout header and converts it into a new
+ * <code>TimeoutHeader</code> object.<br>The default value is used as
+ * fallback if the String is not parseable.
+ *
+ * @param request
+ * @param defaultValue
+ * @return a new TimeoutHeader object.
+ */
+ public static TimeoutHeader parse(HttpServletRequest request, long defaultValue) {
+ String timeoutStr = request.getHeader(HEADER_TIMEOUT);
+ long timeout = parse(timeoutStr, defaultValue);
+ return new TimeoutHeader(timeout);
+ }
+
+ /**
+ * Parses the given timeout String and converts the timeout value
* into a long indicating the number of milliseconds until expiration time
* is reached.<br>
- * NOTE: If the requested timeout is 'infinite' {@link Long.MAX_VALUE}
- * is returned. If the header is missing or is in an invalid format that
- * cannot be parsed, the default value is returned.
+ * NOTE: If the timeout String equals to {@link #TIMEOUT_INFINITE 'infinite'}
+ * {@link Long.MAX_VALUE} is returned. If the Sting is invalid or is in an
+ * invalid format that cannot be parsed, the default value is returned.
*
- * @param request
+ * @param timeoutStr
* @param defaultValue
* @return long representing the timeout present in the header or the default
* value if the header is missing or could not be parsed.
*/
- public static TimeoutHeader parse(HttpServletRequest request, long defaultValue) {
- String timeoutStr = request.getHeader(HEADER_TIMEOUT);
+ public static long parse(String timeoutStr, long defaultValue) {
long timeout = defaultValue;
if (timeoutStr != null && timeoutStr.length() > 0) {
int secondsInd = timeoutStr.indexOf("Second-");
@@ -81,6 +95,6 @@
timeout = INFINITE_TIMEOUT;
}
}
- return new TimeoutHeader(timeout);
+ return timeout;
}
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/lock/LockDiscovery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/lock/LockDiscovery.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/lock/LockDiscovery.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/lock/LockDiscovery.java Wed Jul 12 02:38:25 2006
@@ -18,6 +18,9 @@
import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.header.TimeoutHeader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -104,4 +107,116 @@
return lockdiscovery;
}
+ //---------------------------------------------------< factory from xml >---
+ /**
+ * Builds a new <code>LockDiscovery</code> object from the given xml element.
+ *
+ * @param lockDiscoveryElement
+ * @return
+ * @throws IllegalArgumentException if the given xml element is not a
+ * DAV:lockdiscovery element.
+ */
+ public static LockDiscovery createFromXml(Element lockDiscoveryElement) {
+ if (!DomUtil.matches(lockDiscoveryElement, PROPERTY_LOCKDISCOVERY, NAMESPACE)) {
+ throw new IllegalArgumentException("DAV:lockdiscovery element expected.");
+ }
+
+ List activeLocks = new ArrayList();
+ ElementIterator it = DomUtil.getChildren(lockDiscoveryElement, XML_ACTIVELOCK, NAMESPACE);
+ while (it.hasNext()) {
+ Element al = it.nextElement();
+ activeLocks.add(new ALockImpl(al));
+ }
+
+ return new LockDiscovery((ActiveLock[]) activeLocks.toArray(new ActiveLock[activeLocks.size()]));
+ }
+
+ //------< inner class >-----------------------------------------------------
+ /**
+ * Simple implementation of <code>ActiveLock</code> interface, that retrieves
+ * the values from the DAV:activelock XML element.<br>
+ * Note, that all set-methods as well as {@link #isExpired()} are not
+ * implemented.
+ */
+ private static class ALockImpl implements ActiveLock {
+
+ private final Element alElement;
+
+ private ALockImpl(Element alElement) {
+ if (!DomUtil.matches(alElement, XML_ACTIVELOCK, NAMESPACE)) {
+ throw new IllegalArgumentException("DAV:activelock element expected.");
+ }
+ this.alElement = alElement;
+ }
+
+ public boolean isLockedByToken(String lockToken) {
+ String lt = getToken();
+ if (lt == null) {
+ return false;
+ } else {
+ return lt.equals(lockToken);
+ }
+ }
+
+ public boolean isExpired() {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public String getToken() {
+ Element ltEl = DomUtil.getChildElement(alElement, XML_LOCKTOKEN, NAMESPACE);
+ if (ltEl != null) {
+ return DomUtil.getChildText(alElement, XML_HREF, NAMESPACE);
+ }
+ return null;
+ }
+
+ public String getOwner() {
+ String owner = null;
+ Element ow = DomUtil.getChildElement(alElement, XML_OWNER, NAMESPACE);
+ if (ow != null) {
+ if (DomUtil.hasChildElement(ow, XML_HREF, NAMESPACE)) {
+ owner = DomUtil.getChildTextTrim(ow, XML_HREF, NAMESPACE);
+ } else {
+ owner = DomUtil.getTextTrim(ow);
+ }
+ }
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public long getTimeout() {
+ // get timeout string. if no DAV:timeout element is present,
+ // 't' will be 'null' and the undefined timeout will be returned.
+ String t = DomUtil.getChildTextTrim(alElement, XML_TIMEOUT, NAMESPACE);
+ return TimeoutHeader.parse(t, UNDEFINED_TIMEOUT);
+ }
+
+ public void setTimeout(long timeout) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public boolean isDeep() {
+ String depth = DomUtil.getChildTextTrim(alElement, XML_DEPTH, NAMESPACE);
+ return DEPTH_INFINITY_S.equalsIgnoreCase(depth);
+ }
+
+ public void setIsDeep(boolean isDeep) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public Type getType() {
+ return Type.createFromXml(DomUtil.getChildElement(alElement, XML_LOCKTYPE, NAMESPACE));
+ }
+
+ public Scope getScope() {
+ return Scope.createFromXml(DomUtil.getChildElement(alElement, XML_LOCKSCOPE, NAMESPACE));
+ }
+
+ public Element toXml(Document document) {
+ return (Element) document.importNode(alElement, true);
+ }
+ }
}
Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java?rev=421206&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java Wed Jul 12 02:38:25 2006
@@ -0,0 +1,130 @@
+/*
+ * $URL$
+ * $Id$
+ *
+ * Copyright 1997-2005 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.jackrabbit.webdav.observation;
+
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * <code>DefaultEventType</code> defines a simple EventType implementation that
+ * only consists of a qualified event name consisting of namespace plus local
+ * name.
+ */
+public class DefaultEventType implements EventType {
+
+ private static final Map eventTypes = new HashMap();
+
+ private final String localName;
+ private final Namespace namespace;
+
+ /**
+ * Avoid instanciation of <code>DefaultEventType</code>. Since the amount
+ * of available (and registered) events is considered to be limited, the
+ * static {@link #create(String, Namespace) method is defined.
+ *
+ * @param localName
+ * @param namespace
+ */
+ private DefaultEventType(String localName, Namespace namespace) {
+ this.localName = localName;
+ this.namespace = namespace;
+ }
+
+ /**
+ * Factory method to create a new <code>EventType</code>.
+ *
+ * @param localName
+ * @param namespace
+ * @return
+ */
+ public static EventType create(String localName, Namespace namespace) {
+ if (localName == null || "".equals(localName)) {
+ throw new IllegalArgumentException("null and '' are not valid local names of an event type.");
+ }
+ String key = DomUtil.getQualifiedName(localName, namespace);
+ if (eventTypes.containsKey(key)) {
+ return (EventType) eventTypes.get(key);
+ } else {
+ EventType type = new DefaultEventType(localName, namespace);
+ eventTypes.put(key, type);
+ return type;
+ }
+ }
+
+ /**
+ * Retrieves one or multiple <code>EventType</code>s from the 'eventtype'
+ * Xml element. While a subscription may register multiple types (thus
+ * the 'eventtype' contains multiple child elements), a single event may only
+ * refer to one single type.
+ *
+ * @param eventType
+ * @return
+ */
+ public static EventType[] createFromXml(Element eventType) {
+ if (!DomUtil.matches(eventType, ObservationConstants.XML_EVENTTYPE, ObservationConstants.NAMESPACE)) {
+ throw new IllegalArgumentException("'eventtype' element expected which contains a least a single child element.");
+ }
+
+ List etypes = new ArrayList();
+ ElementIterator it = DomUtil.getChildren(eventType);
+ while (it.hasNext()) {
+ Element el = it.nextElement();
+ etypes.add(create(el.getLocalName(), DomUtil.getNamespace(el)));
+ }
+ return (EventType[]) etypes.toArray(new EventType[etypes.size()]);
+ }
+
+ //----------------------------------------------------------< EventType >---
+ /**
+ * @see EventType#getName()
+ */
+ public String getName() {
+ return localName;
+ }
+
+ /**
+ * @see EventType#getNamespace()
+ */
+ public Namespace getNamespace() {
+ return namespace;
+ }
+
+ //----------------------------------------------------< XmlSerializable >---
+ /**
+ * Returns a single empty Xml element where namespace and local name of this
+ * event type define the elements name.
+ * <pre>
+ * EventType.create("someevent", Namespace.getNamespace("F", "http://www.foo.bar/eventtypes"));
+ *
+ * returns the following element upon call of toXml:
+ *
+ * <F:someevent xmlns:F="http://www.foo.bar/eventtypes" />
+ * </pre>
+ *
+ * @see XmlSerializable#toXml(Document)
+ */
+ public Element toXml(Document document) {
+ return DomUtil.createElement(document, localName, namespace);
+ }
+}
Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/DefaultEventType.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/EventDiscovery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/EventDiscovery.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/EventDiscovery.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/EventDiscovery.java Wed Jul 12 02:38:25 2006
@@ -37,7 +37,7 @@
private static Logger log = LoggerFactory.getLogger(EventDiscovery.class);
- private List bundles = new ArrayList();
+ private final List bundles = new ArrayList();
/**
* Add the Xml representation of an single 'eventBundle' listing the
@@ -54,6 +54,27 @@
}
/**
+ * Returns an iterator over the {@link EventBundle event bundles} currently
+ * present on this discovery.
+ *
+ * @return iterator over event bundles present.
+ */
+ public Iterator getEventBundles() {
+ return bundles.iterator();
+ }
+
+ /**
+ * Returns true, if this event discovery does not report any events (thus
+ * {@link #getEventBundles()} would return an empty iterator.
+ *
+ * @return true if {@link #getEventBundles()} would return an empty iterator,
+ * false otherwise.
+ */
+ public boolean isEmpty() {
+ return bundles.isEmpty();
+ }
+
+ /**
* Returns the Xml representation of this <code>EventDiscovery</code> as
* being present in the POLL response body.
*
@@ -63,12 +84,11 @@
*/
public Element toXml(Document document) {
Element ed = DomUtil.createElement(document, XML_EVENTDISCOVERY, NAMESPACE);
- Iterator it = bundles.iterator();
+ Iterator it = getEventBundles();
while (it.hasNext()) {
EventBundle bundle = (EventBundle)it.next();
ed.appendChild(bundle.toXml(document));
}
return ed;
}
-
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionDiscovery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionDiscovery.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionDiscovery.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionDiscovery.java Wed Jul 12 02:38:25 2006
@@ -17,9 +17,16 @@
package org.apache.jackrabbit.webdav.observation;
import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.DavConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import java.util.List;
+import java.util.ArrayList;
+
/**
* <code>SubscriptionDiscovery</code> encapsulates the 'subscriptiondiscovery'
* property of a webdav resource.
@@ -79,4 +86,38 @@
return elem;
}
+ //-----------------------------------------------------< static Factory >---
+ public static SubscriptionDiscovery createFromXml(Element sDiscoveryElement) {
+ if (!DomUtil.matches(sDiscoveryElement, ObservationConstants.SUBSCRIPTIONDISCOVERY.getName(), ObservationConstants.SUBSCRIPTIONDISCOVERY.getNamespace())) {
+ throw new IllegalArgumentException("'subscriptiondiscovery' element expected.");
+ }
+
+ List subscriptions = new ArrayList();
+ ElementIterator it = DomUtil.getChildren(sDiscoveryElement, ObservationConstants.XML_SUBSCRIPTION, ObservationConstants.NAMESPACE);
+ while (it.hasNext()) {
+ final Element sb = it.nextElement();
+ // anonymous inner class: Subscription interface
+ Subscription s = new Subscription() {
+ /**
+ * @see Subscription#getSubscriptionId()
+ */
+ public String getSubscriptionId() {
+ Element ltEl = DomUtil.getChildElement(sb, ObservationConstants.XML_SUBSCRIPTIONID, ObservationConstants.NAMESPACE);
+ if (ltEl != null) {
+ return DomUtil.getChildText(sb, DavConstants.XML_HREF, DavConstants.NAMESPACE);
+ }
+ return null;
+ }
+ /**
+ * @see XmlSerializable#toXml(Document)
+ */
+ public Element toXml(Document document) {
+ return (Element) document.importNode(sb, true);
+ }
+ };
+ subscriptions.add(s);
+ }
+
+ return new SubscriptionDiscovery((Subscription[]) subscriptions.toArray(new Subscription[subscriptions.size()]));
+ }
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionInfo.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionInfo.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/observation/SubscriptionInfo.java Wed Jul 12 02:38:25 2006
@@ -18,6 +18,8 @@
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.header.TimeoutHeader;
+import org.apache.jackrabbit.webdav.header.DepthHeader;
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
import org.apache.jackrabbit.webdav.xml.Namespace;
@@ -98,11 +100,16 @@
}
/**
- * Create a new <code>SubscriptionInfo</code>
- *
+ * Create a new <code>SubscriptionInfo</code> from the given Xml element
+ * and from additional information that is transported within the request
+ * header:
+ * <ul>
+ * <li>{@link TimeoutHeader timeout},</li>
+ * <li>{@link DepthHeader isDeep}</li>
+ * </ul>
* @param reqInfo Xml element present in the request body.
- * @param timeout as defined by the {@link org.apache.jackrabbit.webdav.DavConstants#HEADER_TIMEOUT timeout header}.
- * @param isDeep as defined by the {@link org.apache.jackrabbit.webdav.DavConstants#HEADER_DEPTH depth header}.
+ * @param timeout as defined in the {@link org.apache.jackrabbit.webdav.DavConstants#HEADER_TIMEOUT timeout header}.
+ * @param isDeep as defined in the {@link org.apache.jackrabbit.webdav.DavConstants#HEADER_DEPTH depth header}.
* @throws IllegalArgumentException if the reqInfo element does not contain the mandatory elements.
*/
public SubscriptionInfo(Element reqInfo, long timeout, boolean isDeep) throws DavException {
@@ -110,26 +117,18 @@
log.warn("Element with name 'subscriptioninfo' expected");
throw new DavException(DavServletResponse.SC_BAD_REQUEST);
}
- List typeList = new ArrayList();
Element el = DomUtil.getChildElement(reqInfo, XML_EVENTTYPE, NAMESPACE);
if (el != null) {
- ElementIterator it = DomUtil.getChildren(el);
- while (it.hasNext()) {
- Element typeElem = it.nextElement();
- EventType et = new SimpleEventType(typeElem.getLocalName(), DomUtil.getNamespace(typeElem));
- typeList.add(et);
+ eventTypes = DefaultEventType.createFromXml(el);
+ if (eventTypes.length == 0) {
+ log.warn("'subscriptioninfo' must at least indicate a single, valid event type.");
+ throw new DavException(DavServletResponse.SC_BAD_REQUEST);
}
} else {
log.warn("'subscriptioninfo' must contain an 'eventtype' child element.");
throw new DavException(DavServletResponse.SC_BAD_REQUEST);
}
- if (typeList.isEmpty()) {
- log.warn("'subscriptioninfo' must at least indicate a single event type.");
- throw new DavException(DavServletResponse.SC_BAD_REQUEST);
- }
- eventTypes = (EventType[]) typeList.toArray(new EventType[typeList.size()]);
-
List filters = new ArrayList();
el = DomUtil.getChildElement(reqInfo, XML_FILTER, NAMESPACE);
if (el != null) {
@@ -239,33 +238,5 @@
DomUtil.addChildElement(subscrInfo, XML_NOLOCAL, NAMESPACE);
}
return subscrInfo;
- }
-
- //--------------------------------------------------------< inner class >---
- /**
- * Simple EventType implementation that only consists of a qualified event
- * name.
- */
- private class SimpleEventType implements EventType {
-
- private String localName;
- private Namespace namespace;
-
- SimpleEventType(String localName, Namespace namespace) {
- this.localName = localName;
- this.namespace = namespace;
- }
-
- public Element toXml(Document document) {
- return DomUtil.createElement(document, localName, namespace);
- }
-
- public String getName() {
- return localName;
- }
-
- public Namespace getNamespace() {
- return namespace;
- }
}
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/MergeInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/MergeInfo.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/MergeInfo.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/MergeInfo.java Wed Jul 12 02:38:25 2006
@@ -154,4 +154,29 @@
return elem;
}
+
+ /**
+ * Factory method to create a minimal DAV:merge element to create a new
+ * <code>MergeInfo</code> object.
+ *
+ * @param mergeSource
+ * @param isNoAutoMerge
+ * @param isNoCheckout
+ * @param factory
+ * @return
+ */
+ public static Element createMergeElement(String[] mergeSource, boolean isNoAutoMerge, boolean isNoCheckout, Document factory) {
+ Element mergeElem = DomUtil.createElement(factory, XML_MERGE, NAMESPACE);
+ Element source = DomUtil.addChildElement(mergeElem, DavConstants.XML_SOURCE, DavConstants.NAMESPACE);
+ for (int i = 0; i < mergeSource.length; i++) {
+ DomUtil.addChildElement(source, DavConstants.XML_HREF, DavConstants.NAMESPACE, mergeSource[i]);
+ }
+ if (isNoAutoMerge) {
+ DomUtil.addChildElement(mergeElem, XML_N0_AUTO_MERGE, NAMESPACE);
+ }
+ if (isNoCheckout) {
+ DomUtil.addChildElement(mergeElem, XML_N0_CHECKOUT, NAMESPACE);
+ }
+ return mergeElem;
+ }
}
Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/UpdateInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/UpdateInfo.java?rev=421206&r1=421205&r2=421206&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/UpdateInfo.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/UpdateInfo.java Wed Jul 12 02:38:25 2006
@@ -65,8 +65,8 @@
public static final int UPDATE_BY_WORKSPACE = 2;
private Element updateElement;
- private DavPropertyNameSet propertyNameSet = new DavPropertyNameSet();
+ private DavPropertyNameSet propertyNameSet = new DavPropertyNameSet();
private String[] source;
private int type;
@@ -192,24 +192,45 @@
if (updateElement != null) {
elem = (Element)document.importNode(updateElement, true);
} else {
- elem = DomUtil.createElement(document, XML_UPDATE, NAMESPACE);
- switch (type) {
- case UPDATE_BY_VERSION:
- Element vE = DomUtil.addChildElement(elem, XML_VERSION, NAMESPACE);
- for (int i = 0; i < source.length; i++) {
- vE.appendChild(DomUtil.hrefToXml(source[i], document));
- }
- break;
- case UPDATE_BY_LABEL:
- DomUtil.addChildElement(elem, XML_LABEL_NAME, NAMESPACE, source[0]);
- break;
- case UPDATE_BY_WORKSPACE:
- DomUtil.addChildElement(elem, XML_WORKSPACE, NAMESPACE, source[0]);
- // no default.
- }
+ elem = createUpdateElement(source, type, document);
}
if (!propertyNameSet.isEmpty()) {
elem.appendChild(propertyNameSet.toXml(document));
+ }
+ return elem;
+ }
+
+ /**
+ * Factory method to create the basic structure of an <code>UpdateInfo</code>
+ * object.
+ *
+ * @param updateSource
+ * @param updateType
+ * @param factory
+ * @return
+ */
+ public static Element createUpdateElement(String[] updateSource, int updateType, Document factory) {
+ if (updateSource == null || updateSource.length == 0) {
+ throw new IllegalArgumentException("Update source must specific at least a single resource used to run the update.");
+ }
+
+ Element elem = DomUtil.createElement(factory, XML_UPDATE, NAMESPACE);
+ switch (updateType) {
+ case UPDATE_BY_VERSION:
+ Element vE = DomUtil.addChildElement(elem, XML_VERSION, NAMESPACE);
+ for (int i = 0; i < updateSource.length; i++) {
+ vE.appendChild(DomUtil.hrefToXml(updateSource[i], factory));
+ }
+ break;
+ case UPDATE_BY_LABEL:
+ DomUtil.addChildElement(elem, XML_LABEL_NAME, NAMESPACE, updateSource[0]);
+ break;
+ case UPDATE_BY_WORKSPACE:
+ DomUtil.addChildElement(elem, XML_WORKSPACE, NAMESPACE, updateSource[0]);
+ break;
+ // no default.
+ default:
+ throw new IllegalArgumentException("Invalid update type: " + updateType);
}
return elem;
}