/*
* Copyright 2014 Buddycloud
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.buddycloud.mediaserver.web;
import com.buddycloud.mediaserver.business.dao.DAOFactory;
import com.buddycloud.mediaserver.business.dao.MediaDAO;
import com.buddycloud.mediaserver.commons.Constants;
import com.buddycloud.mediaserver.commons.MediaFile;
import com.buddycloud.mediaserver.commons.exception.*;
import com.buddycloud.mediaserver.web.representation.DynamicFileRepresentation;
import com.buddycloud.mediaserver.xmpp.XMPPToolBox;
import org.apache.commons.fileupload.FileUploadException;
import org.restlet.Request;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.representation.EmptyRepresentation;
import org.restlet.representation.FileRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.Put;
import java.io.File;
import java.io.IOException;
/**
* Resource that represents /<channel>/<mediaId> endpoint.
*
* @author Rodrigo Duarte Sousa - rodrigodsousa@gmail.com
*/
public class MediaResource extends MediaServerResource {
/**
* Uploads avatar (PUT /<channel>/avatar)
*/
@Put("application/x-www-form-urlencoded|multipart/form-data")
public Representation putAvatar(Representation entity) {
setServerHeader();
Request request = getRequest();
try {
String userJID = getUsedJID(request, true);
MediaDAO mediaDAO = DAOFactory.getInstance().getDAO();
String entityId = (String) request.getAttributes().get(Constants.ENTITY_ARG);
String mediaId = (String) request.getAttributes().get(Constants.MEDIA_ARG);
if (!mediaId.equals(Constants.AVATAR_ARG)) {
setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
return new StringRepresentation("Valid only for avatars!", MediaType.APPLICATION_JSON);
}
String result;
if (MediaType.MULTIPART_FORM_DATA.equals(entity.getMediaType(), true)) {
result = mediaDAO.insertFormDataMedia(userJID, entityId, getRequest(), true);
} else {
result = mediaDAO.insertWebFormMedia(userJID, entityId, new Form(entity), true);
}
setStatus(Status.SUCCESS_CREATED);
return new StringRepresentation(result, MediaType.APPLICATION_JSON);
} catch (MissingAuthenticationException e) {
setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
return authenticationResponse();
} catch (FileUploadException e) {
setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
} catch (UserNotAllowedException e) {
setStatus(Status.CLIENT_ERROR_FORBIDDEN);
} catch (XMPPException e) {
setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
} catch (Throwable t) {
return unexpectedError(t);
}
return new EmptyRepresentation();
}
/**
* Deletes media (DELETE /<channel>/<mediaId>)
*/
@Delete
public Representation deleteMedia() {
setServerHeader();
Request request = getRequest();
try {
String userJID = getUsedJID(request, true);
String entityId = (String) request.getAttributes().get(Constants.ENTITY_ARG);
String mediaId = (String) request.getAttributes().get(Constants.MEDIA_ARG);
MediaDAO mediaDAO = DAOFactory.getInstance().getDAO();
mediaDAO.deleteMedia(userJID, entityId, mediaId);
return new StringRepresentation("Media deleted!", MediaType.APPLICATION_JSON);
} catch (MetadataSourceException e) {
setStatus(Status.SERVER_ERROR_INTERNAL);
} catch (MediaNotFoundException e) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND);
} catch (UserNotAllowedException e) {
setStatus(Status.CLIENT_ERROR_FORBIDDEN);
} catch (MissingAuthenticationException e) {
setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
return authenticationResponse();
} catch (XMPPException e) {
setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
} catch (Throwable t) {
return unexpectedError(t);
}
return new EmptyRepresentation();
}
/**
* Updates media (POST /<channel>/<mediaId>)
*/
@Post("application/x-www-form-urlencoded")
public Representation updateMedia(Representation entity) {
setServerHeader();
Request request = getRequest();
try {
String userJID = getUsedJID(request, true);
String entityId = (String) request.getAttributes().get(Constants.ENTITY_ARG);
String mediaId = (String) request.getAttributes().get(Constants.MEDIA_ARG);
MediaDAO mediaDAO = DAOFactory.getInstance().getDAO();
return new StringRepresentation(mediaDAO.updateMedia(
userJID, entityId, mediaId, new Form(entity)),
MediaType.APPLICATION_JSON);
} catch (MetadataSourceException e) {
setStatus(Status.SERVER_ERROR_INTERNAL);
} catch (MediaNotFoundException e) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND);
} catch (UserNotAllowedException e) {
setStatus(Status.CLIENT_ERROR_FORBIDDEN);
} catch (MissingAuthenticationException e) {
setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
return authenticationResponse();
} catch (XMPPException e) {
setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
} catch (Throwable t) {
return unexpectedError(t);
}
return new EmptyRepresentation();
}
/**
* Downloads media (GET /<channel>/<mediaId>)
*/
@Get
public Representation getMedia() {
setServerHeader();
Request request = getRequest();
Integer maxHeight = getIntegerQueryValue(Constants.MAX_HEIGHT_QUERY);
Integer maxWidth = getIntegerQueryValue(Constants.MAX_WIDTH_QUERY);
if (maxHeight != null && maxWidth == null) {
maxWidth = maxHeight;
} else if (maxHeight == null && maxWidth != null) {
maxHeight = maxWidth;
}
String entityId = (String) request.getAttributes().get(Constants.ENTITY_ARG);
String mediaId = (String) request.getAttributes().get(Constants.MEDIA_ARG);
try {
if (mediaId.equals(Constants.AVATAR_ARG)) {
return getAvatar(entityId, maxHeight, maxWidth);
}
return getRegularMedia(request, entityId, mediaId, maxHeight, maxWidth);
} catch (MetadataSourceException e) {
setStatus(Status.SERVER_ERROR_INTERNAL);
} catch (IOException e) {
setStatus(Status.SERVER_ERROR_INTERNAL);
} catch (MediaNotFoundException e) {
setStatus(Status.CLIENT_ERROR_NOT_FOUND);
} catch (InvalidPreviewFormatException e) {
setStatus(Status.CLIENT_ERROR_PRECONDITION_FAILED);
} catch (UserNotAllowedException e) {
setStatus(Status.CLIENT_ERROR_FORBIDDEN);
} catch (MissingAuthenticationException e) {
setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
return authenticationResponse();
} catch (XMPPException e) {
setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
} catch (Throwable t) {
return unexpectedError(t);
}
return new EmptyRepresentation();
}
private Representation getRegularMedia(Request request, String entityId, String mediaId, Integer maxHeight, Integer maxWidth)
throws UserNotAllowedException, MissingAuthenticationException, IOException,
MediaNotFoundException, MetadataSourceException, InvalidPreviewFormatException {
String userJID = null;
boolean isChannelPublic = XMPPToolBox.getInstance().getPubSubClient().isChannelPublic(entityId);
if (!isChannelPublic) {
userJID = getUsedJID(request, true);
}
MediaDAO mediaDAO = DAOFactory.getInstance().getDAO();
if (maxHeight == null && maxWidth == null) {
MediaFile<File> mediaFile = mediaDAO.getMedia(userJID, entityId, mediaId);
MediaType mediaType = new MediaType(mediaFile.getMimeType());
return new FileRepresentation(mediaFile.getMediaFile(), mediaType);
}
MediaFile<byte[]> thumbnail = mediaDAO.getMediaPreview(userJID, entityId, mediaId, maxHeight, maxWidth);
return new DynamicFileRepresentation(new MediaType(thumbnail.getMimeType()), thumbnail.getMediaFile());
}
private Representation getAvatar(String entityId, Integer maxHeight, Integer maxWidth)
throws MetadataSourceException, UserNotAllowedException, MediaNotFoundException,
IOException, InvalidPreviewFormatException {
MediaDAO mediaDAO = DAOFactory.getInstance().getDAO();
Representation representation;
if (maxHeight == null && maxWidth == null) {
MediaFile<File> mediaFile = mediaDAO.getMedia(null, entityId, Constants.AVATAR_ARG);
MediaType mediaType = new MediaType(mediaFile.getMimeType());
representation = new FileRepresentation(mediaFile.getMediaFile(), mediaType);
representation.setModificationDate(mediaFile.getLastModified());
} else {
MediaFile<byte[]> thumbnail = mediaDAO.getMediaPreview(null, entityId, Constants.AVATAR_ARG, maxHeight, maxWidth);
representation = new DynamicFileRepresentation(new MediaType(thumbnail.getMimeType()), thumbnail.getMediaFile());
representation.setModificationDate(thumbnail.getLastModified());
}
return representation;
}
}