/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. 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.wink.webdav.server;
import java.io.StringReader;
import java.util.List;
import java.util.Set;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.xml.bind.Unmarshaller;
import org.apache.wink.common.http.HttpHeadersEx;
import org.apache.wink.common.http.HttpStatus;
import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
import org.apache.wink.common.internal.utils.HeaderUtils;
import org.apache.wink.server.internal.contexts.UriInfoImpl;
import org.apache.wink.server.internal.registry.ResourceInstance;
import org.apache.wink.server.internal.registry.ResourceRegistry;
import org.apache.wink.webdav.WebDAVHeaders;
import org.apache.wink.webdav.model.Activelock;
import org.apache.wink.webdav.model.Lockdiscovery;
import org.apache.wink.webdav.model.Lockinfo;
import org.apache.wink.webdav.model.Prop;
import org.apache.wink.webdav.model.WebDAVModelHelper;
public class WebDAVUtils {
// 1000 years ~ infinite timeout ("Infinite" constant is not accepted by MS
// client)
private static final String LOCK_TIMEOUT = "Second-31536000000"; //$NON-NLS-1$
/**
* Provides a default response with two additional headers for WebDAV and MS
* compatibility.
*
* @return
*/
public static Response getOptions(UriInfo info) {
List<ResourceInstance> matchedResourceInstances =
((UriInfoImpl)info).getMatchedResourceInstances();
ResourceRegistry resourceRegistry =
RuntimeContextTLS.getRuntimeContext().getAttribute(ResourceRegistry.class);
Set<String> options = resourceRegistry.getOptions(matchedResourceInstances.get(0));
String allowHeader = HeaderUtils.buildOptionsHeader(options);
Response response =
RuntimeDelegate.getInstance().createResponseBuilder().header(WebDAVHeaders.DAV, "1") //$NON-NLS-1$
.header(WebDAVHeaders.MS_AUTHOR_VIA, "DAV") //$NON-NLS-1$
.header(HttpHeadersEx.ALLOW, allowHeader).entity("").build(); //$NON-NLS-1$
return response;
}
/**
* This method does not perform a real lock but returns a 'dummy' lock
* response for compatibility with MS Windows. It opens any resource as
* read-only file when a lock is not received.
*
* @param body the lock request xml
* @return a response instance
*/
public static Response msCompatibilityLock(String body) {
// empty request means refreshing a lock
// it should not happen since we set infinite timeouts
// we do not respond properly - sending 200 OK with empty body
if (body == null || body.length() == 0) {
Response response = RuntimeDelegate.getInstance().createResponseBuilder().build();
return response;
}
// parse the request
Unmarshaller unmarshaller = WebDAVModelHelper.createUnmarshaller();
Lockinfo lockinfo =
WebDAVModelHelper.unmarshal(unmarshaller,
new StringReader(body),
Lockinfo.class,
"lockinfo"); //$NON-NLS-1$
// make a response
Activelock activelock = new Activelock();
// set lock type from the request
activelock.setLocktype(lockinfo.getLocktype());
// set lock scope from the request
activelock.setLockscope(lockinfo.getLockscope());
// set 0 depth
activelock.setDepth("0"); //$NON-NLS-1$
// set owner from the request
activelock.setOwner(lockinfo.getOwner());
// set infinite timeout
activelock.setTimeout(LOCK_TIMEOUT);
// a lock token is not necessary for MS compatibility
Lockdiscovery lockdiscovery = new Lockdiscovery();
lockdiscovery.getActivelock().add(activelock);
Prop prop = new Prop();
prop.setLockdiscovery(lockdiscovery);
Response response =
RuntimeDelegate.getInstance().createResponseBuilder().entity(prop).build();
return response;
}
/**
* This method does not perform a real unlock but returns a NO_CONTENT
* response for compatibility with MS Windows.
*
* @return a response instance
*/
public static Response msCompatibilityUnlock() {
Response response =
RuntimeDelegate.getInstance().createResponseBuilder().status(HttpStatus.NO_CONTENT
.getCode()).build();
return response;
}
}