eu.semlibproject.annotationserver.restapis.NotebooksAPI.java Source code

Java tutorial

Introduction

Here is the source code for eu.semlibproject.annotationserver.restapis.NotebooksAPI.java

Source

/*
 * Copyright (c) 2013 Net7 SRL, <http://www.netseven.it/>
 * 
 * This file is part of Pundit: Annonation Server.
 * 
 * Pundit: Annonation Server 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.
 * 
 * Pundit: Annonation Server 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 Pundit: Annonation Server.  If not, see <http ://www.gnu.org/licenses/>.
 *
 * See LICENSE.TXT or visit <http://thepund.it> for the full text of the license.
 */

package eu.semlibproject.annotationserver.restapis;

import eu.semlibproject.annotationserver.MediaType;
import eu.semlibproject.annotationserver.SemlibConstants;
import eu.semlibproject.annotationserver.managers.RepositoryManager;
import eu.semlibproject.annotationserver.managers.UtilsManager;
import eu.semlibproject.annotationserver.models.Notebook;
import eu.semlibproject.annotationserver.models.User;
import eu.semlibproject.annotationserver.repository.RepositoryException;
import eu.semlibproject.annotationserver.security.PermissionsManager;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 * Main class that implements all REST APIs under
 * the namespace "[our-webapps]/notebooks/"
 * 
 * @author Michele Nucci
 */
@Path("/notebooks")
public class NotebooksAPI extends APIHelper {

    private Logger logger = Logger.getLogger(NotebooksAPI.class.getName());

    public enum NotebookListType {
        PUBLIC_NOTEBOOKS, ACTIVE_NOTEBOOKS, OWNED_NOTEBOOKS
    }

    /**
     * Default constructor.
     * 
     * @param req               the servlet's request passed by the Jersy framework
     * @param servletContext    the servlet context
     */
    public NotebooksAPI(@Context HttpServletRequest req, @Context ServletContext servletContext) {
        super(req, servletContext);
    }

    /**
     * Check if a specified Notebook is public
     * 
     * @param callback      the JSONP callback or null
     * @param notebookID    the ID of the Notebook to check
     * @param accepts       the Accept HTTP header
     * 
     * @return              This API return a response containing JSON data with the following format:<br/>
     *                      <code>{ "NotebookPublic": "0|1" }</code><br/><br/>
     *                      Value:
     *                      <ul>
     *                          <li>0: the specified Notebook is private</li>
     *                          <li>1: the specified Notebook is public</li>
     *                      </ul><br/>
     *                      HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" if the request or the Notebook ID is non correct</li>
     *                          <li>"404 Not Found" if the Notebook ID does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      </ul>
     */
    @GET
    @Path("public/{notebook-id}")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_JAVASCRIPT })
    public Response isNotebookPublic(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {
        return notebookPublicOrPrivate(callback, notebookID, accepts, false);
    }

    /**
     * Check if a specified Notebook is private
     * 
     * @param callback      the JSONP callback or null
     * @param notebookID    the ID of the Notebook to check
     * @param accepts       the Accept HTTP header
     * 
     * @return              This API return a response containing JSON data with the following format:<br/>
     *                      <code>{ "NotebookPrivate": "0|1" }</code><br/><br/>
     *                      Value:
     *                      <ul>
     *                          <li>0: the specified Notebook is public</li>
     *                          <li>1: the specified Notebook is private</li>
     *                      </ul><br/>
     *                      HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" if the request or the Notebook ID is non correct</li>
     *                          <li>"404 Not Found" if the Notebook ID does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      </ul>
     */
    @GET
    @Path("private/{notebook-id}")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_JAVASCRIPT })
    public Response isNotebookPrivate(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {
        return super.notebookPublicOrPrivate(callback, notebookID, accepts, true);
    }

    /**
     * Set a Notebook as public.
     * 
     * @param notebookID    the ID of the Notebook to set as Public
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" is the request or the Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebooks does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      <ul>
     */
    @PUT
    @Path("public/{notebook-id}")
    public Response setNotebookAsPublic(@PathParam("notebook-id") String notebookID) {
        return this.setNotebookVisibility(notebookID, true);
    }

    /**
     * Set a Notebook as private.
     * 
     * @param notebookID    the ID of the Notebook to set as Private
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" is the request or the Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebooks does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      <ul>
     */
    @PUT
    @Path("private/{notebook-id}")
    public Response setNotebookAsPrivate(@PathParam("notebook-id") String notebookID) {
        return this.setNotebookVisibility(notebookID, false);
    }

    /**
     * Set a Notebook as public. This API is an alias of the API: PUT /notebooks/{notebook-id}/public
     * 
     * @param notebookID    the ID of the Notebook to set as Public
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" is the request or the Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebooks does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      <ul>
     */
    @DELETE
    @Path("private/{notebook-id}")
    public Response setNotebookAsPublicByDelete(@PathParam("notebook-id") String notebookID) {
        return this.setNotebookAsPublic(notebookID);
    }

    /**
     * Set a Notebook as private. This API is an alias of the API: PUT /notebooks/{notebook-id}/private
     * 
     * @param notebookID    the ID of the Notebook to set as Private
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" is the request or the Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebooks does not exist</li>
     *                          <li>"500 Internal Server Error" for internal server error</li>
     *                      <ul>
     */
    @DELETE
    @Path("public/{notebook-id}")
    public Response setNotebookAsPrivateByDelete(@PathParam("notebook-id") String notebookID) {
        return this.setNotebookAsPrivate(notebookID);
    }

    /**
     * Return the current Notebook for the current User.
     * 
     * @param callback  the JSONP callback or null
     * @param accepts   the value of the HTTP Accept Header
     * @return          the ID of the current Notebook for the current User.
     *                  The Notebook ID is returned has JSON data:<br/>
     *                  <code>{ "NotebookID": "notebokid" }</code>     
     */
    @GET
    @Path("current")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_JAVASCRIPT })
    public Response getCurrentActiveNotebook(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        String notebookID = null;
        try {
            notebookID = RepositoryManager.getInstance().getCurrentDataRepository()
                    .getCurrentNotebookID(currentLoggedUser.getUserID());
        } catch (RepositoryException re) {
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        if (notebookID == null) {
            notebookID = this.createCurrentNotebook(currentLoggedUser);
            if (notebookID != null) {
                return this.createResponseForNewNotebook(notebookID, Status.OK);
            } else {
                return Response.status(Status.INTERNAL_SERVER_ERROR).build();
            }
        } else {

            try {

                JSONObject jsonResponse = new JSONObject();
                jsonResponse.put(SemlibConstants.JSON_NOTEBOOK_ID, notebookID);

                String fResponse = jsonResponse.toString();
                String faccepts = MediaType.APPLICATION_JSON;

                return super.createFinalResponseForNotebooksAPI(Response.Status.OK, callback, faccepts, fResponse,
                        null);

            } catch (JSONException ex) {
                return Response.status(Status.INTERNAL_SERVER_ERROR).build();
            }

        }

    }

    /**
     * Get the RDF graph composed by all the annotation's triples in the current Notebook for the current logged User.
     * 
     * @param callback      the JSONP callback function or null
     * @param accepts       the accepted format (application/rdf+xml, application/json, text/rdf+n3)     
     * @return              Return a graph composed by all annotation's triples stored in the current Notebook as a payload response.
     *                      The response data format could be: application/rdf+xml, application/json, text/rdf+n3 (see the accepts paramenter).<br/>
     *                      HTTP Status code:
     *                      <ul>
     *                          <li>"200 OK" and the RDF graph as payload response</li>
     *                          <li>"204 No Content" if there are no triples in the current notebook</li>
     *                          <li>"400 Bad Request" if the notebook id is not specified or it is incorrect</li>
     *                          <li>"403 Forbidden" if the current logged User has not the correct right to access the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified notebooks do not exist</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("current/graph")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3,
            MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getCurrentNotebookGraph(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        String notebookID = null;
        try {
            notebookID = RepositoryManager.getInstance().getCurrentDataRepository()
                    .getCurrentNotebookID(currentLoggedUser.getUserID());
        } catch (RepositoryException re) {
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        if (notebookID == null) {
            notebookID = this.createCurrentNotebook(currentLoggedUser);
        }

        if (notebookID == null) {
            return Response.status(Status.NOT_FOUND).build();
        } else {
            return this.getAllAnnotationsTriples(callback, notebookID, accepts);
        }
    }

    /**
     * Post a new annotation in the current active notebook for the current logged user.
     * 
     * @param annotationData    the JSON data extracted from the payload
     * @param notebookID        the Notebook ID in which to put the annotation
     * @param annotationContex  the context of the annotation
     * @param contentType       the contentType of the annotation data
     * 
     * @return                  The ID of the created annotation in JSON format as response payload:<br/>
     *                          <code>{ AnnotationID : { ANNOTATION-ID } }</code><br/>
     *                          HTTP Header:<br/> 
     *                          Location: URI-of-the-new-annotation<br/><br/>
     *                          HTTP Response Status Code:
     *                          <ul>
     *                              <li>"201 Created" on success</li>
     *                              <li>"400 Bad Request" if the request is not correct</li>     
     *                              <li>"500 Internal Server Error" in case of internal error</li>
     *                          </ul>
     */
    @POST
    @Path("current")
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT })
    public Response postAnnotationInCurrentActiveNotebook(String annotationData,
            @QueryParam(SemlibConstants.CONTEXT_PARAM) String annotationContext,
            @HeaderParam(SemlibConstants.HTTP_HEADER_CONTENT_TYPE) String contentType) {

        Response response = getCurrentActiveNotebook(null, contentType);
        if (response.getStatus() != 200) {
            return response;
        } else {
            String strJsonObject = (String) response.getEntity();
            try {
                JSONObject jsonData = new JSONObject(strJsonObject);
                String notebookID = jsonData.getString(SemlibConstants.JSON_NOTEBOOK_ID);
                if (notebookID == null) {
                    return Response.status(Status.BAD_REQUEST).build();
                } else {
                    return createNewAnnotation(notebookID, annotationData, contentType, annotationContext);
                }

            } catch (JSONException ex) {
                logger.log(Level.SEVERE, null, ex);
                return Response.status(Status.INTERNAL_SERVER_ERROR).build();
            }
        }

    }

    /**    
     * Create a new notebook with a specific name.
     * 
     * @param notebookName The name of the new Notebooks in JSON format or null. JSON format:<br/>
     *                     <code>{ "NotebookName": "{Notebook-Name}" }
     * @return             The ID od the new created Notebook as payload response in JSON format:<br/>
     *                     <code>{ NotebookID : { NOTEBOOK-ID } }<code><br/>
     *                     HTTP Header:<br/>
     *                     Location: URI-of-the-new-notebook<br/><br/>
     *                     HTTP Response Status Code:
     *                     <ul>
     *                      <li>"201 Created" on success</li>
     *                      <li>"400 Bad Request" if the request is not correct</li>
     *                      <li>"500 Internal Server Error" in case of internal error</li>
     *                     </ul>
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT })
    public Response createNewNotebook(String notebookNameAsJSON) {

        User currentUser = super.getCurrentLoggedUserOrAnonUser();

        Notebook notebook = null;
        String notebookName = null;

        if (notebookNameAsJSON != null && notebookNameAsJSON.length() > 0) {
            try {
                JSONObject jsonObj = new JSONObject(notebookNameAsJSON);
                notebookName = jsonObj.getString(SemlibConstants.JSON_NOTEBOOK_NAME);
            } catch (JSONException ex) {
                notebookName = null;
            }
        }

        try {
            notebook = Notebook.createNewNotebook(currentUser, notebookName);
        } catch (Exception ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        Status responseCode = RepositoryManager.getInstance().writeNotebook(currentUser, notebook);
        if (responseCode != Status.OK) {
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        return this.createResponseForNewNotebook(notebook.getID(), Status.CREATED);
    }

    /**
     * Create a new Annotation in the specified Notebook writing at the same time the
     * Annotation's graph and the Annotation's items (if they exists). 
     * This is the main API that must be used to create new Annotations with data model version 2:
     * 
     * <pre>
     * {
     *      "graph": {
     *       // Annotation's Graph
     *       JSON/RDF
     *  },
     *      "items": {
     *       // Annotation's items
     *       JSON/RDF
     *      }
     *  }
     * </pre>
     * 
     * @param annotationData    the JSON data extracted from the payload
     * @param notebookID        the Notebook ID in which to put the annotation
     * @param annotationContext additional annotation metadata in JSON format
     * @param contentType       the contentType of the annotation data
     * 
     * @return                  The ID of the created annotation in JSON format as response payload:<br/>
     *                          <code>{ AnnotationID : { ANNOTATION-ID } }</code><br/>
     *                          HTTP Header:<br/> 
     *                          Location: URI-of-the-new-annotation<br/><br/>
     *                          HTTP Response Status Code:
     *                          <ul>
     *                              <li>"201 Created" on success</li>
     *                              <li>"400 Bad Request" if the request is not correct</li>
     *                              <li>"403 Forbidden" if the current logged User has not the correct rights to access to the specified Notebooks</li>
     *                              <li>"500 Internal Server Error" in case of internal error</li>
     *                          </ul>            
     */
    @POST
    @Path("{notebook-id}")
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT })
    public Response createNewAnnotationWithGraphAndItems(String annotationData,
            @PathParam("notebook-id") String notebookID,
            @QueryParam(SemlibConstants.CONTEXT_PARAM) String annotationContext,
            @HeaderParam(SemlibConstants.HTTP_HEADER_CONTENT_TYPE) String contentType) {
        return super.createNewAnnotation(notebookID, annotationData, contentType, annotationContext);
    }

    /**
     * Create a new Annotation in the specified Notebook writing only the
     * Annotation's graph. 
     * This is used to write Annotation with data model version 1 (old).
     *      
     * @param annotationData    the JSON data extracted from the payload
     * @param notebookID        the Notebook ID in which to put the annotation
     * @param annotationContext additional annotation metadata in JSON format
     * @param contentType       the contentType of the annotation data
     * 
     * @return                  The ID of the created annotation in JSON format as response payload:<br/>
     *                          <code>{ AnnotationID : { ANNOTATION-ID } }</code><br/>
     *                          HTTP Header:<br/> 
     *                          Location: URI-of-the-new-annotation<br/><br/>
     *                          HTTP Response Status Code:
     *                          <ul>
     *                              <li>"201 Created" on success</li>
     *                              <li>"400 Bad Request" if the request is not correct</li>
     *                              <li>"403 Forbidden" if the current logged User has not the correct rights to access to the specified Notebooks</li>
     *                              <li>"500 Internal Server Error" in case of internal error</li>
     *                          </ul>            
     */
    @POST
    @Path("graph/{notebook-id}")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3 })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT })
    public Response createNewAnnotationWithGraph(String annotationData, @PathParam("notebook-id") String notebookID,
            @QueryParam(SemlibConstants.CONTEXT_PARAM) String annotationContext,
            @HeaderParam(SemlibConstants.HTTP_HEADER_CONTENT_TYPE) String contentType) {
        return super.createNewAnnotation(notebookID, annotationData, contentType, annotationContext);
    }

    /**
     * Get the list of all annotations contained within a Notebook with related metadata.
     * 
     * @param callback      the JSONP callback function or null
     * @param notebookID    the Notebook ID
     * @param accepts       the accepted format (application/rdf+xml or application/json)
     * @param limit         max number of annotation to retrieve (-1 for no limits)
     * @param offset        offset for annotations retrieval (-1 for no offset)
     * @param orderby       property for order by
     * @param orderingMode  (optional) 1/0 (desc/asc) for orderby
     * @return              The list of all annotations contained within a Notebook and related metadata as response payload.
     *                      The returned data format could be: application/rdf+xml or application/json (see the accepts parameter)<br/><br/>
     *                      HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of succe</li>
     *                          <li>"204 No Content" if there are no triples in the specified notebook</li>
     *                          <li>"400 Bad Request" if the notebook id is not specified or it is incorrect</li>
     *                          <li>"403 Forbidden" if the current logged User has not the correct right to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified notebook does not exists</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("{notebook-id}/annotations/metadata")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3,
            MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getAnnotationListAndMetadata(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts,
            @QueryParam(SemlibConstants.LIMIT_PARAM) String limit,
            @QueryParam(SemlibConstants.OFFSET_PARAM) String offset,
            @QueryParam(SemlibConstants.ORDERBY_PARAM) String orderby,
            @QueryParam(SemlibConstants.DESC_PARAM) String orderingMode) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        return super.annotationsListAndMetadata(notebookID, callback, accepts, orderby, orderingMode, limit,
                offset);
    }

    /**
     * Get all data in JSON format about a specified Notebook: metadata, annotations list and related data.
     * The data output format is:<br/>
     * <pre>
     * {
     *      "metadata": {
     *          // JSON/RDF
     *          ... ... ...
     *      },
     *      "annotations": [
     *          {
     *              "metadata: {
     *                  // JSON/RDF
     *                  ... ... ...
     *              },
     *              "graph": {
     *                  // JSON/RDF
     *                  ... ... ...
     *              },
     *              "items": {
     *                  // JSON/RDF
     *                  ... ... ...
     *              }
     *          },
     *          {
     *              ... ... ...
     *          }
     *      ]
     * }
     * </pre>
     * 
     * If the specified Notebook does not contain annotations, this API return:<br/>
     * <pre>
     * {
     *      "metadata": {
     *          // JSON/RDF
     *          ... ... ...
     *      },
     *      "annotations": []
     * }      
     * 
     * @param callback      the JSONP callback function or null
     * @param notebookID    the Notebook ID
     * @param accepts       the accepted format
     * @param limit         max number of annotation to retrieve (-1 for no limits)
     * @param offset        offset for annotations retrieval (-1 for no offset)
     * 
     * @return              all data about a specified Notebook
     */
    @GET
    @Path("{notebook-id}")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getDumpOfNotebook(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts,
            @QueryParam(SemlibConstants.LIMIT_PARAM) String limit,
            @QueryParam(SemlibConstants.OFFSET_PARAM) String offset,
            @QueryParam(SemlibConstants.DESC_PARAM) String orderingMode) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        return super.dumpOfNotebook(notebookID, callback, accepts, limit, offset, orderingMode);
    }

    /**
     * Return all metadata about a specified Notbooks
     * 
     * @param callback      the JSONP callback function or null
     * @param notebookID    the Notebook ID
     * @param accepts       the accepted format (application/rdf+xml or application/json)
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" and the RDF graph as payload response</li>
     *                          <li>"204 No Content" if there are no triples in the specified notebook</li>
     *                          <li>"400 Bad Request" if the notebook id is not specified or it is incorrect</li>
     *                          <li>"404 Not Found" if the specified notebook does not exists</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("{notebook-id}/metadata")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3,
            MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getNotebookMetadata(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        return super.notebookMetadata(notebookID, callback, accepts);
    }

    /**
     * Get the RDF graph composed by all the triples of the annotations in the specified notebook.
     * 
     * @param callback      the JSONP callback function or null
     * @param notebookID    the notebook ID
     * @param accepts       the accepted format (application/rdf+xml or application/json)
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" and the RDF graph as payload response</li>
     *                          <li>"204 No Content" if there are no triples in the specified notebook</li>
     *                          <li>"400 Bad Request" if the notebook id is not specified or it is incorrect</li>
     *                          <li>"404 Not Found" if the specified notebook does not exists</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("{notebook-id}/graph")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3,
            MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getAllAnnotationsTriples(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, true);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        return super.annotationsTriples(notebookID, callback, accepts);
    }

    /**
     * Search for all annotation metadata according to specific parameters within a specified Notebook.
     * 
     * @param callback      callback function for JSONP
     * @param queryParams   parameters (JSON format), encoded
     * @param accept        the accepted format (n3, application/rdf+xml or application/json)
     * @param limit         max number of annotation to retrieve
     * @param offset        offset for annotations retrieval
     * @param orderby       property for order by
     * @param orderingMode  1/0 (desc/asc) for orderby
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" annotation metadata</li>
     *                          <li>"204 No Content" if there are no annotation metadata for the specified parameters</li>
     *                          <li>"400 Bad Request" if the specified parameters or the request are incorrect</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("{notebook-id}/search")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_RDFXML, MediaType.TEXT_RDFN3,
            MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response searchAnnotationMetadataInNotebooks(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @QueryParam(SemlibConstants.QUERY_PARAM) String queryParams,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts,
            @QueryParam(SemlibConstants.LIMIT_PARAM) String limit,
            @QueryParam(SemlibConstants.OFFSET_PARAM) String offset,
            @QueryParam(SemlibConstants.ORDERBY_PARAM) String orderby,
            @QueryParam(SemlibConstants.DESC_PARAM) String orderingMode) {

        if (queryParams == null || queryParams.length() == 0) {
            return Response.status(Status.BAD_REQUEST).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        int qLimit = UtilsManager.getInstance().parseLimitOrOffset(limit);
        int qOffset = UtilsManager.getInstance().parseLimitOrOffset(offset);
        boolean desc = false;

        if (orderingMode != null && orderingMode.equals("1")) {
            desc = true;
        }

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        UtilsManager utilsManager = UtilsManager.getInstance();
        String cAccepts = utilsManager.getCorrectAcceptValue(callback, accepts);
        String tripleFormat = utilsManager.getCorrectTripleFormat(callback, accepts, cAccepts);

        List<String> notebookIDsList = new ArrayList<String>();
        notebookIDsList.add(notebookID);

        String annotationMetadata = null;
        try {
            annotationMetadata = RepositoryManager.getInstance().getCurrentRDFRepository()
                    .searchMetadataWithParameters(queryParams, qLimit, qOffset, orderby, desc, tripleFormat,
                            notebookIDsList);
        } catch (RepositoryException ex) {
            logger.log(Level.SEVERE, ex.getMessage().toString(), ex);
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        if (annotationMetadata != null) {
            if (StringUtils.isBlank(annotationMetadata)) {
                return Response.status(Status.NO_CONTENT).build();
            } else {
                return super.createFinalResponseForNotebooksAPI(Response.Status.OK, callback, cAccepts,
                        annotationMetadata, null);
            }
        } else {
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Update metadata of an existing notebook. At the only supported metadata is NotebookName.
     * 
     * @param notebookMetadata  the notebook metadata (JSON). At the moment the only supported metadata is NotebookName
     * @param notebookID        the ID of the notebook to update
     * @return                  <ul>
     *                              <li>"200 OK" and the RDF graph as payload response</li>
     *                              <li>"204 No Content" if there are no triples in the current notebook</li>
     *                              <li>"400 Bad Request" if the notebook id is not specified or it is incorrect</li>
     *                              <li>"403 Forbidden" if the current logged user has not the correct right to access the specified Notebook</li>
     *                              <li>"404 Not Found" if the specified notebooks do not exist</li>
     *                              <li>"500 Internal Server Error" in case of error</li>
     *                          </ul>
     */
    @PUT
    @Path("{notebook-id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateNotebookName(String notebookMetadata, @PathParam("notebook-id") String notebookID) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canWriteNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        String notebookName;
        try {
            JSONObject jsonObject = new JSONObject(notebookMetadata);
            notebookName = jsonObject.getString(SemlibConstants.JSON_NOTEBOOK_NAME);
            if (StringUtils.isBlank(notebookName)) {
                return Response.status(Status.BAD_REQUEST).build();
            }
        } catch (JSONException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(Status.BAD_REQUEST).build();
        }

        Notebook notebook = Notebook.getEmptyNotebookObject();
        notebook.setID(notebookID);
        notebook.setName(notebookName);
        notebook.setModifiedDate(UtilsManager.getInstance().getDate(true));

        Status response = RepositoryManager.getInstance().getCurrentRDFRepository()
                .updateNotebookMetadata(notebook);

        if (response == Status.INTERNAL_SERVER_ERROR || response == Status.NOT_FOUND) {
            return Response.status(response).build();
        } else {
            return Response.ok().build();
        }
    }

    /**
     * Get all Notebooks owned by the current logged User
     * 
     * @param callback callback function for JSONP
     * @return         a list of all Notebooks owned by the current logged User in JSON format<br/>
     *                 HTTP Response Status Code:
     *                 <ul>
     *                  <li>"200 OK" in case of success</li>
     *                  <li>"204 No Content" if there are no active Notebooks for the current logged user</li>
     *                  <li>"400 Bad Request" if the request is not correct</li>
     *                  <li>"403 Forbidden" if no users is logged or if the current logged user has not the correct rights to access to this API</li>
     *                  <li>"500 Internal Server Error" for internal server error</li>
     *                 </ul>
     */
    @GET
    @Path("/owned")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_JAVASCRIPT })
    public Response getAllNotebookOwnedByUser(@QueryParam(SemlibConstants.JSONP_PARAM) String callback) {
        return super.getNotebooksList(NotebookListType.OWNED_NOTEBOOKS, callback);
    }

    /**
     * Get all active Notebooks for the current logged User
     * 
     * @param callback callback function for JSONP
     * @return         a list of all active Notebooks in JSON format<br/>
     *                 HTTP Response Status Code:
     *                 <ul>
     *                  <li>"200 OK" in case of success</li>
     *                  <li>"204 No Content" if there are no active Notebooks for the current logged user</li>
     *                  <li>"400 Bad Request" if the request is not correct</li>
     *                  <li>"403 Forbidden" if no users is logged or if the current logged user has not the correct rights to access to this API</li>
     *                  <li>"500 Internal Server Error" for internal server error</li>
     *                 </ul>
     */
    @GET
    @Path("/active")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_JAVASCRIPT })
    public Response getAllActiveNotebooks(@QueryParam(SemlibConstants.JSONP_PARAM) String callback) {
        return super.getNotebooksList(NotebookListType.ACTIVE_NOTEBOOKS, callback);
    }

    /**
     * Check if a specified Notebook is active or not.
     * 
     * @param callback      callback function for JSONP
     * @param notebookID    the ID of the Notebook to check
     * @param accepts       the HTTP accept header
     * @return              Return JSON data as payload response with the following format:<br>
     *                      <code>{ "NotebookActive": "0|1" }</code><br/><br/>
     *                      HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of succe</li>
     *                          <li>"400 Bad Request" if the request or the ID of the Notebook are not valid</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </ul>
     */
    @GET
    @Path("/active/{notebook-id}")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_JAVASCRIPT, MediaType.TEXT_HTML })
    public Response getActiveNotebookStatus(@QueryParam(SemlibConstants.JSONP_PARAM) String callback,
            @PathParam("notebook-id") String notebookID,
            @HeaderParam(SemlibConstants.HTTP_HEADER_ACCEPT) String accepts) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }

        try {
            boolean notebookActive = RepositoryManager.getInstance().getCurrentDataRepository()
                    .isNotebookActive(currentLoggedUser.getUserID(), notebookID);

            JSONObject jsonResponse = new JSONObject();
            jsonResponse.put(SemlibConstants.JSON_NOTEBOOK_ACTIVE, (notebookActive) ? "1" : "0");

            String fResponse = jsonResponse.toString();
            String faccepts = MediaType.APPLICATION_JSON;

            return super.createFinalResponseForNotebooksAPI(Response.Status.OK, callback, faccepts, fResponse,
                    null);

        } catch (Exception re) {
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * Activate a specified Notebook.
     * 
     * @param notebookID    the ID of the Notebook to activate
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" if the request or the specified Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logget user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebook does not exist</li>
     *                          <li>"500 Internal Server Error" in case of internal error</li>
     *                      </ul>
     */
    @PUT
    @Path("/active/{notebook-id}")
    public Response activateNotebook(@PathParam("notebook-id") String notebookID) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }

            Status notebookActivation = RepositoryManager.getInstance().getCurrentDataRepository()
                    .setNotebookActive(currentLoggedUser.getUserID(), notebookID, true);

            return Response.status(notebookActivation).build();

        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }
    }

    /**
     * Set a specified Notebook as "current". If antoher Notebooks is already set as current 
     * this API set it as "not current".
     * 
     * 
     * @param notebookID    The ID of the Notebook to set as current
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" if there quest and/or the Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logged user has not the correct rights to access the specified Notebook</li>
     *                          <li>"404 Not Found if the specified Notebook does not exist</li>
     *                          <li>"500 Internal Server Error" in case of error</li>
     *                      </u>
     */
    @PUT
    @Path("/current/{notebook-id}")
    public Response setNotebookAsCurrent(@PathParam("notebook-id") String notebookID) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canWriteNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }

            Status operationStatus = RepositoryManager.getInstance().getCurrentDataRepository()
                    .setNotebookAsCurrent(currentLoggedUser.getUserID(), notebookID);

            return Response.status(operationStatus).build();

        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }
    }

    /**
     * Deactivate a specified Notebook. By default a Notebook set as current can not be deactivated. If a user try to 
     * deactivate a Notebook that is set as current, this API return a 403 HTTP error.
     * 
     * @param notebookID    the ID of the Notebook to deactivate
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"200 OK" in case of success</li>
     *                          <li>"400 Bad Request" if the request or the specified Notebook ID is not correct</li>
     *                          <li>"403 Forbidden" if the current logget user has not the correct rights to access to the specified Notebook</li>
     *                          <li>"404 Not Found" if the specified Notebook does not exist</li>
     *                          <li>"500 Internal Server Error" in case of internal error</li>
     *                      </ul>
     */
    @DELETE
    @Path("/active/{notebook-id}")
    public Response deactiveteNotebook(@PathParam("notebook-id") String notebookID) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();

        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canReadNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            }

            Status notebookActivation = RepositoryManager.getInstance().getCurrentDataRepository()
                    .setNotebookActive(currentLoggedUser.getUserID(), notebookID, false);

            return Response.status(notebookActivation).build();

        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(ex.getStatusCode()).build();
        }
    }

    /**
     * Delete a notebook and all annotation contained within it.
     * 
     * @param notebookID    the ID of the notebook to delete
     * @return              HTTP Response Status Code:
     *                      <ul>
     *                          <li>"204 No Content" if the notebook has correctly deleted</li>
     *                          <li>"403 Forbidde" if the user is not the owner of the specified Notebook or if the notebook is set as current</li>
     *                          <li>"404 Not Found" it the specified notebook does not exists</li>
     *                          <li>"400 Bad Request" if the notebook is not valid or is not specified</li>
     *                          <li>"500 Internal Server Error" in case of general problems</li>
     *                      </ul>
     */
    @DELETE
    @Path("{notebook-id}")
    public Response deleteNotebook(@PathParam("notebook-id") String notebookID) {

        Status notebookStatus = super.checkNotebookID(notebookID, false);
        if (notebookStatus != Status.OK) {
            return Response.status(notebookStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();
        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            boolean rightsOk = permManager.canWriteNotebook(currentLoggedUser.getUserID(), notebookID);
            if (!rightsOk) {
                return Response.status(Status.FORBIDDEN).build();
            } else {
                // Check if the Notebook is a current Notebook. If so, we can't delete it
                boolean isCurrentNotebook = RepositoryManager.getInstance().getCurrentDataRepository()
                        .isCurrentNotebook(notebookID);
                if (isCurrentNotebook) {
                    return Response.status(Status.FORBIDDEN).build();
                }
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException ex) {
            logger.log(Level.SEVERE, null, ex);
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        } catch (RepositoryException re) {
            logger.log(Level.SEVERE, null, re);
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }

        Notebook notebookToDelete = Notebook.getEmptyNotebookObject();
        notebookToDelete.setID(notebookID);

        Status notebookDeletion = RepositoryManager.getInstance().deleteNotebook(notebookToDelete);
        if (notebookDeletion == Status.OK) {
            return Response.status(Status.NO_CONTENT).build();
        } else {
            return Response.status(notebookDeletion).build();
        }

    }

    /**
     * Create a new notebook and set it as current for the current logged user.
     * 
     * @param currentLoggedUser the current logged User
     * @return                  the new Notebook ID or <code>null</code> if some problem has occurred during the Notebook creation
     */
    private String createCurrentNotebook(User currentLoggedUser) {

        Response response;
        if (currentLoggedUser.isAnonymous()) {
            String notebookData = "{ \"" + SemlibConstants.JSON_NOTEBOOK_NAME + "\": \""
                    + SemlibConstants.NOTEBOOK_PUBLIC + "\" }";
            response = createNewNotebook(notebookData);
        } else {
            response = createNewNotebook(null);
        }

        if (response.getStatus() == 201) {

            String entity = response.getEntity().toString();

            try {
                JSONObject nData = new JSONObject(entity);
                String notebookId = nData.getString(SemlibConstants.JSON_NOTEBOOK_ID);

                Status setCurrentResponse = RepositoryManager.getInstance().getCurrentDataRepository()
                        .setNotebookAsCurrent(currentLoggedUser.getUserID(), notebookId);
                if (setCurrentResponse == Status.OK) {
                    return notebookId;
                } else {
                    return null;
                }

            } catch (Exception e) {
                return null;
            }

        } else {
            return null;
        }
    }

    /**
     * Create the final HTTP Response for the creation of a new Notebook.
     * 
     * @param notebookId    the ID of the newly created Notebook
     * @param status        the status code to return
     * @return              a Response (@see Response)
     */
    private Response createResponseForNewNotebook(String notebookId, Status status) {
        try {
            // Create JSON response
            JSONObject jsonResponse = new JSONObject();
            jsonResponse.put(SemlibConstants.JSON_NOTEBOOK_ID, notebookId);

            String fResponse = jsonResponse.toString();
            String fContentType = MediaType.APPLICATION_JSON;

            return super.createFinalResponseForNotebooksAPI(status, null, fContentType, fResponse,
                    Notebook.getURIFromID(notebookId));

        } catch (JSONException ex) {
            logger.log(Level.SEVERE, ex.getMessage().toString(), ex);
            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
        }
    }

    private Response setNotebookVisibility(String notebookID, boolean notebookPublic) {

        Status notebookIDStatus = super.checkNotebookID(notebookID, false);
        if (notebookIDStatus != Status.OK) {
            return Response.status(notebookIDStatus).build();
        }

        User currentLoggedUser = super.getCurrentLoggedUserOrAnonUser();
        try {
            PermissionsManager permManager = eu.semlibproject.annotationserver.managers.SecurityManager
                    .getInstance().getPermissionManager();

            if (!permManager.canWriteNotebook(currentLoggedUser.getUserID(), notebookID)) {
                return Response.status(Status.FORBIDDEN).build();
            }
        } catch (eu.semlibproject.annotationserver.security.SecurityException se) {
            logger.log(Level.SEVERE, null, se);
            return Response.status(se.getStatusCode()).build();
        }

        Status status = RepositoryManager.getInstance().getCurrentDataRepository().setNotebookVisibility(notebookID,
                currentLoggedUser.getUserID(), notebookPublic);

        return Response.status(status).build();
    }
}