/**
* Copyright (c) 2008-2012 The Sakai Foundation
*
* Licensed under the Educational Community 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.osedu.org/licenses/ECL-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 org.sakaiproject.profile2.tool.pages;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.form.upload.MultiFileUploadField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.GridView;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.util.file.Files;
import org.apache.wicket.util.file.Folder;
import org.apache.wicket.util.lang.Bytes;
import org.sakaiproject.profile2.model.GalleryImage;
import org.sakaiproject.profile2.tool.components.GalleryImageRenderer;
import org.sakaiproject.profile2.tool.components.IconWithClueTip;
import org.sakaiproject.profile2.tool.dataproviders.GalleryImageDataProvider;
import org.sakaiproject.profile2.util.ProfileConstants;
import org.sakaiproject.profile2.util.ProfileUtils;
/**
* Main gallery component for viewing the current user's picture gallery.
*
* @author d.b.robinson@lancaster.ac.uk
*/
public class MyPictures extends BasePage {
private static final Logger log = Logger.getLogger(MyPictures.class);
private List<File> addPictureFiles = new ArrayList<File>();
private FileListView addPictureListView;
private Folder addPictureUploadFolder;
private GridView gridView;
/**
* Constructor for current user.
*/
public MyPictures() {
renderMyPictures(0, sakaiProxy.getCurrentUserId());
}
/**
* Constructor for current user.
*
* @param pageToDisplay
* gallery page index used to set the page the user is returned
* to after making a change to the gallery.
*/
public MyPictures(int pageToDisplay) {
renderMyPictures(pageToDisplay, sakaiProxy.getCurrentUserId());
}
/**
* Does the actual rendering of the page
*/
private void renderMyPictures(int pageToDisplay, String userUuid) {
log.debug("MyPictures()");
disableLink(myPicturesLink);
createGalleryForm(userUuid, pageToDisplay);
createAddPictureForm(userUuid);
}
private void createAddPictureForm(final String userUuid) {
addPictureUploadFolder = new Folder(System
.getProperty("java.io.tmpdir"), "addPicturesUploadFolder");
addPictureUploadFolder.mkdirs();
//file feedback will be redirected here
final FeedbackPanel fileFeedback = new FeedbackPanel("fileFeedback");
fileFeedback.setOutputMarkupId(true);
Form addPictureForm = new FileUploadForm("form", userUuid, fileFeedback);
addPictureForm.add(fileFeedback);
addPictureForm.setOutputMarkupId(true);
add(addPictureForm);
Label invalidFileTypeMessageLabel = new Label("invalidFileTypeMessage",new ResourceModel("pictures.filetypewarning"));
invalidFileTypeMessageLabel.setMarkupId("invalidFileTypeMessage");
invalidFileTypeMessageLabel.setOutputMarkupId(true);
addPictureForm.add(invalidFileTypeMessageLabel);
WebMarkupContainer addPictureContainer = new WebMarkupContainer(
"addPictureContainer");
addPictureContainer.add(new Label("addPictureLabel", new ResourceModel(
"pictures.addpicture")));
addPictureContainer.add(new MultiFileUploadField("choosePicture",
new PropertyModel<Collection<FileUpload>>(addPictureForm,
"uploads"), ProfileConstants.MAX_GALLERY_FILE_UPLOADS));
IndicatingAjaxButton submitButton = new IndicatingAjaxButton(
"submitPicture", new ResourceModel("button.gallery.upload")) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
target.addComponent(fileFeedback);
}
protected void onError(AjaxRequestTarget target, Form form) {
log.debug("MyPictures.onSubmit validation failed.");
target.addComponent(fileFeedback);
}
};
addPictureContainer.add(submitButton);
addPictureContainer
.add(new IconWithClueTip("galleryImageUploadToolTip",
ProfileConstants.INFO_IMAGE, new StringResourceModel(
"text.gallery.upload.tooltip", null,
new Object[] { sakaiProxy.getMaxProfilePictureSize()
* ProfileConstants.MAX_GALLERY_FILE_UPLOADS })));
addPictureForm.add(addPictureContainer);
addPictureFiles.addAll(Arrays
.asList(addPictureUploadFolder.listFiles()));
addPictureListView = new FileListView("fileList", addPictureFiles);
addPictureForm.add(addPictureListView);
}
private void createGalleryForm(final String userUuid, int pageToDisplay) {
Label galleryHeading = new Label("galleryHeading", new ResourceModel(
"heading.pictures.my.pictures"));
add(galleryHeading);
Form galleryForm = new Form("galleryForm");
galleryForm.setOutputMarkupId(true);
populateGallery(galleryForm, userUuid, pageToDisplay);
add(galleryForm);
Label addPictureHeading = new Label("addPictureHeading",
new ResourceModel("heading.pictures.addpicture"));
add(addPictureHeading);
}
/**
* Populates gallery using GalleryImageDataProvider for given user. The
* pageToDisplay allows us to return the user to the gallery page they were
* previously viewing after removing an image from the gallery.
*/
private void populateGallery(Form galleryForm, final String userUuid,
int pageToDisplay) {
IDataProvider dataProvider = new GalleryImageDataProvider(userUuid);
int numImages = dataProvider.size();
gridView = new GridView("rows", dataProvider) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(Item item) {
final GalleryImage image = (GalleryImage) item.getModelObject();
final GalleryImageRenderer galleryImageThumbnailRenderer = new GalleryImageRenderer(
"galleryImageThumbnailRenderer", image
.getThumbnailResource());
AjaxLink galleryImageLink = new AjaxLink("galleryItem") {
public void onClick(AjaxRequestTarget target) {
setResponsePage(new MyPicture(userUuid, image, getCurrentPage()));
}
};
galleryImageLink.add(galleryImageThumbnailRenderer);
item.add(galleryImageLink);
}
@Override
protected void populateEmptyItem(Item item) {
Link galleryImageLink = new Link("galleryItem") {
@Override
public void onClick() {
}
};
galleryImageLink.add(new Label("galleryImageThumbnailRenderer"));
item.add(galleryImageLink);
}
};
gridView.setRows(3);
gridView.setColumns(4);
galleryForm.add(gridView);
Label noPicturesLabel;
//pager
if (numImages == 0) {
galleryForm.add(new PagingNavigator("navigator", gridView).setVisible(false));
noPicturesLabel = new Label("noPicturesLabel", new ResourceModel("text.gallery.pictures.num.none"));
} else if (numImages <= ProfileConstants.MAX_GALLERY_IMAGES_PER_PAGE) {
galleryForm.add(new PagingNavigator("navigator", gridView).setVisible(false));
noPicturesLabel = new Label("noPicturesLabel");
} else {
galleryForm.add(new PagingNavigator("navigator", gridView));
noPicturesLabel = new Label("noPicturesLabel");
}
galleryForm.add(noPicturesLabel);
// set page to display
if (pageToDisplay > 0) {
if (pageToDisplay < gridView.getPageCount()) {
gridView.setCurrentPage(pageToDisplay);
} else {
// default to last page for add/remove operations
gridView.setCurrentPage(gridView.getPageCount() - 1);
}
} else {
gridView.setCurrentPage(0);
}
}
private class FileListView extends ListView<File> {
private static final long serialVersionUID = 1L;
public FileListView(String name, final List<File> files) {
super(name, files);
}
protected void populateItem(ListItem<File> listItem) {
final File file = (File) listItem.getModelObject();
listItem.add(new Label("file", file.getName()));
listItem.add(new Link("delete") {
public void onClick() {
Files.remove(file);
}
});
}
}
private class FileUploadForm extends Form {
private static final long serialVersionUID = 1L;
private final Collection<FileUpload> uploads = new ArrayList<FileUpload>();
private final String userUuid;
private FeedbackPanel fileFeedback;
public FileUploadForm(String id, String userUuid, FeedbackPanel fileFeedback) {
super(id);
this.userUuid = userUuid;
this.fileFeedback = fileFeedback;
// set form to multipart mode
setMultiPart(true);
setMaxSize(Bytes.megabytes(sakaiProxy.getMaxProfilePictureSize()
* ProfileConstants.MAX_GALLERY_FILE_UPLOADS));
}
public Collection<FileUpload> getUploads() {
return uploads;
}
protected void onSubmit() {
if (uploads.size() == 0) {
error(new StringResourceModel("error.gallery.upload.warning", this, null).getString());
return;
}
Iterator<FileUpload> filesToUpload = uploads.iterator();
while (filesToUpload.hasNext()) {
final FileUpload upload = filesToUpload.next();
if (upload == null) {
log.error("picture upload was null.");
error(new StringResourceModel("error.no.file.uploaded", this, null).getString());
return;
} else if (upload.getSize() == 0) {
log.error("picture upload was empty.");
error(new StringResourceModel("error.empty.file.uploaded", this, null).getString());
return;
} else if (!ProfileUtils.checkContentTypeForProfileImage(upload
.getContentType())) {
log.error("attempted to upload invalid file type to gallery");
error(new StringResourceModel("error.invalid.image.type", this, null).getString());
return;
}
byte[] imageBytes = upload.getBytes();
if (!imageLogic.addGalleryImage(
userUuid, imageBytes, upload.getContentType(),
FilenameUtils.getName(upload.getClientFileName()))) {
log.error("unable to save gallery image");
error(new StringResourceModel("error.file.save.failed", this, null).getString());
return;
}
// post upload event
sakaiProxy.postEvent(
ProfileConstants.EVENT_GALLERY_IMAGE_UPLOAD,
"/profile/" + sakaiProxy.getCurrentUserId(), true);
}
// post to walls if wall enabled
if (true == sakaiProxy.isWallEnabledGlobally()) {
wallLogic.addNewEventToWall(ProfileConstants.EVENT_GALLERY_IMAGE_UPLOAD, sakaiProxy.getCurrentUserId());
}
setResponsePage(new MyPictures(gridView.getPageCount()));
}
}
}