001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider.webdav;
018
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.Collections;
022
023import org.apache.commons.httpclient.HttpClient;
024import org.apache.commons.vfs2.Capability;
025import org.apache.commons.vfs2.FileName;
026import org.apache.commons.vfs2.FileObject;
027import org.apache.commons.vfs2.FileSystem;
028import org.apache.commons.vfs2.FileSystemConfigBuilder;
029import org.apache.commons.vfs2.FileSystemException;
030import org.apache.commons.vfs2.FileSystemOptions;
031import org.apache.commons.vfs2.UserAuthenticationData;
032import org.apache.commons.vfs2.provider.GenericFileName;
033import org.apache.commons.vfs2.provider.http.HttpClientFactory;
034import org.apache.commons.vfs2.provider.http.HttpFileProvider;
035import org.apache.commons.vfs2.util.UserAuthenticatorUtils;
036
037/**
038 * A provider for WebDAV.
039 *
040 * @since 2.0
041 */
042public class WebdavFileProvider extends HttpFileProvider {
043
044    /**
045     * The authenticator types used by the WebDAV provider.
046     *
047     * @deprecated Might be removed in the next major version.
048     */
049    @Deprecated
050    public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = {
051            UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD };
052
053    /** The capabilities of the WebDAV provider */
054    protected static final Collection<Capability> capabilities = Collections
055            .unmodifiableCollection(Arrays.asList(Capability.CREATE, Capability.DELETE, Capability.RENAME, Capability.GET_TYPE,
056                    Capability.LIST_CHILDREN, Capability.READ_CONTENT, Capability.URI, Capability.WRITE_CONTENT,
057                    Capability.GET_LAST_MODIFIED, Capability.ATTRIBUTES, Capability.RANDOM_ACCESS_READ,
058                    Capability.DIRECTORY_READ_CONTENT));
059
060    /**
061     * Constructs a new instance.
062     */
063    public WebdavFileProvider() {
064        setFileNameParser(WebdavFileNameParser.getInstance());
065    }
066
067    /**
068     * Creates a {@link FileSystem}.
069     * <p>
070     * If you're looking at this method and wondering how to get a FileSystemOptions object bearing the proxy host and
071     * credentials configuration through to this method so it's used for resolving a
072     * {@link org.apache.commons.vfs2.FileObject FileObject} in the FileSystem, then be sure to use correct signature of
073     * the {@link org.apache.commons.vfs2.FileSystemManager FileSystemManager} resolveFile method.
074     * </p>
075     *
076     * @see org.apache.commons.vfs2.impl.DefaultFileSystemManager#resolveFile(FileObject, String, FileSystemOptions)
077     */
078    @Override
079    protected FileSystem doCreateFileSystem(final FileName name, final FileSystemOptions fileSystemOptions)
080            throws FileSystemException {
081        // Create the file system
082        final GenericFileName rootName = (GenericFileName) name;
083        final FileSystemOptions fsOpts = fileSystemOptions == null ? new FileSystemOptions() : fileSystemOptions;
084
085        UserAuthenticationData authData = null;
086        HttpClient httpClient;
087        try {
088            authData = UserAuthenticatorUtils.authenticate(fsOpts, AUTHENTICATOR_TYPES);
089
090            httpClient = HttpClientFactory.createConnection(WebdavFileSystemConfigBuilder.getInstance(), "http",
091                    rootName.getHostName(), rootName.getPort(),
092                    UserAuthenticatorUtils.toString(UserAuthenticatorUtils.getData(authData,
093                            UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName()))),
094                    UserAuthenticatorUtils.toString(UserAuthenticatorUtils.getData(authData,
095                            UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword()))),
096                    fsOpts);
097        } finally {
098            UserAuthenticatorUtils.cleanup(authData);
099        }
100
101        return new WebdavFileSystem(rootName, httpClient, fsOpts);
102    }
103
104    @Override
105    public Collection<Capability> getCapabilities() {
106        return capabilities;
107    }
108
109    @Override
110    public FileSystemConfigBuilder getConfigBuilder() {
111        return WebdavFileSystemConfigBuilder.getInstance();
112    }
113}