org.dspace.rest.Resource.java Source code

Java tutorial

Introduction

Here is the source code for org.dspace.rest.Resource.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.rest;

import java.net.CookieHandler;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.rest.exceptions.ContextException;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.usage.UsageEvent;
import org.dspace.utils.DSpace;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

/**
 * Superclass of all resource classes in REST API. It has methods for creating
 * context, write statistics, processsing exceptions, splitting a key of
 * metadata, string representation of action and method for getting the logged
 * in user from the token in request header.
 * 
 * @author Rostislav Novak (Computing and Information Centre, CTU in Prague)
 * 
 */
public class Resource {

    @javax.ws.rs.core.Context
    public ServletContext servletContext;

    private static Logger log = Logger.getLogger(Resource.class);

    private static final boolean writeStatistics;
    static {
        writeStatistics = DSpaceServicesFactory.getInstance().getConfigurationService()
                .getBooleanProperty("rest.stats", false);
    }

    /**
     * Create context to work with DSpace database. It can create context
     * with or without a logged in user (retrieved from SecurityContextHolder). Throws
     * WebApplicationException caused by: SQLException if there was a problem
     * with reading from database. Throws AuthorizeException if there was
     * a problem with authorization to read from the database. Throws Exception
     * if there was a problem creating context.
     * 
     * @return Newly created context with the logged in user unless the specified user was null.
     *     If user is null, create the context without a logged in user.
     * @throws ContextException
     *     Thrown in case of a problem creating context. Can be caused by
     *     SQLException error in creating context or finding the user to
     *     log in. Can be caused by AuthorizeException if there was a
     *     problem authorizing the found user.
     * @throws SQLException
     *     An exception that provides information on a database access error or other errors.
     */
    protected static org.dspace.core.Context createContext() throws ContextException, SQLException {
        org.dspace.core.Context context = new org.dspace.core.Context();
        //context.getDBConnection().setAutoCommit(false); // Disable autocommit.

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            Collection<SimpleGrantedAuthority> specialGroups = (Collection<SimpleGrantedAuthority>) authentication
                    .getAuthorities();
            for (SimpleGrantedAuthority grantedAuthority : specialGroups) {
                context.setSpecialGroup(EPersonServiceFactory.getInstance().getGroupService()
                        .findByName(context, grantedAuthority.getAuthority()).getID());
            }
            context.setCurrentUser(EPersonServiceFactory.getInstance().getEPersonService().findByEmail(context,
                    authentication.getName()));
        }

        return context;
    }

    /**
     * Records a statistics event about an object used via REST API.
     * @param dspaceObject
     *     DSpace object on which a request was performed.
     * @param action
     *     Action that was performed.
     * @param user_ip
     *     User's IP address.
     * @param user_agent
     *     User agent string (specifies browser used and its version).
     * @param xforwardedfor
     *     When accessed via a reverse proxy, the application sees the proxy's IP as the
     *     source of the request. The proxy may be configured to add the
     *     "X-Forwarded-For" HTTP header containing the original IP of the client
     *     so that the reverse-proxied application can get the client's IP.
     * @param headers
     *     If you want to access the item as the user logged into the
     *     context. The header "rest-dspace-token" with the token passed
     *     from the login method must be set.
     * @param request
     *     Servlet's HTTP request object.
     * @param context
     *     Context which must be aborted.
     */
    protected void writeStats(DSpaceObject dspaceObject, UsageEvent.Action action, String user_ip,
            String user_agent, String xforwardedfor, HttpHeaders headers, HttpServletRequest request,
            Context context) {
        if (!writeStatistics) {
            return;
        }

        if ((user_ip == null) || (user_ip.length() == 0)) {
            DSpaceServicesFactory.getInstance().getEventService()
                    .fireEvent(new UsageEvent(action, request, context, dspaceObject));
        } else {
            DSpaceServicesFactory.getInstance().getEventService()
                    .fireEvent(new UsageEvent(action, user_ip, user_agent, xforwardedfor, context, dspaceObject));
        }

        log.debug("fired event");
    }

    /**
     * Process exception, print message to logger error stream and abort DSpace
     * context.
     * 
     * @param message
     *     Message, which will be printed to error stream.
     * @param context
     *     Context which must be aborted.
     * @throws WebApplicationException
     *     This exception is throw for user of REST api.
     */
    protected static void processException(String message, org.dspace.core.Context context)
            throws WebApplicationException {
        if ((context != null) && (context.isValid())) {
            context.abort();
        }
        log.error(message);
        throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
    }

    /**
     * Process finally statement. It will print message to logger error stream
     * and abort DSpace context, if was not properly ended.
     *
     * @param context
     *     Context which must be aborted.
     * @throws WebApplicationException
     *     This exception is thrown for user of REST API.
     */
    protected void processFinally(org.dspace.core.Context context) throws WebApplicationException {
        if ((context != null) && (context.isValid())) {
            context.abort();
            log.error("Something get wrong. Aborting context in finally statement.");
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * Split string with regex ".".
     * 
     * @param key
     *     String which will be splitted.
     * @return String array filed with separated string.
     */
    protected String[] mySplit(String key) {
        ArrayList<String> list = new ArrayList<String>();
        int prev = 0;
        for (int i = 0; i < key.length(); i++) {
            if (key.charAt(i) == '.') {
                list.add(key.substring(prev, i));
                prev = i + 1;
            } else if (i + 1 == key.length()) {
                list.add(key.substring(prev, i + 1));
            }
        }

        if (list.size() == 2) {
            list.add(null);
        }

        return list.toArray(new String[0]);
    }

    /**
     * Return string representation of values
     * org.dspace.core.Constants.{READ,WRITE,DELETE}.
     * 
     * @param action
     *     Constant from org.dspace.core.Constants.*
     * @return String representation. read or write or delete.
     */
    protected String getActionString(int action) {
        String actionStr;
        switch (action) {
        case org.dspace.core.Constants.READ:
            actionStr = "read";
            break;
        case org.dspace.core.Constants.WRITE:
            actionStr = "write";
            break;
        case org.dspace.core.Constants.DELETE:
            actionStr = "delete";
            break;
        case org.dspace.core.Constants.REMOVE:
            actionStr = "remove";
            break;
        case org.dspace.core.Constants.ADD:
            actionStr = "add";
            break;
        default:
            actionStr = "(?action?)";
            break;
        }
        return actionStr;
    }

}