com.flexive.chemistry.webdav.ObjectResource.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.chemistry.webdav.ObjectResource.java

Source

/***************************************************************
 *  This file is part of the [fleXive](R) framework.
 *
 *  Copyright (c) 1999-2014
 *  UCS - unique computing solutions gmbh (http://www.ucs.at)
 *  All rights reserved
 *
 *  The [fleXive](R) project is free software; you can redistribute
 *  it and/or modify it under the terms of the GNU Lesser General Public
 *  License version 2.1 or higher as published by the Free Software Foundation.
 *
 *  The GNU Lesser General Public License can be found at
 *  http://www.gnu.org/licenses/lgpl.html.
 *  A copy is found in the textfile LGPL.txt and important notices to the
 *  license from the author are found in LICENSE.txt distributed with
 *  these libraries.
 *
 *  This library 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.
 *
 *  For further information about UCS - unique computing solutions gmbh,
 *  please see the company website: http://www.ucs.at
 *
 *  For further information about [fleXive](R), please see the
 *  project website: http://www.flexive.org
 *
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package com.flexive.chemistry.webdav;

import com.bradmcevoy.http.*;
import com.bradmcevoy.http.exceptions.ConflictException;
import com.flexive.chemistry.webdav.extensions.CopyDocumentExtension;
import org.apache.chemistry.AllowableAction;
import org.apache.chemistry.CMISObject;
import org.apache.chemistry.NameConstraintViolationException;
import org.apache.chemistry.UpdateConflictException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import java.util.Collection;
import java.util.Date;

import static com.flexive.chemistry.webdav.AuthenticationFilter.getConnection;

/**
 * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 * @version $Rev$
 */
public abstract class ObjectResource<T extends CMISObject>
        implements GetableResource, PropFindableResource, MoveableResource, DeletableResource, CopyableResource {
    private static final Log LOG = LogFactory.getLog(ObjectResource.class);

    /** The security realm for HTTP authentication */
    public static final String SECURITY_REALM = "WebDAV";

    /** Max age for contents retrieved by the guest user (10 days) */
    private static final long MAX_AGE_GUEST = 10L * 24 * 60 * 60;
    /** Max age for contents retrieved by a logged in user (10 minutes) */
    private static final long MAX_AGE_USER = 10L * 60;

    protected final ChemistryResourceFactory resourceFactory;
    protected final T object;
    protected final String path;

    protected ObjectResource(ChemistryResourceFactory resourceFactory, String path, T object) {
        this.resourceFactory = resourceFactory;
        this.path = path;
        this.object = object;
    }

    public T getObject() {
        return object;
    }

    /**
     * {@inheritDoc}
     */
    public String getUniqueId() {
        return object.getId();
    }

    /**
     * {@inheritDoc}
     */
    public Object authenticate(String user, String password) {
        // indicate that the user is already logged in. The authentication is performed in
        // AuthenticationFilter because at this place, the resource resolution has already
        // happened 
        return "authenticated";
    }

    /**
     * {@inheritDoc}
     */
    public boolean authorise(Request request, Request.Method method, Auth auth) {
        final Collection<QName> actions = getConnection().getSPI().getAllowableActions(object);
        switch (method) {
        case GET:
        case PROPFIND:
            return true; // since we already loaded it, we can also read
        case PUT:
            return actions.contains(AllowableAction.CAN_CREATE_DOCUMENT)
                    || actions.contains(AllowableAction.CAN_CREATE_FOLDER)
                    || actions.contains(AllowableAction.CAN_ADD_OBJECT_TO_FOLDER);
        case POST:
        case PROPPATCH:
            return actions.contains(AllowableAction.CAN_UPDATE_PROPERTIES);
        case DELETE:
            return actions.contains(AllowableAction.CAN_DELETE_OBJECT);
        case LOCK:
            return actions.contains(AllowableAction.CAN_CHECK_OUT);
        case UNLOCK:
            return actions.contains(AllowableAction.CAN_CANCEL_CHECK_OUT)
                    || actions.contains(AllowableAction.CAN_CHECK_IN);
        case MOVE:
            return actions.contains(AllowableAction.CAN_MOVE_OBJECT);
        default:
            return true;
        }
    }

    /**
     * {@inheritDoc}
     */
    public String getRealm() {
        return SECURITY_REALM; // TODO?
    }

    /**
     * {@inheritDoc}
     */
    public String checkRedirect(Request request) {
        return null; // TODO
    }

    /**
     * {@inheritDoc}
     */
    public Long getMaxAgeSeconds(Auth auth) {
        return MAX_AGE_GUEST;
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return object.getName();
    }

    /**
     * {@inheritDoc}
     */
    public Date getModifiedDate() {
        return object.getLastModificationDate().getTime();
    }

    /**
     * {@inheritDoc}
     */
    public Date getCreateDate() {
        return object.getCreationDate().getTime();
    }

    /**
     * {@inheritDoc}
     */
    public void moveTo(CollectionResource rDest, String name) throws ConflictException {
        final com.flexive.chemistry.webdav.FolderResource target = (com.flexive.chemistry.webdav.FolderResource) rDest;
        final String oldName = object.getName();
        boolean done = false;
        try {
            if (isOverwriteRequest()) {
                final ObjectResource targetRes = (ObjectResource) resourceFactory.getResource(null,
                        target.getChildPath(name));
                if (targetRes != null) {
                    try {
                        targetRes.delete();
                    } catch (Exception e) {
                        if (LOG.isWarnEnabled()) {
                            LOG.warn("Failed to remove " + target.getChildPath(name) + ": " + e.getMessage(), e);
                        }
                        // try to move the object anyway...
                    }
                }
            }
            if (!target.getObject().getId().equals(object.getParent().getId())) {
                object.move(target.getObject(), object.getParent());
            }
            if (!oldName.equals(name)) {
                // save name change (TODO: cannot move *and* set name in one operation)
                object.setName(name);
                object.save();
            }
            done = true;
        } catch (NameConstraintViolationException e) {
            throw new ConflictException(this);
        } catch (UpdateConflictException e) {
            throw new ConflictException(this);
        } finally {
            // now name is changed after moving, so if we go wrong there we don't do anything
            /*if (!done) {
            try {
                object.setName(oldName);    // restore object name in case of errors
            } catch (NameConstraintViolationException e) {
                // cannot do much except emit a warning
                if (LOG.isWarnEnabled()) {
                    LOG.warn("Failed to restore old filename: " + e.getMessage(), e);
                }
            }
            }*/
        }
    }

    /**
     * {@inheritDoc}
     */
    public void copyTo(CollectionResource toCollection, String name) {
        copyObject(toCollection, name, isOverwriteRequest());
    }

    protected void copyObject(CollectionResource toCollection, String name, boolean overwrite) {
        // get extension for direct copying
        final CopyDocumentExtension cde = getConnection().getRepository().getExtension(CopyDocumentExtension.class);
        if (cde == null) {
            throw new UnsupportedOperationException(
                    "Copy not supported, please implement " + CopyDocumentExtension.class.getCanonicalName());
        }
        // perform copy and add to target folder
        try {
            cde.copy(getConnection(), object, ((FolderResource) toCollection).getObject(), name, overwrite,
                    getDepthHeader() == 0);
        } catch (UpdateConflictException e) {
            throw new IllegalArgumentException(e);
        } catch (NameConstraintViolationException e) {
            throw new IllegalArgumentException(e);
        }
    }

    protected boolean isOverwriteRequest() {
        final String overwriteFlag = getRequestHeader("overwrite");
        return "T".equalsIgnoreCase(overwriteFlag);
    }

    protected int getDepthHeader() {
        return HttpManager.request() != null ? HttpManager.request().getDepthHeader() : AbstractRequest.INFINITY;
    }

    protected String getRequestHeader(String name) {
        return HttpManager.request() != null ? HttpManager.request().getHeaders().get(name) : null;
    }

    protected String getChildPath(String childName) {
        return path + (path.endsWith("/") ? "" : "/") + childName;
    }
}