/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/OptionsMethod.java,v 1.37.2.1 2004/02/05 16:11:23 mholz Exp $
* $Revision: 1.37.2.1 $
* $Date: 2004/02/05 16:11:23 $
*
* ====================================================================
*
* 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 java.util.Iterator;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionDescriptors;
import org.apache.slide.search.SearchLanguage;
import org.apache.slide.util.Configuration;
import org.apache.slide.webdav.WebdavException;
import org.apache.slide.webdav.WebdavServletConfig;
import org.apache.slide.webdav.util.AclConstants;
import org.apache.slide.webdav.util.BindConstants;
import org.apache.slide.webdav.util.DeltavConstants;
import org.apache.slide.webdav.util.HistoryPathHandler;
import org.apache.slide.webdav.util.UriHandler;
import org.apache.slide.webdav.util.WebdavUtils;
import org.apache.slide.webdav.util.WorkspacePathHandler;
import org.apache.slide.webdav.util.resourcekind.AbstractResourceKind;
import org.apache.slide.webdav.util.resourcekind.ResourceKind;
import org.apache.util.WebdavStatus;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.output.XMLOutputter;
/**
* OPTIONS Method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class OptionsMethod extends AbstractWebdavMethod
implements DeltavConstants, AclConstants, BindConstants {
// An XML outputter
private XMLOutputter xmlOut = new XMLOutputter(XML_REPONSE_INDENT, true, "UTF-8" );
// private Namespace xmlNs = Namespace.getNamespace(DEFAULT_NAMESPACE);
// the collections which may contain VH or workspace resources are requested
private boolean versionHistoryCollectionSetRequested = false;
private boolean workspaceCollectionSetRequested = false;
private boolean responseBodyNeeded = false;
// ----------------------------------------------------------- Constructors
/**
* Constructor.
*
* @param token the token for accessing the namespace
* @param config configuration of the WebDAV servlet
*/
public OptionsMethod(NamespaceAccessToken token,
WebdavServletConfig config) {
super(token, config);
}
protected void parseRequest() throws WebdavException {
if( req.getContentLength() > 0 ) {
try {
Iterator i = parseRequestContent(E_OPTIONS).getChildren().iterator();
while( i.hasNext() ) {
Element e = (Element)i.next();
if( e.getName().equals(E_VERSION_HISTORY_COLLECTION_SET) )
versionHistoryCollectionSetRequested = true;
if( e.getName().equals(E_WORKSPACE_COLLECTION_SET) )
workspaceCollectionSetRequested = true;
}
if( versionHistoryCollectionSetRequested || workspaceCollectionSetRequested )
responseBodyNeeded = true;
}
catch(JDOMException e ){
int statusCode = WebdavStatus.SC_BAD_REQUEST;
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
catch( IOException e ){
int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
}
}
protected void executeRequest() throws WebdavException {
/*
We have been experiencing a strange behaviour with the *creation* of a
Microsoft webfolder. When the DAV: header of an OPTIONS response
becomes too long, an <The folder you entered does not appear to be
valid. Please choose another.> error occurs.
As a workaround we break-up the DAV: header into multiple DAV: header
lines.
*/
StringBuffer davHeader = new StringBuffer();
davHeader.append( F_WEBDAV );
if( Configuration.useIntegratedLocking() )
davHeader.append( ", " ).append( F_LOCKING );
davHeader.append( ", " ).append( F_SLIDE );
if( Configuration.useIntegratedSecurity() )
davHeader.append( ", " ).append( F_ACCESS_CONTROL );
if( Configuration.useGlobalBinding() )
davHeader.append( ", " ).append( F_BINDING );
resp.addHeader( "DAV", davHeader.toString() );
if( Configuration.useVersionControl() ) {
davHeader = new StringBuffer();
davHeader.append( F_VERSION_CONTROL );
davHeader.append( ", " ).append( F_VERSION_HISTORY );
davHeader.append( ", " ).append( F_CHECKOUT_IN_PLACE );
resp.addHeader( "DAV", davHeader.toString() );
davHeader = new StringBuffer();
davHeader.append( F_WORKSPACE );
davHeader.append( ", " ).append( F_WORKING_RESOURCE );
davHeader.append( ", " ).append( F_UPDATE );
davHeader.append( ", " ).append( F_LABEL );
resp.addHeader( "DAV", davHeader.toString() );
}
String resourceUri = requestUri;
if (resourceUri == null) {
resourceUri = "/";
}
// prepare for allow-header
boolean resourceExists = false;
boolean resourceIsCollection = false;
SearchLanguage[] languages =
token.getSearchHelper().getSupportedLanguages ();
ResourceKind resourceKind = null;
try {
NodeRevisionDescriptors revisionDescriptors =
content.retrieve(slideToken, resourceUri);
NodeRevisionDescriptor revisionDescriptor =
content.retrieve(slideToken, revisionDescriptors);
resourceKind = AbstractResourceKind.determineResourceKind(token, revisionDescriptors, revisionDescriptor);
resourceExists = true;
if( WebdavUtils.isCollection(revisionDescriptor) )
resourceIsCollection = true;
} catch (SlideException e) {
if (resourceUri.equals("/")) {
resourceExists = true;
resourceIsCollection = true;
} else {
resourceExists = false;
}
}
// build allow-header
StringBuffer methodsAllowed = new StringBuffer();
if( resourceKind != null ) {
Iterator methodIterator = resourceKind.getSupportedMethods().iterator();
while (methodIterator.hasNext()) {
methodsAllowed.append((String)methodIterator.next());
methodsAllowed.append(", ");
}
if (methodsAllowed.length() > 1) {
methodsAllowed.setLength(methodsAllowed.length()-2);
}
}
else {
methodsAllowed.append( "OPTIONS, MKCOL, PUT" );
if( Configuration.useIntegratedLocking() )
methodsAllowed.append( ", LOCK" );
}
resp.addHeader("Allow", methodsAllowed.toString());
if (Configuration.useSearch () && languages != null && resourceExists)
for (int i = 0; i < languages.length; i++)
resp.addHeader ("DASL", "<" + languages [i].getGrammarUri() +
languages [i].getName () + ">");
resp.addHeader("MS-Author-Via", "DAV");
// build response body if needed
if( responseBodyNeeded ) {
resp.setContentType( TEXT_XML_UTF_8 );
UriHandler uh = UriHandler.getUriHandler( resourceUri );
String storeName = uh.getAssociatedBaseStoreName(token.getName());
UriHandler hpath = HistoryPathHandler.getHistoryPathHandler();
UriHandler wspath = WorkspacePathHandler.getWorkspacePathHandler();
Element ore =
new Element( E_OPTIONS_RESPONSE, DNSP );
if( versionHistoryCollectionSetRequested ) {
Element vhcse =
new Element( E_VERSION_HISTORY_COLLECTION_SET, DNSP );
Iterator i = ((HistoryPathHandler)hpath).getResolvedHistoryPaths(storeName).iterator();
while( i.hasNext() ) {
Element hre =
new Element( E_HREF,DNSP );
hre.addContent( getFullPath(String.valueOf(i.next())) );
vhcse.addContent( hre );
}
ore.addContent( vhcse );
}
if( workspaceCollectionSetRequested ) {
Element wscse =
new Element( E_WORKSPACE_COLLECTION_SET, DNSP );
Iterator i = ((WorkspacePathHandler)wspath).getResolvedWorkspacePaths(storeName).iterator();
while( i.hasNext() ) {
Element hre =
new Element( E_HREF, DNSP );
hre.addContent( getFullPath(String.valueOf(i.next())) );
wscse.addContent( hre );
}
ore.addContent( wscse );
}
try {
xmlOut.output(new Document(ore), resp.getWriter());
}
catch( IOException e ) {
int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
sendError( statusCode, e );
throw new WebdavException( statusCode );
}
}
}
}