/* MyMAM - Open Source Digital Media Asset Management. * http://www.mymam.net * * Copyright 2013, MyMAM contributors as indicated by the @author tag. * * 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 net.mymam.controller; import net.mymam.ejb.ConfigEJB; import net.mymam.ejb.MediaFileEJB; import net.mymam.entity.MediaFile; import net.mymam.ui.UploadedFile; import javax.ejb.EJB; import javax.faces.FacesException; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * Backing bean for the {@link net.mymam.ui.Upload Upload} component. * * @author fstab */ @ManagedBean @RequestScoped public class FileUploadBean implements Serializable { @ManagedProperty(value = "#{userBean}") private UserBean userBean; @EJB private ConfigEJB config; @EJB private MediaFileEJB mediaFileEJB; private UploadedFile uploadedFile; /** * Must provide getter for {@link ManagedProperty}. * * @return userBean to find the logged-on user who uploaded the file. */ public UserBean getUserBean() { return userBean; } /** * Must provide setter for {@link ManagedProperty}. * * @param userBean to find the logged-on user who uploaded the file. */ public void setUserBean(UserBean userBean) { this.userBean = userBean; } public UploadedFile getUploadedFile() { return uploadedFile; } /** * Save the uploaded file data into a new folder in media root, * and create a new file entity using the {@link MediaFileEJB}. * * @param uploadedFile points to the file data in the HTTP request body. */ public void setUploadedFile(UploadedFile uploadedFile) { this.uploadedFile = uploadedFile; process(uploadedFile); } private void process(UploadedFile file) { try { if ( ! userBean.isLoggedOn() ) { // This should not happen, as the upload page is restricted to authenticated users. err("Anonymous uploads not supported."); return; } makeMediaRoot(); Path root = makeRootDir(); Path orig = Paths.get(root.toString(), file.getFileItem().getName()); moveToPath(file, orig); String relRoot = Paths.get(config.findConfig().getMediaRoot()).relativize(root).toString(); String relOrig = root.relativize(orig).toString(); mediaFileEJB.createNewMediaFile(relRoot, relOrig); } catch (IOException e) { err("Failed to save " + file.getFileItem().getName() + ": " + e.getClass().getSimpleName() + ": " + e.getMessage()); } } /** * The file upload requests are not standard JSF requests: they are triggered * in a generated iframe using jQuery's file upload plugin. * * <p/> * Therefore, error handling is limited: Faces messages will not be handled * correctly. The only way to report an error to the client is to send an HTTP error code. * * @param msg is used for logging and may be seen in the browser's debugger, * but will not be displayed in the HTML page. */ private void err(String msg) { try { System.err.println(msg); FacesContext.getCurrentInstance().getExternalContext().responseSendError(500, msg); FacesContext.getCurrentInstance().responseComplete(); } catch ( IOException e ) { throw new FacesException(e); } } private void makeMediaRoot() throws IOException { File mediaRoot = Paths.get(config.findConfig().getMediaRoot()).toFile(); if ( ! mediaRoot.exists() ) { if ( ! mediaRoot.mkdirs() ) { throw new IOException("Cannot create " + config.findConfig().getMediaRoot()); } } } private Path makeRootDir() throws IOException { SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd."); return Files.createTempDirectory(Paths.get(config.findConfig().getMediaRoot()), myFormat.format(new Date())); } private void moveToPath(UploadedFile file, Path path) throws IOException { try (InputStream in = file.getFileItem().getInputStream(); OutputStream out = Files.newOutputStream(path)) { int read; byte[] bytes = new byte[1024]; while ((read = in.read(bytes)) != -1) { out.write(bytes, 0, read); } } } }