/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.fo.restapi;
import static org.olat.restapi.security.RestSecurityHelper.getIdentity;
import static org.olat.restapi.security.RestSecurityHelper.isAdmin;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
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.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.BaseSecurityManager;
import org.olat.core.id.Identity;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.StringHelper;
import org.olat.core.util.WebappHelper;
import org.olat.core.util.vfs.LocalFileImpl;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSManager;
import org.olat.core.util.vfs.filters.SystemItemFilter;
import org.olat.core.util.vfs.restapi.VFSStreamingOutput;
import org.olat.modules.fo.Forum;
import org.olat.modules.fo.Message;
import org.olat.modules.fo.manager.ForumManager;
import org.olat.restapi.support.MediaTypeVariants;
import org.olat.restapi.support.MultipartReader;
import org.olat.restapi.support.vo.File64VO;
import org.olat.restapi.support.vo.FileVO;
/**
*
* Description:<br>
* Web service to manage a forum.
*
* <P>
* Initial Date: 20 apr. 2010 <br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class ForumWebService {
private static final OLog log = Tracing.createLoggerFor(ForumWebService.class);
public static CacheControl cc = new CacheControl();
static {
cc.setMaxAge(-1);
}
private final Forum forum;
private final ForumManager fom = ForumManager.getInstance();
public ForumWebService(Forum forum) {
this.forum = forum;
}
/**
* Retrieves the forum.
* @response.representation.200.qname {http://www.example.com}forumVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_FORUMVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The forum not found
* @return The forum
*/
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getForum() {
if(forum == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
ForumVO forumVo = new ForumVO(forum);
return Response.ok(forumVo).build();
}
/**
* Retrieves the threads in the forum
* @response.representation.200.qname {http://www.example.com}messageVOes
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVOes}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author, forum or message not found
* @param start
* @param limit
* @param orderBy (value name,creationDate)
* @param asc (value true/false)
* @param httpRequest The HTTP request
* @param uriInfo The URI informations
* @param request The REST request
* @return The list of threads
*/
@GET
@Path("threads")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getThreads(@QueryParam("start") @DefaultValue("0") Integer start,
@QueryParam("limit") @DefaultValue("25") Integer limit, @QueryParam("orderBy") @DefaultValue("creationDate") String orderBy,
@QueryParam("asc") @DefaultValue("true") Boolean asc, @Context HttpServletRequest httpRequest, @Context UriInfo uriInfo,
@Context Request request) {
if(forum == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(MediaTypeVariants.isPaged(httpRequest, request)) {
int totalCount = fom.countThreadsByForumID(forum.getKey());
Message.OrderBy order = toEnum(orderBy);
List<Message> threads = fom.getThreadsByForumID(forum.getKey(), start, limit, order, asc);
MessageVO[] vos = toArrayOfVO(threads, uriInfo);
MessageVOes voes = new MessageVOes();
voes.setMessages(vos);
voes.setTotalCount(totalCount);
return Response.ok(voes).build();
} else {
List<Message> threads = fom.getThreadsByForumID(forum.getKey(), 0, -1, null, true);
MessageVO[] voes = toArrayOfVO(threads, uriInfo);
return Response.ok(voes).build();
}
}
/**
* Creates a new thread in the forum of the course node
* @response.representation.mediaType application/x-www-form-urlencoded
* @response.representation.200.qname {http://www.example.com}messageVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author, forum or message not found
* @param forumKey The id of the forum
* @param title The title for the first post in the thread
* @param body The body for the first post in the thread
* @param authorKey The author key (optional)
* @param httpRequest The HTTP request
* @return The new thread
*/
@POST
@Path("threads")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response newThreadToForumPost(@FormParam("title") String title,
@FormParam("body") String body, @FormParam("authorKey") Long authorKey,
@Context HttpServletRequest httpRequest) {
return newThreadToForum(title, body, authorKey, httpRequest);
}
/**
* Creates a new thread in the forum of the course node
* @response.representation.200.qname {http://www.example.com}messageVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author, forum or message not found
* @param title The title for the first post in the thread
* @param body The body for the first post in the thread
* @param authorKey The author user key (optional)
* @param httpRequest The HTTP request
* @return The new thread
*/
@PUT
@Path("threads")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response newThreadToForum(@QueryParam("title") String title,
@QueryParam("body") String body, @QueryParam("authorKey") Long authorKey,
@Context HttpServletRequest httpRequest) {
Identity author = getMessageAuthor(authorKey, httpRequest);
// creating the thread (a message without a parent message)
Message newThread = fom.createMessage(forum, author, false);
newThread.setTitle(title);
newThread.setBody(body);
// open a new thread
fom.addTopMessage(newThread);
MessageVO vo = new MessageVO(newThread);
return Response.ok(vo).build();
}
/**
* Retrieves the messages in the thread
* @response.representation.200.qname {http://www.example.com}messageVOes
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVOes}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author, forum or message not found
* @param threadKey The key of the thread
* @param start
* @param limit
* @param orderBy (value name, creationDate)
* @param asc (value true/false)
* @param httpRequest The HTTP request
* @param uriInfo The URI informations
* @param request The REST request
* @return The messages of the thread
*/
@GET
@Path("posts/{threadKey}")
public Response getMessages( @PathParam("threadKey") Long threadKey, @QueryParam("start") @DefaultValue("0") Integer start,
@QueryParam("limit") @DefaultValue("25") Integer limit, @QueryParam("orderBy") @DefaultValue("creationDate") String orderBy,
@QueryParam("asc") @DefaultValue("true") Boolean asc, @Context HttpServletRequest httpRequest, @Context UriInfo uriInfo,
@Context Request request) {
if(forum == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(MediaTypeVariants.isPaged(httpRequest, request)) {
int totalCount = fom.countThread(threadKey);
Message.OrderBy order = toEnum(orderBy);
List<Message> threads = fom.getThread(threadKey, start, limit, order, asc);
MessageVO[] vos = toArrayOfVO(threads, uriInfo);
MessageVOes voes = new MessageVOes();
voes.setMessages(vos);
voes.setTotalCount(totalCount);
return Response.ok(voes).build();
} else {
List<Message> messages = fom.getThread(threadKey);
MessageVO[] messageArr = toArrayOfVO(messages, uriInfo);
return Response.ok(messageArr).build();
}
}
/**
* Creates a new reply in the forum of the course node
* @response.representation.mediaType application/x-www-form-urlencoded
* @response.representation.200.qname {http://www.example.com}messageVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author or message not found
* @param messageKey The id of the reply message
* @param title The title for the first post in the thread
* @param body The body for the first post in the thread
* @param authorKey The author key
* @param httpRequest The HTTP request
* @param uriInfo The URI informations
* @return The new message
*/
@POST
@Path("posts/{messageKey}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPostPost(@PathParam("messageKey") Long messageKey, @FormParam("title") String title,
@FormParam("body") String body, @FormParam("authorKey") Long authorKey,
@Context HttpServletRequest httpRequest, @Context UriInfo uriInfo) {
return replyToPost(messageKey, new ReplyVO(title, body), authorKey, httpRequest, uriInfo);
}
/**
* Creates a new reply in the forum of the course node
* @response.representation.200.qname {http://www.example.com}messageVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author or message not found
* @param messageKey The id of the reply message
* @param title The title for the first post in the thread
* @param body The body for the first post in the thread
* @param authorKey The author user key (optional)
* @param httpRequest The HTTP request
* @param uriInfo The URI informations
* @return The new Message
*/
@PUT
@Path("posts/{messageKey}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPost(@PathParam("messageKey") Long messageKey, @QueryParam("title") String title,
@QueryParam("body") String body, @QueryParam("authorKey") Long authorKey,
@Context HttpServletRequest httpRequest, @Context UriInfo uriInfo) {
return replyToPost(messageKey, new ReplyVO(title, body), authorKey, httpRequest, uriInfo);
}
/**
* Creates a new reply in the forum of the course node
* @response.representation.200.qname {http://www.example.com}messageVO
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The root message of the thread
* @response.representation.200.example {@link org.olat.modules.fo.restapi.Examples#SAMPLE_MESSAGEVO}
* @response.representation.401.doc The roles of the authenticated user are not sufficient
* @response.representation.404.doc The author or message not found
* @param messageKey The id of the reply message
* @param reply The reply object
* @param httpRequest The HTTP request
* @return The new message
*/
@PUT
@Path("posts/{messageKey}")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPost(@PathParam("messageKey") Long messageKey, ReplyVO reply,
@Context HttpServletRequest httpRequest, @Context UriInfo uriInfo) {
return replyToPost(messageKey, reply, null, httpRequest, uriInfo);
}
private Response replyToPost(Long messageKey, ReplyVO reply, Long authorKey, HttpServletRequest httpRequest, UriInfo uriInfo) {
Identity identity = getIdentity(httpRequest);
if(identity == null) {
return Response.serverError().status(Status.UNAUTHORIZED).build();
}
Identity author;
if(isAdmin(httpRequest)) {
if(authorKey == null) {
author = identity;
} else {
author = getMessageAuthor(authorKey, httpRequest);
}
} else {
if(authorKey == null) {
author = identity;
} else if(authorKey.equals(identity.getKey())) {
author = identity;
} else {
return Response.serverError().status(Status.UNAUTHORIZED).build();
}
}
// load message
Message mess = fom.loadMessage(messageKey);
if(mess == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(!forum.equalsByPersistableKey(mess.getForum())) {
return Response.serverError().status(Status.CONFLICT).build();
}
// creating the thread (a message without a parent message)
Message newMessage = fom.createMessage(forum, author, false);
newMessage.setTitle(reply.getTitle());
newMessage.setBody(reply.getBody());
fom.replyToMessage(newMessage, mess);
if(reply.getAttachments() != null) {
for(File64VO attachment:reply.getAttachments()) {
byte[] fileAsBytes = Base64.decodeBase64(attachment.getFile());
InputStream in = new ByteArrayInputStream(fileAsBytes);
attachToPost(newMessage, attachment.getFilename(), in, httpRequest);
}
}
MessageVO vo = new MessageVO(newMessage);
vo.setAttachments(getAttachments(newMessage, uriInfo));
return Response.ok(vo).build();
}
/**
* Retrieves the attachments of the message
* @response.representation.200.mediaType application/xml, application/json
* @response.representation.200.doc The links to the attachments
* @response.representation.404.doc The message not found
* @param messageKey The key of the message
* @param uriInfo The URI information
* @return The attachments
*/
@GET
@Path("posts/{messageKey}/attachments")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getAttachments(@PathParam("messageKey") Long messageKey, @Context UriInfo uriInfo) {
//load message
Message mess = fom.loadMessage(messageKey);
if(mess == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(!forum.equalsByPersistableKey(mess.getForum())) {
return Response.serverError().status(Status.CONFLICT).build();
}
FileVO[] attachments = getAttachments(mess, uriInfo);
return Response.ok(attachments).build();
}
/**
* Retrieves the attachment of the message
* @response.representation.200.mediaType application/octet-stream
* @response.representation.200.doc The portrait as image
* @response.representation.404.doc The identity or the portrait not found
* @param messageKey The identity key of the user being searched
* @param filename The name of the attachment
* @param request The REST request
* @return The attachment
*/
@GET
@Path("posts/{messageKey}/attachments/{filename}")
@Produces({"*/*", MediaType.APPLICATION_OCTET_STREAM})
public Response getAttachment(@PathParam("messageKey") Long messageKey, @PathParam("filename") String filename,
@Context Request request) {
//load message
Message mess = fom.loadMessage(messageKey);
if(mess == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(!forum.equalsByPersistableKey(mess.getForum())) {
return Response.serverError().status(Status.CONFLICT).build();
}
VFSContainer container = fom.getMessageContainer(mess.getForum().getKey(), mess.getKey());
VFSItem item = container.resolve(filename);
if(item instanceof LocalFileImpl) {
//local file -> the length is given to the client which is good
Date lastModified = new Date(item.getLastModified());
Response.ResponseBuilder response = request.evaluatePreconditions(lastModified);
if(response == null) {
File attachment = ((LocalFileImpl)item).getBasefile();
String mimeType = WebappHelper.getMimeType(attachment.getName());
if (mimeType == null) mimeType = "application/octet-stream";
response = Response.ok(attachment).lastModified(lastModified).type(mimeType).cacheControl(cc);
}
return response.build();
} else if (item instanceof VFSLeaf) {
//stream -> the length is not given to the client which is not nice
Date lastModified = new Date(item.getLastModified());
Response.ResponseBuilder response = request.evaluatePreconditions(lastModified);
if(response == null) {
StreamingOutput attachment = new VFSStreamingOutput((VFSLeaf)item);
String mimeType = WebappHelper.getMimeType(item.getName());
if (mimeType == null) mimeType = "application/octet-stream";
response = Response.ok(attachment).lastModified(lastModified).type(mimeType).cacheControl(cc);
}
return response.build();
}
return Response.serverError().status(Status.NOT_FOUND).build();
}
/**
* Upload the attachment of a message, as parameter:<br>
* filename The name of the attachment<br>
* file The attachment.
* @response.representation.200.mediaType application/json, application/xml
* @response.representation.200.doc Ok
* @response.representation.404.doc The identity or the portrait not found
* @param messageKey The key of the message
* @param request The HTTP request
* @return Ok
*/
@POST
@Path("posts/{messageKey}/attachments")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPostAttachment(@PathParam("messageKey") Long messageKey, @Context HttpServletRequest request) {
InputStream in = null;
MultipartReader partsReader = null;
try {
partsReader = new MultipartReader(request);
File tmpFile = partsReader.getFile();
in = new FileInputStream(tmpFile);
String filename = partsReader.getValue("filename");
return attachToPost(messageKey, filename, in, request);
} catch (FileNotFoundException e) {
log.error("", e);
return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
} finally {
MultipartReader.closeQuietly(partsReader);
IOUtils.closeQuietly(in);
}
}
/**
* Upload the attachment of a message
* @response.representation.200.mediaType application/json, application/xml
* @response.representation.200.doc Ok
* @response.representation.404.doc The identity or the portrait not found
* @param messageKey The key of the message
* @param filename The name of the attachment
* @file file64 The attachment (encoded as Base64)
* @param request The HTTP request
* @return Ok
*/
@POST
@Path("posts/{messageKey}/attachments")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPostAttachment(@PathParam("messageKey") Long messageKey, @FormParam("filename") String filename,
@FormParam("file") String file, @Context HttpServletRequest request) {
byte[] fileAsBytes = Base64.decodeBase64(file);
InputStream in = new ByteArrayInputStream(fileAsBytes);
return attachToPost(messageKey, filename, in, request);
}
@PUT
@Path("posts/{messageKey}/attachments")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response replyToPostAttachment(@PathParam("messageKey") Long messageKey, File64VO file64, @Context HttpServletRequest request) {
String file = file64.getFile();
String filename = file64.getFilename();
byte[] fileAsBytes = Base64.decodeBase64(file);
InputStream in = new ByteArrayInputStream(fileAsBytes);
return attachToPost(messageKey, filename, in, request);
}
protected Response attachToPost(Long messageKey, String filename, InputStream file, HttpServletRequest request) {
//load message
Message mess = fom.loadMessage(messageKey);
if(mess == null) {
return Response.serverError().status(Status.NOT_FOUND).build();
}
if(!forum.equalsByPersistableKey(mess.getForum())) {
return Response.serverError().status(Status.CONFLICT).build();
}
return attachToPost(mess, filename, file, request);
}
protected Response attachToPost(Message mess, String filename, InputStream file, HttpServletRequest request) {
Identity identity = getIdentity(request);
if(identity == null) {
return Response.serverError().status(Status.UNAUTHORIZED).build();
} else if (!identity.equalsByPersistableKey(mess.getCreator())) {
if(mess.getModifier() == null || !identity.equalsByPersistableKey(mess.getModifier())) {
return Response.serverError().status(Status.UNAUTHORIZED).build();
}
}
VFSContainer container = fom.getMessageContainer(mess.getForum().getKey(), mess.getKey());
VFSItem item = container.resolve(filename);
VFSLeaf attachment = null;
if(item == null) {
attachment = container.createChildLeaf(filename);
} else {
filename = VFSManager.rename(container, filename);
if(filename == null) {
return Response.serverError().status(Status.NOT_ACCEPTABLE).build();
}
attachment = container.createChildLeaf(filename);
}
OutputStream out = attachment.getOutputStream(false);
try {
IOUtils.copy(file, out);
} catch (IOException e) {
return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
} finally {
FileUtils.closeSafely(out);
FileUtils.closeSafely(file);
}
return Response.ok().build();
}
public String format(String segment) {
segment = segment.replace(" ", "_");
return segment;
}
private FileVO[] getAttachments(Message mess, UriInfo uriInfo) {
VFSContainer container = fom.getMessageContainer(mess.getForum().getKey(), mess.getKey());
List<FileVO> attachments = new ArrayList<FileVO>();
for(VFSItem item: container.getItems(new SystemItemFilter())) {
UriBuilder attachmentUri = uriInfo.getBaseUriBuilder().path("repo")
.path("forums").path(mess.getForum().getKey().toString())
.path("posts").path(mess.getKey().toString())
.path("attachments").path(format(item.getName()));
String uri = attachmentUri.build().toString();
if(item instanceof VFSLeaf) {
attachments.add(new FileVO("self", uri, item.getName(), ((VFSLeaf)item).getSize()));
} else {
attachments.add(new FileVO("self", uri, item.getName()));
}
}
FileVO[] attachmentArr = new FileVO[attachments.size()];
attachmentArr = attachments.toArray(attachmentArr);
return attachmentArr;
}
private MessageVO[] toArrayOfVO(List<Message> threads, UriInfo uriInfo) {
MessageVO[] threadArr = new MessageVO[threads.size()];
int i=0;
for(Message thread:threads) {
MessageVO msg = new MessageVO(thread);
msg.setAttachments(getAttachments(thread, uriInfo));
threadArr[i++] = msg;
}
return threadArr;
}
private Message.OrderBy toEnum(String str) {
if(StringHelper.containsNonWhitespace(str)) {
try {
return Message.OrderBy.valueOf(str);
} catch (Exception e) {
log.warn("", e);
}
}
return null;
}
private Identity getMessageAuthor(Long authorKey, HttpServletRequest httpRequest) {
BaseSecurity securityManager = BaseSecurityManager.getInstance();
Identity author;
if(authorKey == null) {
author = getIdentity(httpRequest);
} else if(isAdmin(httpRequest)) {
author = securityManager.loadIdentityByKey(authorKey, false);
} else {
author = getIdentity(httpRequest);
if(!authorKey.equals(author.getKey())) {
throw new WebApplicationException(Status.CONFLICT);
}
}
if(author == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
return author;
}
}