
org.modeshape.webdav.methods.DoProppatch Maven / Gradle / Ivy
The newest version!
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.modeshape.webdav.methods;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import org.modeshape.common.i18n.TextI18n;
import org.modeshape.webdav.ITransaction;
import org.modeshape.webdav.IWebdavStore;
import org.modeshape.webdav.StoredObject;
import org.modeshape.webdav.WebdavStatus;
import org.modeshape.webdav.exceptions.AccessDeniedException;
import org.modeshape.webdav.exceptions.LockFailedException;
import org.modeshape.webdav.exceptions.WebdavException;
import org.modeshape.webdav.fromcatalina.RequestUtil;
import org.modeshape.webdav.fromcatalina.XMLHelper;
import org.modeshape.webdav.fromcatalina.XMLWriter;
import org.modeshape.webdav.locking.LockedObject;
import org.modeshape.webdav.locking.ResourceLocks;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public class DoProppatch extends AbstractMethod {
private boolean readOnly;
private IWebdavStore store;
private ResourceLocks resourceLocks;
public DoProppatch( IWebdavStore store,
ResourceLocks resLocks,
boolean readOnly ) {
this.readOnly = readOnly;
this.store = store;
this.resourceLocks = resLocks;
}
@Override
public void execute( ITransaction transaction,
HttpServletRequest req,
HttpServletResponse resp ) throws IOException, LockFailedException {
logger.trace("-- " + this.getClass().getName());
if (readOnly) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
return;
}
String path = getRelativePath(req);
String parentPath = getParentPath(getCleanPath(path));
Hashtable errorList = new Hashtable();
if (!isUnlocked(transaction, req, resourceLocks, parentPath)) {
resp.setStatus(WebdavStatus.SC_LOCKED);
return; // parent is locked
}
if (!isUnlocked(transaction, req, resourceLocks, path)) {
resp.setStatus(WebdavStatus.SC_LOCKED);
return; // resource is locked
}
// Retrieve the resources
String tempLockOwner = "doProppatch" + System.currentTimeMillis() + req.toString();
if (resourceLocks.lock(transaction, path, tempLockOwner, false, 0, TEMP_TIMEOUT, TEMPORARY)) {
StoredObject so = null;
LockedObject lo = null;
try {
so = store.getStoredObject(transaction, path);
lo = resourceLocks.getLockedObjectByPath(transaction, getCleanPath(path));
if (so == null) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
// we do not to continue since there is no root
// resource
}
if (so.isNullResource()) {
String methodsAllowed = DeterminableMethod.determineMethodsAllowed(so);
resp.addHeader("Allow", methodsAllowed);
resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
return;
}
String[] lockTokens = getLockIdFromIfHeader(req);
boolean lockTokenMatchesIfHeader = (lockTokens != null && lockTokens[0].equals(lo.getID()));
if (lo != null && lo.isExclusive() && !lockTokenMatchesIfHeader) {
// Object on specified path is LOCKED
errorList = new Hashtable();
errorList.put(path, WebdavStatus.SC_LOCKED);
sendReport(req, resp, errorList);
return;
}
Map propertiesToSet = new HashMap();
List propertiesToRemove = new ArrayList();
List allProperties = new Vector();
Map response = null;
path = getCleanPath(getRelativePath(req));
Node tosetNode = null;
Node toremoveNode = null;
if (RequestUtil.streamNotConsumed(req)) {
DocumentBuilder documentBuilder = getDocumentBuilder();
try {
Document document = documentBuilder.parse(new InputSource(req.getInputStream()));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
tosetNode = XMLHelper.findSubElement(XMLHelper.findSubElement(rootElement, "set"), "prop");
if (tosetNode != null) {
propertiesToSet = XMLHelper.getPropertiesWithValuesFromXML(tosetNode);
}
toremoveNode = XMLHelper.findSubElement(XMLHelper.findSubElement(rootElement, "remove"), "prop");
if (toremoveNode != null) {
propertiesToRemove = XMLHelper.getPropertiesFromXML(toremoveNode);
}
if (!propertiesToSet.isEmpty() || !propertiesToRemove.isEmpty()) {
response = store.setCustomProperties(transaction, path, propertiesToSet, propertiesToRemove);
}
} catch (Exception e) {
resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
return;
}
} else {
// no content: error
resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
return;
}
allProperties.addAll(propertiesToSet.keySet());
allProperties.addAll(propertiesToRemove);
HashMap namespaces = new HashMap();
namespaces.put("DAV:", "D");
resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
resp.setContentType("text/xml; charset=UTF-8");
// Create multistatus object
XMLWriter generatedXML = new XMLWriter(resp.getWriter(), namespaces);
generatedXML.writeXMLHeader();
generatedXML.writeElement("DAV::multistatus", XMLWriter.OPENING);
generatedXML.writeElement("DAV::response", XMLWriter.OPENING);
// Generating href element
generatedXML.writeElement("DAV::href", XMLWriter.OPENING);
String href = req.getContextPath();
if ((href.endsWith("/")) && (path.startsWith("/"))) {
href += path.substring(1);
} else {
href += path;
}
if ((so.isFolder()) && (!href.endsWith("/"))) {
href += "/";
}
generatedXML.writeText(rewriteUrl(href));
generatedXML.writeElement("DAV::href", XMLWriter.CLOSING);
for (String property : allProperties) {
generatedXML.writeElement("DAV::propstat", XMLWriter.OPENING);
generatedXML.writeElement("DAV::prop", XMLWriter.OPENING);
generatedXML.writeElement(property, XMLWriter.NO_CONTENT);
generatedXML.writeElement("DAV::prop", XMLWriter.CLOSING);
generatedXML.writeElement("DAV::status", XMLWriter.OPENING);
generatedXML.writeText(statusForProperty(property, response));
generatedXML.writeElement("DAV::status", XMLWriter.CLOSING);
generatedXML.writeElement("DAV::propstat", XMLWriter.CLOSING);
}
if (response != null && !response.isEmpty()) {
String firstErrorMessage = response.entrySet().iterator().next().getValue();
generatedXML.writeProperty("DAV::responsedescription", firstErrorMessage);
}
generatedXML.writeElement("DAV::response", XMLWriter.CLOSING);
generatedXML.writeElement("DAV::multistatus", XMLWriter.CLOSING);
if (logger.isTraceEnabled()) {
logger.trace("Sending response: {0}", generatedXML.toString());
}
generatedXML.sendData();
} catch (AccessDeniedException e) {
resp.sendError(WebdavStatus.SC_FORBIDDEN);
} catch (WebdavException e) {
resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (ServletException e) {
logger.error(e, new TextI18n("Cannot create document builder"));
} finally {
resourceLocks.unlockTemporaryLockedObjects(transaction, path, tempLockOwner);
}
} else {
resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
private String statusForProperty( String propertyName,
Map response ) {
if (response == null || response.isEmpty()) {
return "HTTP/1.1 " + WebdavStatus.SC_OK + " " + WebdavStatus.getStatusText(WebdavStatus.SC_OK);
} else if (response.containsKey(propertyName)) {
return "HTTP/1.1 " + WebdavStatus.SC_BAD_REQUEST + " " + WebdavStatus.getStatusText(WebdavStatus.SC_BAD_REQUEST);
} else {
return "HTTP/1.1 " + WebdavStatus.SC_FAILED_DEPENDENCY + " "
+ WebdavStatus.getStatusText(WebdavStatus.SC_FAILED_DEPENDENCY);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy