juergen 02/03/20 06:24:32
Modified: src/webdav/server/org/apache/slide/webdav/method
ReportMethod.java
Log:
Added <locate-by-history> report.
Some code clean-up.
(ralf)
Revision Changes Path
1.10 +295 -26
jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/ReportMethod.java
Index: ReportMethod.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/ReportMethod.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ReportMethod.java 19 Mar 2002 07:32:35 -0000 1.9
+++ ReportMethod.java 20 Mar 2002 14:24:31 -0000 1.10
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/ReportMethod.java,v
1.9 2002/03/19 07:32:35 juergen Exp $
- * $Revision: 1.9 $
- * $Date: 2002/03/19 07:32:35 $
+ * $Header:
/home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/ReportMethod.java,v
1.10 2002/03/20 14:24:31 juergen Exp $
+ * $Revision: 1.10 $
+ * $Date: 2002/03/20 14:24:31 $
*
* ====================================================================
*
@@ -131,6 +131,14 @@
import org.apache.slide.webdav.util.UriHandler;
import org.apache.slide.webdav.util.WebdavUtils;
import org.apache.slide.webdav.util.XMLValue;
+import org.apache.slide.webdav.util.ViolatedPrecondition;
+import org.apache.slide.webdav.util.PreconditionViolationException;
+
+import org.apache.slide.webdav.util.resourcekind.ResourceKind;
+import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
+import org.apache.slide.webdav.util.resourcekind.VersionControlled;
+import org.apache.slide.webdav.util.resourcekind.CheckedOutVersionControlled;
+import org.apache.slide.webdav.util.resourcekind.CheckedInVersionControlled;
import org.jdom.Element;
import org.jdom.Document;
@@ -145,7 +153,7 @@
/**
* An implementation of the DeltaV <code>REPORT</code> method.
*
- * @version $Revision: 1.9 $
+ * @version $Revision: 1.10 $
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ralf Stuckert</a>
*/
@@ -186,6 +194,11 @@
**/
protected static SAXBuilder saxBuilder = null;
+ /**
+ * Default depth is infite.
+ */
+ protected static final int INFINITY = Integer.MAX_VALUE;
+
/**
@@ -199,9 +212,11 @@
protected int depth = 0;
/**
- * The list of requested properties for the <code>version-tree</code> report.
+ * The list of requested properties for the <code>version-tree</code>,
+ * <code>acl-principal</code> and <code>locate-by-history</code>
+ * report.
*/
- protected RequestedProperties requestedVersionTreeProperties = null;
+ protected RequestedProperties requestedProperties = null;
/**
* The request content (XML) Document.
@@ -215,16 +230,20 @@
/**
* The <code><expand-property></code> element of an
- * expand-property report request.
+ * <code>expand-property</code> report request.
*/
protected Element expandPropertyElement = null;
/**
- * The list of requested properties for the <code>acl-principal</code> report.
+ * The <code><href></code> elements of the
<code><version-history-set></code>
+ * of an <code>locate-by-history</code> report request.
*/
- protected RequestedProperties requestedAclPrincipalProperties = null;
-
+ protected XMLValue versionHistorySet = null;
+ /**
+ * The VersioningHelper used by this method.
+ */
+ protected VersioningHelper versioningHelper = null;
/**
@@ -238,6 +257,7 @@
*/
public ReportMethod(NamespaceAccessToken token, HttpServletRequest request,
HttpServletResponse response, WebdavServletConfig servletConfig) {
super(token, request, response, servletConfig);
+ versioningHelper = VersioningHelper.getVersioningHelper(slideToken, token,
req, resp, servletConfig);
}
@@ -279,8 +299,10 @@
requestedReport = R_ACL_PRINCIPAL_PROPS;
parseACLPrincipalRequest(element);
}
- // TODO
- // locate-by-history report
+ else if (element.getName().equalsIgnoreCase(R_LOCATE_BY_HISTORY)){
+ requestedReport = R_LOCATE_BY_HISTORY;
+ parseLocateByHistoryRequest(element);
+ }
else{
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
@@ -294,6 +316,21 @@
catch (ParserConfigurationException e){
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
+ catch (WebdavException e) {
+ e.printStackTrace();
+ String statusText = getStatusText(e);
+ try {
+ if (statusText != null) {
+ resp.sendError(e.getStatusCode(), statusText);
+ }
+ else {
+ resp.sendError(e.getStatusCode());
+ }
+ }
+ catch (IOException ioe) {}
+ throw e;
+ }
+
}
/**
@@ -314,7 +351,7 @@
Element element = (Element)childrenList.get(0);
if ( E_ALLPROP.equals(element.getName()) ||
E_PROP.equals(element.getName()) ) {
- requestedVersionTreeProperties = new RequestedPropertiesImpl(element);
+ requestedProperties = new RequestedPropertiesImpl(element);
}
else {
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
@@ -339,7 +376,7 @@
Element element = (Element)childrenList.get(0);
if ( E_ALLPROP.equals(element.getName()) ||
E_PROP.equals(element.getName()) ) {
- requestedAclPrincipalProperties = new RequestedPropertiesImpl(element);
+ requestedProperties = new RequestedPropertiesImpl(element);
}
else {
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
@@ -358,6 +395,49 @@
this.expandPropertyElement = expandPropertyElement;
}
+ /**
+ * Parses the <code><locate-by-history></code> request.
+ *
+ * @param locateByHistoryElement the
<code><locate-by-history></code>
+ * Element.
+ *
+ * @throws WebdavException if parsing fails for any reason.
+ */
+ protected void parseLocateByHistoryRequest(Element locateByHistoryElement)
throws WebdavException {
+
+ List childrenList = locateByHistoryElement.getChildren();
+ if (childrenList.size() != 2) {
+ throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
+ }
+
+ Element versionHistorySetElement = null;
+ Element propElement = null;
+ if ( E_VERSION_HISTORY_SET.equals(((Element)childrenList.get(0)).getName())
&&
+ E_PROP.equals(((Element)childrenList.get(1)).getName()) ) {
+ versionHistorySetElement = (Element)childrenList.get(0);
+ propElement = (Element)childrenList.get(1);
+ }
+ else if ( E_PROP.equals(((Element)childrenList.get(0)).getName()) &&
+
E_VERSION_HISTORY_SET.equals(((Element)childrenList.get(1)).getName()) ) {
+ propElement = (Element)childrenList.get(0);
+ versionHistorySetElement = (Element)childrenList.get(1);
+ }
+ else {
+ throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
+ }
+
+ childrenList = versionHistorySetElement.getChildren();
+ versionHistorySet = new XMLValue(childrenList);
+ Iterator iterator = versionHistorySet.iterator();
+ while (iterator.hasNext()) {
+ if ( ! E_HREF.equals(((Element)iterator.next()).getName()) ) {
+ throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
+ }
+ }
+
+ requestedProperties = new RequestedPropertiesImpl(propElement);
+ }
+
/**
@@ -385,9 +465,16 @@
else if (R_ACL_PRINCIPAL_PROPS.equals(requestedReport)) {
executeAclPrincipalReport(requestUri, multistatusElement,
getDepth());
}
+ else if (R_LOCATE_BY_HISTORY.equals(requestedReport)) {
+ executeLocateByHistoryReport(requestUri, multistatusElement,
getDepth());
+ }
new XMLOutputter().output(multistatusElement,
getResponse().getWriter());
}
+ catch (PreconditionViolationException e) {
+ sendPreconditionViolation(e.getViolatedPrecondition());
+ throw e;
+ }
catch (Exception e) {
e.printStackTrace();
String statusText = getStatusText(e);
@@ -657,15 +744,13 @@
// get NodeRevisionDescriptor
try {
- VersioningHelper vHelp = VersioningHelper.getVersioningHelper(
- slideToken, token, req, resp, getConfig() );
if( !Configuration.useVersionControl() ) {
revisionDescriptors =
content.retrieve(slideToken, resourcePath);
}
else {
- revisionDescriptors =
vHelp.retrieveRevisionDescriptors(resourcePath);
+ revisionDescriptors =
versioningHelper.retrieveRevisionDescriptors(resourcePath);
}
try {
@@ -673,7 +758,7 @@
revisionDescriptor = content.retrieve(slideToken,
revisionDescriptors);
}
else {
- revisionDescriptor =
vHelp.retrieveLatestRevisionDescriptor(resourcePath, revisionDescriptors);
+ revisionDescriptor =
versioningHelper.retrieveLatestRevisionDescriptor(resourcePath, revisionDescriptors);
}
} catch (RevisionDescriptorNotFoundException e) {
@@ -741,7 +826,7 @@
Iterator principalIter = principals.iterator();
while (principalIter.hasNext()) {
String principalUrl =
((String)principalIter.next()).substring(token.getNamespaceConfig().toString().length()+1);
- Element response = getResponseElement(principalUrl,
revisionDescriptors, revisionNumber, slideToken, principalUrl,
requestedAclPrincipalProperties);
+ Element response = getResponseElement(principalUrl,
revisionDescriptors, revisionNumber, slideToken, principalUrl, requestedProperties);
parentElement.addContent((Element) response);
}
}
@@ -827,6 +912,153 @@
}
+ /**
+ * Executes a requested <code>locate-by-history</code> report.
+ *
+ * @param requestUri the URI of the requested resource.
+ * @param parentElement the parent Element to append the
+ * <response></code> to.
+ * @param depth the depth of the request.
+ *
+ * @throws WebdavException
+ * @throws ObjectLockedException
+ * @throws RevisionDescriptorNotFoundException
+ * @throws ServiceAccessException
+ * @throws LinkedObjectNotFoundException
+ * @throws AccessDeniedException
+ * @throws ObjectNotFoundException
+ * @throws JDOMException
+ * @throws PreconditionViolationException
+ * @throws SlideException
+ */
+ protected void executeLocateByHistoryReport(String requestUri, Element
parentElement, int depth) throws WebdavException, ObjectLockedException,
RevisionDescriptorNotFoundException, ServiceAccessException,
LinkedObjectNotFoundException, AccessDeniedException, ObjectNotFoundException,
JDOMException, PreconditionViolationException, SlideException {
+
+ // <locate-by-history> report can only be applied to collection
+ if ( ! WebdavUtils.isCollection(token, slideToken, requestUri) ) {
+ throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
+ }
+
+ // check DAV:must-be-version-history
+ Iterator iterator = versionHistorySet.iterator();
+ UriHandler uriHandler = null;
+ String href = null;
+ boolean isVersionHistory = true;
+ while (iterator.hasNext()) {
+ href = ((Element)iterator.next()).getText();
+ if (href == null) {
+ isVersionHistory = false;
+ }
+ else {
+ uriHandler = UriHandler.getUriHandler(token, href);
+ isVersionHistory = uriHandler.isHistoryUri();
+ }
+ if ( ! isVersionHistory ) {
+ throw new PreconditionViolationException(new
ViolatedPrecondition(C_MUST_BE_VERSION_HISTORY, WebdavStatus.SC_CONFLICT));
+ }
+ }
+ writeLocateByHistoryReport(requestUri, parentElement, depth);
+ }
+
+
+ /**
+ * Writes the <code>locate-by-history</code> report for the collection
+ * identified by the given <code>collectionUri</code>.
+ *
+ * @param collectionUri the URI of the collection.
+ * @param parentElement the parent Element to append the
+ * <response></code> to.
+ * @param depth the depth of the report.
+ *
+ * @throws WebdavException
+ * @throws ObjectLockedException
+ * @throws RevisionDescriptorNotFoundException
+ * @throws ServiceAccessException
+ * @throws LinkedObjectNotFoundException
+ * @throws AccessDeniedException
+ * @throws ObjectNotFoundException
+ * @throws JDOMException
+ * @throws SlideException
+ */
+ protected void writeLocateByHistoryReport(String collectionUri, Element
parentElement, int depth) throws WebdavException, ObjectLockedException,
RevisionDescriptorNotFoundException, ServiceAccessException,
LinkedObjectNotFoundException, AccessDeniedException, ObjectNotFoundException,
JDOMException, SlideException {
+
+ if (depth < 0) {
+ return;
+ }
+
+ NodeRevisionDescriptor revisionDescriptor = null;
+ NodeRevisionDescriptors revisionDescriptors = null;
+ ResourceKind resourceKind = null;
+ String versionHistoryUri = null;
+ ObjectNode collectionNode = structure.retrieve(slideToken, collectionUri);
+ Enumeration childrenEnum = structure.getChildren(slideToken,
collectionNode);
+ while (childrenEnum.hasMoreElements()) {
+
+ ObjectNode child = (ObjectNode)childrenEnum.nextElement();
+ if (child.hasChildren()) {
+ writeLocateByHistoryReport(child.getUri(), parentElement, depth-1);
+ }
+ else {
+ revisionDescriptors =
versioningHelper.retrieveRevisionDescriptors(child.getUri());
+ revisionDescriptor =
versioningHelper.retrieveLatestRevisionDescriptor(child.getUri(), revisionDescriptors);
+ resourceKind =
AbstractResourceKind.determineResourceKind(revisionDescriptor);
+ versionHistoryUri = null;
+
+ if (resourceKind instanceof VersionControlled) {
+ versionHistoryUri = getHistoryUriOfVCR(revisionDescriptors,
revisionDescriptor);
+ }
+
+ if (versionHistoryUri != null) {
+ boolean found = false;
+ Iterator iterator = versionHistorySet.iterator();
+ String currentHistoryUri = null;
+ while ( !found && iterator.hasNext() ) {
+ currentHistoryUri = ((Element)iterator.next()).getText();
+ found = versionHistoryUri.equals(currentHistoryUri);
+ }
+ if (found) {
+ parentElement.addContent(getResponseElement(child.getUri(),
revisionDescriptors, revisionDescriptor.getRevisionNumber(), slideToken,
child.getUri(), requestedProperties));
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Returns the URI of the history associated with the version controlled
+ * resource. If the resource is neither a checked-in nor checked-out
+ * version controlled resource, <code>null</code> is returned.
+ *
+ * @param revisionDescriptors the NodeRevisionDescriptors of the VCR.
+ * @param revisionDescriptor the NodeRevisionDescriptor of the VCR.
+ *
+ * @return the URI of the history associated with the VCR.
+ */
+ private String getHistoryUriOfVCR(NodeRevisionDescriptors revisionDescriptors,
NodeRevisionDescriptor revisionDescriptor) {
+
+ String historyUri = null;
+ NodeProperty property = revisionDescriptor.getProperty(P_CHECKED_IN);
+ if (property == null) {
+ property = revisionDescriptor.getProperty(P_CHECKED_OUT);
+ }
+ if ( (property != null) && (property.getValue() != null) ) {
+ try {
+ XMLValue xmlValue = new XMLValue(property.getValue().toString());
+ Iterator iterator = xmlValue.iterator();
+ if (iterator.hasNext()) {
+ String vrUri = ((Element)iterator.next()).getText();
+ UriHandler uriHandler = UriHandler.getUriHandler(token, vrUri);
+ if (uriHandler.isVersionUri()) {
+ historyUri = uriHandler.getAssociatedHistoryUri();
+ }
+ }
+ }
+ catch (JDOMException e) {}
+ }
+
+ return historyUri;
+ }
+
/**
* Creates a <code>RequestedProperties</code> object from a list of
@@ -894,10 +1126,10 @@
* @return the list of requested properties.
*/
protected RequestedProperties getRequestedVersionTreeProperties() {
- if (requestedVersionTreeProperties == null) {
- requestedVersionTreeProperties = new RequestedPropertiesImpl();
+ if (requestedProperties == null) {
+ requestedProperties = new RequestedPropertiesImpl();
}
- return requestedVersionTreeProperties;
+ return requestedProperties;
}
/**
@@ -934,11 +1166,29 @@
*/
protected void retrieveDepth() {
- depth = Integer.MAX_VALUE;
+ String depthStr = req.getHeader("Depth");
+ if (depthStr == null) {
+ depth = INFINITY;
+ } else if (depthStr.equals("0")) {
+ depth = 0;
+ } else if (depthStr.equals("1")) {
+ depth = 1;
+ } else if (depthStr.equalsIgnoreCase("infinity")) {
+ depth = INFINITY;
+ } else {
try {
- depth = req.getIntHeader("Depth");
+ depth = Integer.parseInt(depthStr);
+ if (depth < 0) {
+ depth = 0;
+ }
+ } catch (NumberFormatException ex) {
+ depth = INFINITY;
+ }
}
- catch (java.lang.NumberFormatException nfEx){
+
+ // limit tree browsing a bit
+ if (depth > getConfig().getDepthLimit()) {
+ depth = getConfig().getDepthLimit();
}
}
@@ -986,10 +1236,29 @@
String status = null;
if (exception instanceof WebdavException) {
-
WebdavStatus.getStatusText(((WebdavException)exception).getStatusCode());
+ status =
WebdavStatus.getStatusText(((WebdavException)exception).getStatusCode());
}
return status;
+ }
+
+ /**
+ * Sends a precondition vilolation response.
+ *
+ * @param violatedPrecondition the precondition that has been violated.
+ */
+ protected void sendPreconditionViolation(ViolatedPrecondition
violatedPrecondition) throws IOException {
+
+ if (violatedPrecondition != null) {
+
+ resp.setStatus(violatedPrecondition.getStatusCode());
+ resp.setContentType(TEXT_XML);
+
+ Element errorElement = new Element(E_ERROR,
Namespace.getNamespace(DEFAULT_NAMESPACE));
+ Element preconditionElement = new
Element(violatedPrecondition.getPrecondition(),
Namespace.getNamespace(DEFAULT_NAMESPACE));
+ errorElement.addContent(preconditionElement);
+ new XMLOutputter().output(errorElement, resp.getWriter());
+ }
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>