fi.helsinki.lib.simplerest.ItemsResource.java Source code

Java tutorial

Introduction

Here is the source code for fi.helsinki.lib.simplerest.ItemsResource.java

Source

/**
 * A RESTful web service on top of DSpace.
 * Copyright (C) 2010-2014 National Library of Finland
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */

package fi.helsinki.lib.simplerest;

import com.google.gson.Gson;
import fi.helsinki.lib.simplerest.stubs.StubItem;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;

import org.dspace.content.WorkspaceItem;
import org.dspace.content.ItemIterator;

import org.dspace.content.*;

import org.restlet.ext.xml.DomRepresentation;
import org.restlet.ext.fileupload.RestletFileUpload;
import org.restlet.representation.Representation;
import org.restlet.representation.InputRepresentation;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import org.restlet.resource.Post;
import org.restlet.resource.Delete;
import org.restlet.resource.ResourceException;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.data.Method;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.log4j.Logger;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Priority;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.identifier.IdentifierException;

public class ItemsResource extends BaseResource {

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

    private Item[] items;
    private Context context;
    private int collectionId;

    static public String relativeUrl(int collectionId) {
        return "collection/" + collectionId + "/items";
    }

    public ItemsResource(Item[] i, int colelctionId) {
        this.items = i;
        this.collectionId = colelctionId;
    }

    public ItemsResource() {
        this.collectionId = 0;
        this.items = null;
        try {
            this.context = new Context();
        } catch (SQLException e) {
            log.log(Priority.ERROR, e);
        }
    }

    @Override
    protected final void doInit() throws ResourceException {
        try {
            String s = (String) getRequest().getAttributes().get("collectionId");
            this.collectionId = Integer.parseInt(s);

        } catch (NumberFormatException e) {
            ResourceException resourceException = new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
                    "Collection ID must be a number.");
            throw resourceException;
        }
    }

    @Get("html|xhtml|xml")
    public Representation toXml() {
        Collection collection = null;
        DomRepresentation representation = null;
        Document d = null;
        try {
            collection = Collection.find(context, this.collectionId);
            if (collection == null) {
                return errorNotFound(context, "Could not find the collection.");
            }

            representation = new DomRepresentation(MediaType.TEXT_HTML);
            d = representation.getDocument();
        } catch (SQLException e) {
            return errorInternal(context, e.toString());
        } catch (IOException e) {
            return errorInternal(context, e.toString());
        }

        Element html = d.createElement("html");
        d.appendChild(html);

        Element head = d.createElement("head");
        html.appendChild(head);

        Element title = d.createElement("title");
        head.appendChild(title);
        title.appendChild(d.createTextNode("Items for collection " + collection.getName()));

        Element body = d.createElement("body");
        html.appendChild(body);

        Element ulItems = d.createElement("ul");
        setId(ulItems, "items");
        body.appendChild(ulItems);

        String base = baseUrl();
        try {
            ItemIterator ii = collection.getItems();
            while (ii.hasNext()) {
                Item item = ii.next();
                Element li = d.createElement("li");
                Element a = d.createElement("a");
                String name = item.getName();
                if (name == null) {
                    // FIXME: Should we really give names for items with no
                    // FIXME: name? (And if so does "Untitled" make sense?)
                    // FIXME: Anyway, this would break with null values.
                    name = "Untitled";
                }
                a.appendChild(d.createTextNode(name));
                String href = base + ItemResource.relativeUrl(item.getID());
                setAttribute(a, "href", href);
                li.appendChild(a);
                ulItems.appendChild(li);
            }
        } catch (SQLException e) {
            String errMsg = "SQLException while trying to items of the collection. " + e.getMessage();
            return errorInternal(context, errMsg);
        }

        Element form = d.createElement("form");
        form.setAttribute("enctype", "multipart/form-data");
        form.setAttribute("method", "post");
        makeInputRow(d, form, "title", "Title");
        makeInputRow(d, form, "lang", "Language");

        Element submitButton = d.createElement("input");
        submitButton.setAttribute("type", "submit");
        submitButton.setAttribute("value", "Create a new item");
        form.appendChild(submitButton);

        body.appendChild(form);

        try {
            if (context != null) {
                context.complete();
            }
        } catch (SQLException e) {
            log.log(Priority.INFO, e);
        }

        return representation;
    }

    @Get("json")
    public String toJson() throws SQLException {
        ItemIterator items;
        Collection collection = null;
        try {
            context = new Context();
        } catch (Exception ex) {
            log.log(Priority.FATAL, ex);
            return errorInternal(context, ex.toString()).getText();
        }
        try {
            collection = Collection.find(context, collectionId);
        } catch (Exception ex) {
            log.log(Priority.FATAL, ex);
            return errorInternal(context, ex.toString()).getText();
        }
        items = collection.getItems();
        Gson gson = new Gson();

        ArrayList<StubItem> al = new ArrayList<StubItem>(10);

        while (items.hasNext()) {
            al.add(new StubItem(items.next()));
        }

        try {
            items.close();
            if (context != null) {
                context.complete();
            }
        } catch (SQLException ex) {
            log.log(Priority.ERROR, ex);
            return errorInternal(context, ex.toString()).getText();
        }

        return gson.toJson(al);
    }

    @Put
    public Representation put(Representation dummy) {
        HashSet<Method> allowed = new HashSet();
        allowed.add(Method.GET);
        allowed.add(Method.POST);
        setAllowedMethods(allowed);
        return error(null, "Items resource does not allow PUT method.", Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
    }

    @Post
    public Representation addItem(InputRepresentation rep)
            throws AuthorizeException, SQLException, IdentifierException {
        Collection collection = null;
        Context addItemContext = null;
        try {
            //Get Context and make sure the user has the rights to add items.
            addItemContext = getAuthenticatedContext();
            collection = Collection.find(addItemContext, this.collectionId);
            if (collection == null) {
                addItemContext.abort();
                return errorNotFound(addItemContext, "Could not find the collection.");
            }
        } catch (SQLException e) {
            log.log(Priority.ERROR, e);
            return errorInternal(addItemContext, "SQLException");
        } catch (NullPointerException e) {
            log.log(Priority.ERROR, e);
            return errorInternal(addItemContext, "NullPointerException");
        }
        String title = null;
        String lang = null;

        try {
            RestletFileUpload rfu = new RestletFileUpload(new DiskFileItemFactory());
            FileItemIterator iter = rfu.getItemIterator(rep);

            while (iter.hasNext()) {
                FileItemStream fileItemStream = iter.next();
                if (fileItemStream.isFormField()) {
                    String key = fileItemStream.getFieldName();
                    String value = IOUtils.toString(fileItemStream.openStream(), "UTF-8");

                    if (key.equals("title")) {
                        title = value;
                    } else if (key.equals("lang")) {
                        lang = value;
                    } else if (key.equals("in_archive")) {
                        ;
                    } else if (key.equals("withdrawn")) {
                        ;
                    } else {
                        return error(addItemContext, "Unexpected attribute: " + key,
                                Status.CLIENT_ERROR_BAD_REQUEST);
                    }
                }
            }
        } catch (FileUploadException e) {
            return errorInternal(addItemContext, e.toString());
        } catch (NullPointerException e) {
            log.log(Priority.INFO, e);
            return errorInternal(context, e.toString());
        } catch (IOException e) {
            return errorInternal(context, e.toString());
        }

        if (title == null) {
            return error(addItemContext, "There was no title given.", Status.CLIENT_ERROR_BAD_REQUEST);
        }

        Item item = null;
        try {
            WorkspaceItem wsi = WorkspaceItem.create(addItemContext, collection, false);
            item = InstallItem.installItem(addItemContext, wsi);
            item.addMetadata("dc", "title", null, lang, title);
            item.update();
        } catch (AuthorizeException ae) {
            return error(addItemContext, "Unauthorized", Status.CLIENT_ERROR_UNAUTHORIZED);
        } catch (SQLException e) {
            log.log(Priority.FATAL, e, e);
            return errorInternal(addItemContext, e.toString());
        } catch (IOException e) {
            log.log(Priority.FATAL, e, e);
            return errorInternal(addItemContext, e.toString());
        } finally {
            if (addItemContext != null) {
                addItemContext.complete();
            }
        }

        return successCreated("Created a new item.", baseUrl() + ItemResource.relativeUrl(item.getID()));
    }

    @Delete
    public Representation delete(Representation dummy) {
        HashSet<Method> allowed = new HashSet();
        allowed.add(Method.GET);
        allowed.add(Method.POST);
        setAllowedMethods(allowed);
        return error(null, "Items resource does not allow DELETE method.", Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
    }

}