net.sourceforge.ganttproject.document.webdav.MiltonResourceImpl.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.ganttproject.document.webdav.MiltonResourceImpl.java

Source

/*
Copyright 2012 GanttProject Team
    
This file is part of GanttProject, an opensource project management tool.
    
GanttProject is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
    
GanttProject is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with GanttProject.  If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.ganttproject.document.webdav;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.OutputSupplier;
import io.milton.common.Path;
import io.milton.http.exceptions.BadRequestException;
import io.milton.http.exceptions.ConflictException;
import io.milton.http.exceptions.NotAuthorizedException;
import io.milton.http.exceptions.NotFoundException;
import io.milton.httpclient.File;
import io.milton.httpclient.Folder;
import io.milton.httpclient.Host;
import io.milton.httpclient.HttpException;
import io.milton.httpclient.ProgressListener;
import io.milton.httpclient.Resource;
import io.milton.httpclient.Utils.CancelledException;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;

/**
 * Implementation which uses Milton client library.
 *
 * @author dbarashev (Dmitry Barashev)
 */
public class MiltonResourceImpl implements WebDavResource {
    private static final ProgressListener PROGRESS_LISTENER_STUB = null;
    private Resource myImpl;
    private final WebDavUri myUrl;
    private final Host myHost;
    private Boolean myExistance;
    private MiltonResourceFactory myFactory;

    MiltonResourceImpl(WebDavUri webDavUri, Resource impl, MiltonResourceFactory factory) {
        myUrl = webDavUri;
        myImpl = impl;
        myFactory = factory;
        myExistance = true;
        myHost = impl.host();
    }

    MiltonResourceImpl(WebDavUri uri, Host host, MiltonResourceFactory factory) {
        myFactory = factory;
        myUrl = uri;
        myHost = host;
    }

    @Override
    public boolean exists() throws WebDavException {
        if (myExistance == null) {
            Resource impl = getOptionalImpl();
            myExistance = Boolean.valueOf(impl != null);
        }
        return myExistance;
    }

    private void assertExists() {
        try {
            if (!exists()) {
                throw new WebDavRuntimeException(
                        MessageFormat.format("Resource {0} does not exist on {1}", myUrl.path, myUrl.hostName));
            }
        } catch (WebDavException e) {
            throw new WebDavRuntimeException(
                    MessageFormat.format("Resource {0} does not exist on {1}", myUrl.path, myUrl.hostName), e);
        }
    }

    @Override
    public boolean isCollection() {
        assertExists();
        return (myImpl instanceof File) == false;
    }

    private Resource getOptionalImpl() throws WebDavException {
        if (myImpl != null) {
            return myImpl;
        }
        Host host = getHost();
        try {
            Resource resolved = host.find(myUrl.path);
            if (resolved != null) {
                myImpl = resolved;
                return myImpl;
            }
        } catch (NotAuthorizedException e) {
            throw new WebDavException(
                    MessageFormat.format("User {0} is not authorized to access {1}", getUsername(), myUrl.hostName),
                    e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when accessing {0}", myUrl.hostName), e);
        } catch (IOException e) {
            throw new WebDavException(MessageFormat.format("I/O problems when accessing {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when accessing {0}", myUrl.hostName), e);
        }
        return null;
    }

    private Host getHost() {
        return myHost;
    }

    @Override
    public boolean isLockSupported(boolean exclusive) {
        assertExists();
        if (myImpl.getSupportedLock() == null) {
            return false;
        }
        if (exclusive) {
            return myImpl.getSupportedLock().exclusive;
        }
        return myImpl.getSupportedLock().shared;
    }

    @Override
    public List<String> getLockOwners() {
        String lockOwner = myImpl == null ? null : myImpl.getLockOwner();
        return lockOwner == null ? Collections.<String>emptyList() : ImmutableList.<String>of(lockOwner);
    }

    public boolean canLock(String username) {
        assertExists();
        if (!isLockSupported(true)) {
            return false;
        }
        List<String> lockOwners = getLockOwners();
        return lockOwners.isEmpty() || lockOwners.equals(ImmutableList.of(username));
    }

    @Override
    public boolean isLocked() {
        return !getLockOwners().isEmpty();
    }

    @Override
    public void lock(int timeout) throws WebDavException {
        assertExists();
        try {
            myImpl.lock(timeout);
        } catch (NotAuthorizedException e) {
            throw new WebDavException(MessageFormat.format("User {0} is probably not authorized to access {1}",
                    getUsername(), myUrl.hostName), e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when accessing {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when accessing {0}", myUrl.hostName), e);
        } catch (ConflictException e) {
            throw new WebDavException(MessageFormat.format("Conflict when accessing {0}", myUrl.hostName), e);
        } catch (NotFoundException e) {
            throw new WebDavException(
                    MessageFormat.format("Resource {0} is not found on {1}", myUrl.path, myUrl.hostName), e);
        }
    }

    @Override
    public void unlock() throws WebDavException {
        if (!isLocked()) {
            return;
        }
        assertExists();
        try {
            myImpl.unlock();
        } catch (NotAuthorizedException e) {
            throw new WebDavException(MessageFormat.format("User {0} is probably not authorized to access {1}",
                    getUsername(), myUrl.hostName), e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when accessing {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when accessing {0}", myUrl.hostName), e);
        } catch (ConflictException e) {
            throw new WebDavException(MessageFormat.format("Conflict when accessing {0}", myUrl.hostName), e);
        } catch (NotFoundException e) {
            throw new WebDavException(
                    MessageFormat.format("Resource {0} is not found on {1}", myUrl.path, myUrl.hostName), e);
        }
    }

    @Override
    public WebDavResource getParent() {
        if (myImpl != null) {
            return new MiltonResourceImpl(myUrl.buildParent(), myImpl.parent, myFactory);
        }
        return new MiltonResourceImpl(myUrl.buildParent(), myHost, myFactory);
    }

    @Override
    public WebDavUri getWebDavUri() {
        return myUrl;
    }

    @Override
    public String getUrl() {
        return myUrl == null ? myImpl.encodedUrl() : myUrl.buildUrl();
    }

    @Override
    public List<WebDavResource> getChildResources() throws WebDavException {
        assertExists();
        try {
            return Lists.transform(((Folder) myImpl).children(), new Function<Resource, WebDavResource>() {
                @Override
                public WebDavResource apply(Resource r) {
                    return new MiltonResourceImpl(myUrl.buildChild(r.name), r, myFactory);
                }
            });
        } catch (NotAuthorizedException e) {
            throw new WebDavException(MessageFormat.format("User {0} is probably not authorized to access {1}",
                    getUsername(), myUrl.hostName), e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when accessing {0}", myUrl.hostName), e);
        } catch (IOException e) {
            throw new WebDavException(MessageFormat.format("I/O problems when accessing {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when accessing {0}", myUrl.hostName), e);
        }
    }

    @Override
    public String getName() {
        if (myImpl != null) {
            return myImpl.name;
        }
        return Path.path(myUrl.path).getName();
    }

    @Override
    public void write(byte[] byteArray) throws WebDavException {
        MiltonResourceImpl parent = (MiltonResourceImpl) getParent();
        if (!parent.exists()) {
            throw new WebDavException(MessageFormat.format("Folder {0} does not exist", parent.getName()));
        }
        assert parent.myImpl instanceof Folder;
        Folder parentFolder = (Folder) parent.myImpl;
        try {
            final java.io.File tempFile = java.io.File.createTempFile("webdav-" + myUrl.hostUrl, "");
            ByteStreams.write(byteArray, new OutputSupplier<OutputStream>() {
                @Override
                public OutputStream getOutput() throws IOException {
                    return new BufferedOutputStream(new FileOutputStream(tempFile));
                }
            });
            parentFolder.uploadFile(getName(), tempFile, null);
        } catch (NotAuthorizedException e) {
            throw new WebDavException(MessageFormat.format("User {0} is probably not authorized to access {1}",
                    getUsername(), myUrl.hostName), e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when accessing {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when accessing {0}", myUrl.hostName), e);
        } catch (ConflictException e) {
            throw new WebDavException(MessageFormat.format("Conflict when accessing {0}", myUrl.hostName), e);
        } catch (NotFoundException e) {
            throw new WebDavException(
                    MessageFormat.format("Resource {0} is not found on {1}", myUrl.path, myUrl.hostName), e);
        } catch (FileNotFoundException e) {
            throw new WebDavException(
                    MessageFormat.format("I/O problems when uploading {0} to {1}", myUrl.path, myUrl.hostName), e);
        } catch (IOException e) {
            throw new WebDavException(
                    MessageFormat.format("I/O problems when uploading {0} to {1}", myUrl.path, myUrl.hostName), e);
        }
    }

    @Override
    public InputStream getInputStream() throws WebDavException {
        assertExists();
        assert myImpl instanceof File;
        File file = (File) myImpl;
        ByteArrayOutputStream content = new ByteArrayOutputStream();
        try {
            file.download(content, PROGRESS_LISTENER_STUB);
            return new ByteArrayInputStream(content.toByteArray());
        } catch (CancelledException e) {
            throw new WebDavException("File download has been canceled", e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP error {0} while downloading file", e.getResult()),
                    e);
        }
    }

    @Override
    public boolean isWritable() {
        try {
            if (exists()) {
                return canLock();
            }
            WebDavResource parent = getParent();
            return parent.exists() && parent.isWritable();
        } catch (WebDavException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean canLock() throws WebDavException {
        assertExists();
        if (myImpl.getSupportedLock() == null) {
            return false;
        }
        if (!myImpl.getSupportedLock().exclusive) {
            return false;
        }
        List<String> lockOwners = getLockOwners();
        return lockOwners.isEmpty() || lockOwners.equals(ImmutableList.of(getUsername()));
    }

    private String getUsername() {
        return myHost.user;
    }

    @Override
    public void delete() throws WebDavException {
        assertExists();
        try {
            myImpl.delete();
        } catch (NotAuthorizedException e) {
            throw new WebDavException(MessageFormat.format("User {0} is probably not authorized to access {1}",
                    getUsername(), myUrl.hostName), e);
        } catch (BadRequestException e) {
            throw new WebDavException(MessageFormat.format("Bad request when deleting {0}", myUrl.hostName), e);
        } catch (HttpException e) {
            throw new WebDavException(MessageFormat.format("HTTP problems when deleting {0}", myUrl.hostName), e);
        } catch (ConflictException e) {
            throw new WebDavException(MessageFormat.format("Conflict when deleting {0}", myUrl.hostName), e);
        } catch (NotFoundException e) {
            throw new WebDavException(
                    MessageFormat.format("Resource {0} is not found on {1}", myUrl.path, myUrl.hostName), e);
        } catch (IOException e) {
            throw new WebDavException(MessageFormat.format("I/O problems when deleting {0}", myUrl.hostName), e);
        }
    }
}