/* * $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/ReportMethod.java,v 1.74 2005/02/25 17:03:53 luetzkendorf Exp $ * $Revision: 1.74 $ * $Date: 2005/02/25 17:03:53 $ * * ==================================================================== * * Copyright 1999-2002 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.apache.slide.webdav.method; import java.io.IOException; import org.apache.slide.common.NamespaceAccessToken; import org.apache.slide.common.ServiceAccessException; import org.apache.slide.common.SlideToken; import org.apache.slide.event.EventDispatcher; import org.apache.slide.webdav.WebdavException; import org.apache.slide.webdav.WebdavServletConfig; import org.apache.slide.webdav.event.WebdavEvent; import org.apache.slide.webdav.method.report.AbstractReport; import org.apache.slide.webdav.method.report.AclPrincipalPropSetReport; import org.apache.slide.webdav.method.report.ExpandPropertyReport; import org.apache.slide.webdav.method.report.LocateByHistoryReport; import org.apache.slide.webdav.method.report.PrincipalMatchReport; import org.apache.slide.webdav.method.report.PrincipalPropertySearchReport; import org.apache.slide.webdav.method.report.PrincipalSearchPropertySetReport; import org.apache.slide.webdav.method.report.VersionTreeReport; import org.apache.slide.webdav.util.AclConstants; import org.apache.slide.webdav.util.DeltavConstants; import org.apache.slide.webdav.util.PreconditionViolationException; import org.apache.slide.webdav.util.WebdavStatus; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.output.XMLOutputter; /** * REPORT method. * */ public class ReportMethod extends AbstractWebdavMethod implements DeltavConstants, AclConstants, ReadMethod, FineGrainedLockingMethod { private String resourcePath; private AbstractReport reportWorker; private String servletPath; /** * Constructor. * * @param token the token for accessing the namespace * @param config configuration of the WebDAV servlet */ public ReportMethod(NamespaceAccessToken token, WebdavServletConfig config) { super(token, config); } /** * @see org.apache.slide.webdav.method.FineGrainedLockingMethod#acquireFineGrainLocks() */ public void acquireFineGrainLocks() { acquireStandardLocks(resourcePath); // read lock history folder acquireHistoryLocks(resourcePath); } /** * Parse WebDAV XML request body. * * @exception WebdavException */ protected void parseRequest() throws WebdavException { Element reportElm; String reportName; resourcePath = requestUri; if (resourcePath == null) { resourcePath = "/"; } servletPath = req.getServletPath(); try{ reportElm = parseRequestContent().getRootElement(); reportName = reportElm.getName(); reportWorker = getExternalReportWorker(reportName); if (reportWorker == null) { if (R_EXPAND_PROPERTY.equals(reportName)) { reportWorker = new ExpandPropertyReport(slideToken, token, config, getSlideContextPath()); } else if (R_VERSION_TREE.equals(reportName)) { reportWorker = new VersionTreeReport(slideToken, token, config, getSlideContextPath()); ((VersionTreeReport)reportWorker).setVersioningHelper(versioningHelper); } else if (R_LOCATE_BY_HISTORY.equals(reportName)) { reportWorker = new LocateByHistoryReport(slideToken, token, config, getSlideContextPath()); } else if (R_ACL_PRINCIPAL_PROP_SET.equals(reportName)) { reportWorker = new AclPrincipalPropSetReport(slideToken, token, config, getSlideContextPath()); } else if (R_PRINCIPAL_MATCH.equals(reportName)) { reportWorker = new PrincipalMatchReport(slideToken, token, config, getSlideContextPath()); } else if (R_PRINCIPAL_PROPERTY_SEARCH.equals(reportName)) { reportWorker = new PrincipalPropertySearchReport(slideToken, token, config, getSlideContextPath()); } else if (R_PRINCIPAL_SEARCH_PROPERTY_SET.equals(reportName)) { reportWorker = new PrincipalSearchPropertySetReport(slideToken, token, config, getSlideContextPath()); } } if (reportWorker != null) { reportWorker.init(resourcePath, reportElm); } else { int statusCode = WebdavStatus.SC_BAD_REQUEST; sendError( statusCode, new Exception("Unknown report "+reportName) ); throw new WebdavException( statusCode ); } } catch (IOException e) { // TODO: merge exception handling into jdom access methods int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; sendError( statusCode, e ); throw new WebdavException( statusCode ); } catch (JDOMException e) { // TODO: merge exception handling into jdom access methods int statusCode = WebdavStatus.SC_BAD_REQUEST; sendError( statusCode, e ); throw new WebdavException( statusCode ); } catch (PreconditionViolationException e) { // TODO: merge exception handling into jdom access methods try { sendPreconditionViolation(e); throw e; } catch (IOException x) {} throw new WebdavException(e.getStatusCode()); } } private AbstractReport getExternalReportWorker(String reportName) throws JDOMException, WebdavException { AbstractReport result = null; String clsName = config.getExternalReport(reportName); if (clsName != null) { try { Class cls = Class.forName(clsName); Class[] parmtypes = {SlideToken.class, NamespaceAccessToken.class, WebdavServletConfig.class, String.class, String.class }; Object[] initargs = {slideToken, token, config, servletPath, getSlideContextPath() }; result = (AbstractReport)cls.getConstructor(parmtypes).newInstance(initargs); } catch( Exception e ) { int statusCode = WebdavStatus.SC_BAD_REQUEST; sendError( statusCode, new Exception("Cannot create "+reportName+" report worker "+clsName+" ["+e+"]") ); throw new WebdavException( statusCode ); } } return result; } /** * Execute the request. * * @exception WebdavException */ protected void executeRequest() throws WebdavException, IOException { resp.setContentType(TEXT_XML_UTF_8); // check lock-null resources try { if (isLockNull(resourcePath)) { int statusCode = WebdavStatus.SC_NOT_FOUND; sendError( statusCode, "lock-null resource", new Object[]{resourcePath} ); throw new WebdavException( statusCode ); } } catch (ServiceAccessException e) { int statusCode = getErrorCode( e ); sendError( statusCode, e ); throw new WebdavException( statusCode ); } try { if ( WebdavEvent.REPORT.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.REPORT, new WebdavEvent(this)); reportWorker.checkPreconditions(resourcePath, getDepth()); Element rootElm; if (reportWorker instanceof PrincipalSearchPropertySetReport) { rootElm = new Element(E_PRINCIPAL_SEARCH_PROPERTY_SET, DNSP); reportWorker.execute(resourcePath, rootElm, getDepth()); resp.setStatus(WebdavStatus.SC_OK); } else { rootElm = new Element(E_MULTISTATUS, DNSP); reportWorker.execute(resourcePath, rootElm, getDepth()); resp.setStatus(WebdavStatus.SC_MULTI_STATUS); } org.jdom.output.Format format = org.jdom.output.Format.getPrettyFormat(); format.setIndent(XML_RESPONSE_INDENT); new XMLOutputter(format). output(new Document(rootElm), resp.getWriter()); } catch (PreconditionViolationException e) { sendPreconditionViolation(e); throw e; } catch (Exception e) { int statusCode = getErrorCode( e ); sendError( statusCode, e ); throw new WebdavException( statusCode ); } } /** * Returns the value of the Depth request header. * * @return the value of the Depth request header. */ private int getDepth() throws WebdavException { int depth = requestHeaders.getDepth(0); // limit tree browsing a bit if (depth > config.getDepthLimit()) { depth = config.getDepthLimit(); } return depth; } }