/**
* Copyright (c) 2011-2012 Optimax Software Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Optimax Software, ElasticInbox, nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.elasticinbox.rest.v2;
import java.net.URI;
import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.elasticinbox.common.utils.JSONUtils;
import com.elasticinbox.core.DAOFactory;
import com.elasticinbox.core.ExistingLabelException;
import com.elasticinbox.core.IllegalLabelException;
import com.elasticinbox.core.LabelDAO;
import com.elasticinbox.core.MessageDAO;
import com.elasticinbox.core.model.Label;
import com.elasticinbox.core.model.Mailbox;
import com.elasticinbox.rest.BadRequestException;
import com.elasticinbox.rest.RESTApplicationException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* This JAX-RS resource is responsible for managing mailbox labels.
*
* @author Rustam Aliyev
*/
@Path("{domain}/{user}/mailbox/label")
public final class LabelResource
{
private final MessageDAO messageDAO;
private final LabelDAO labelDAO;
private final static Logger logger =
LoggerFactory.getLogger(LabelResource.class);
@Context UriInfo uriInfo;
public LabelResource()
{
DAOFactory dao = DAOFactory.getDAOFactory();
messageDAO = dao.getMessageDAO();
labelDAO = dao.getLabelDAO();
}
/**
* Get all messages labeled with given label
*
* @param account
* @param labelId
* @param withMetadata
* @param reverse
* @param start
* @param count
* @return
*/
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getMessages(
@PathParam("user") String user,
@PathParam("domain") String domain,
@PathParam("id") Integer labelId,
@QueryParam("metadata") @DefaultValue("false") boolean withMetadata,
@QueryParam("includebody") @DefaultValue("false") boolean includeBody,
@QueryParam("reverse") @DefaultValue("true") boolean reverse,
@QueryParam("start") UUID start,
@QueryParam("count") @DefaultValue("50") int count)
{
Mailbox mailbox = new Mailbox(user, domain);
byte[] response;
try {
if (withMetadata) {
response = JSONUtils.fromObject(messageDAO.getMessageIdsWithMetadata(mailbox,
labelId, start, count, reverse, includeBody));
} else {
response = JSONUtils.fromObject(messageDAO.getMessageIds(mailbox,
labelId, start, count, reverse));
}
} catch (Exception e) {
logger.error("REST get of message headers for {}/{} failed: {}",
new Object[] { mailbox.getId(), labelId, e.getMessage() });
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
return Response.ok(response).build();
}
/**
* Update existing label
*
* @param account
* @param labelId
* @param label
* @return
*/
@PUT
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response updateLabel(
@PathParam("user") String user,
@PathParam("domain") String domain,
@PathParam("id") Integer labelId,
@QueryParam("name") String labelName,
String requestJSONContent)
{
Mailbox mailbox = new Mailbox(user, domain);
Label label;
if (requestJSONContent.isEmpty())
{
// if request body is empty, use path param
label = new Label();
label.setName(labelName);
}
else
{
// deserialize request body to Label
try {
ObjectMapper mapper = new ObjectMapper();
label = mapper.readValue(requestJSONContent, Label.class);
} catch (Exception e) {
logger.info("Malformed JSON request: {}", e.getMessage());
throw new BadRequestException("Malformed JSON request");
}
if (label.getName() == null && labelName != null) {
label.setName(labelName);
}
}
label.setId(labelId);
try {
labelDAO.update(mailbox, label);
} catch (IllegalLabelException ile) {
throw new BadRequestException(ile.getMessage());
} catch (ExistingLabelException ele) {
throw new RESTApplicationException(Status.CONFLICT, ele.getMessage());
} catch (Exception e) {
logger.error("Updating label failed: ", e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
return Response.noContent().build();
}
/**
* Add new label
*
* @param account
* @param labelName
* @return
*/
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response addLabel(
@PathParam("user") String user,
@PathParam("domain") String domain,
@QueryParam("name") String labelName,
String requestJSONContent)
{
Mailbox mailbox = new Mailbox(user, domain);
Label label;
if (requestJSONContent.isEmpty())
{
// if request body is empty, use path param
label = new Label();
label.setName(labelName);
}
else
{
// deserialize request body to Label
try {
ObjectMapper mapper = new ObjectMapper();
label = mapper.readValue(requestJSONContent, Label.class);
} catch (Exception e) {
logger.info("Malformed JSON request: {}", e.getMessage());
throw new BadRequestException("Malformed JSON request");
}
}
if (label.getName() == null && labelName == null) {
throw new BadRequestException("Label name must be specified");
}
Integer newLabelId = null;
try {
newLabelId = labelDAO.add(mailbox, label);
} catch (IllegalLabelException ile) {
throw new BadRequestException(ile.getMessage());
} catch (ExistingLabelException ele) {
throw new RESTApplicationException(Status.CONFLICT, ele.getMessage());
} catch (Exception e) {
logger.error("Adding label failed", e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
// build response
URI messageUri = uriInfo.getAbsolutePathBuilder()
.path(Integer.toString(newLabelId)).build();
String responseJson = "{\"id\":" + newLabelId + "}";
return Response.created(messageUri).entity(responseJson).build();
}
/**
* Delete label
*
* @param account
* @param labelId
* @return
*/
@DELETE
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response deleteLabel(
@PathParam("user") String user,
@PathParam("domain") String domain,
@PathParam("id") Integer labelId)
{
Mailbox mailbox = new Mailbox(user, domain);
try {
labelDAO.delete(mailbox, labelId);
} catch (IllegalLabelException ile) {
throw new BadRequestException(ile.getMessage());
} catch (Exception e) {
logger.error("Deleting label failed", e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
return Response.noContent().build();
}
}