Package org.jboss.seam.wiki.core.upload

Source Code of org.jboss.seam.wiki.core.upload.Uploader

package org.jboss.seam.wiki.core.upload;

import net.sf.jmimemagic.Magic;
import org.jboss.seam.ScopeType;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.WikiUpload;
import org.jboss.seam.wiki.core.upload.handler.UploadHandler;

import static org.jboss.seam.international.StatusMessage.Severity.ERROR;
import static org.jboss.seam.international.StatusMessage.Severity.WARN;

import java.util.Map;
import java.io.Serializable;

/**
* A handy conversation-scoped component we can use to bind a typical upload form to.
* <p>
* Call the <tt>uploadNewInstance()</tt> action and then access <tt>getUpload()</tt> in the same
* conversation. Uses upload handlers to instantiate and fill the data into the right
* <tt>WikiUpload</tt> subclass.
* <p>
* Call the <tt>uploadUpdateInstance(id)</tt> action to retrieve and fill the data into
* an existing <tt>WikiUpload</tt> subclass instance.
*
* @author Christian Bauer
*/
@Name("uploader")
@Scope(ScopeType.CONVERSATION)
public class Uploader implements Serializable {

    @Logger
    Log log;

    @In
    private StatusMessages statusMessages;

    @In
    Map<String, UploadType> uploadTypes;

    UploadHandler handler;

    WikiUpload upload;

    private String filename;
    private String contentType;
    private byte[] data;
    Long parentDirectoryId;

    public UploadHandler getUploadHandler() {
        return handler;
    }

    public WikiUpload getUpload() {
        return upload;
    }

    public Long getParentDirectoryId() {
        return parentDirectoryId;
    }

    public void setParentDirectoryId(Long parentDirectoryId) {
        this.parentDirectoryId = parentDirectoryId;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public byte[] getData() {
        return data;
    }

    public void setData(byte[] data) {
        this.data = data;
    }

    /**
     * Marshall form data into a new <tt>WikiUpload</tt> instance, pick
     * the right handler automatically based on the data (or browser, if magic fails) content type.
     *
     * @return String outcome of action, null or if successful, the simple classname of the created entity.
     */
    public String uploadNewInstance() {
        log.debug("uploading new instance");
        if (!validateData()) return null;
        resolveContentType();
        UploadType uploadType = uploadTypes.get(contentType);
        if (uploadType == null) {
            uploadType = uploadTypes.get(UploadTypes.GENERIC_UPLOAD_TYPE);
        }
        upload = uploadType.getUploadHandler().handleUpload(this);
        handler = uploadType.getUploadHandler();
        log.debug("uploaded: " + upload);
        return upload.getClass().getSimpleName();
    }

    /**
     * Marshall form data into existing <tt>WikiUpload</tt> instance, pick
     * the right handler automatically based on (possibly new) content type.
     *
     * @param instance The instance to be updated
     * @return String outcome of action, null or if successful, the simple classname of the updated entity.
     */
    public String uploadUpdateInstance(WikiUpload instance) {
        return uploadUpdateInstance(instance, false);
    }

    /**
     * Marshall form data into existing <tt>WikiUpload</tt> instance.
     * <p>
     * Optionally you can enforce that the same upload handler class should be used
     * as has been used for the existing <tt>WikiUpload</tt>. For example, if the
     * existing entity is a <tt>WikiUploadImage</tt>, its upload handler would be
     * <tt>WikiUploadImageHandler</tt>, based on the content type we stored along with
     * the entity. If the newly uploaded data/content type does not produce the same
     * handler class, a JSF message will be queued, <tt>getUpdate()</tt> will return null,
     * and no data will be marshalled.
     *
     * @param instance The instance to be updated
     * @param forceSameHandler Force the same handler
     * @return String outcome of action, null or if successful, the simple classname of the updated entity.
     */
    public String uploadUpdateInstance(WikiUpload instance, boolean forceSameHandler) {
        log.debug("uploading and updating existing instance: " + instance);
        this.upload = instance;
        if (!validateData()) return null;
        resolveContentType();

        UploadType newUploadType = uploadTypes.get(contentType);
        UploadHandler newupUploadHandler =
                newUploadType != null
                ? newUploadType.getUploadHandler()
                : uploadTypes.get(UploadTypes.GENERIC_UPLOAD_TYPE).getUploadHandler();

        if (forceSameHandler) {
            log.debug("using same upload handler as for the original, based on content type: " + instance.getContentType());
            UploadHandler previousUploadHandler;
            UploadType previousUploadType = uploadTypes.get(instance.getContentType());
            previousUploadHandler =
                    previousUploadType != null
                    ? previousUploadType.getUploadHandler()
                    : uploadTypes.get(UploadTypes.GENERIC_UPLOAD_TYPE).getUploadHandler();
            if (!previousUploadHandler.getClass().equals(newupUploadHandler.getClass())) {
                statusMessages.addFromResourceBundleOrDefault(
                    ERROR,
                    "lacewiki.msg.upload.HandlersDontMatch",
                    "Wrong file type uploaded, please try again with a different file."
                );
                upload = null;
                return null;
            }
        }

        log.debug("using upload handler to marshall data: " + newupUploadHandler.getClass());
        upload = newupUploadHandler.handleUpload(this, upload);
        handler = newupUploadHandler;
        log.debug("uploaded: " + upload);
        return upload.getClass().getSimpleName();
    }

    public boolean hasData() {
        return data != null && data.length > 0;
    }

    public boolean validateData() {
        if (data == null || data.length == 0) {
            statusMessages.addFromResourceBundleOrDefault(
                WARN,
                "lacewiki.msg.upload.NoData",
                "Please select a file to upload"
            );
            return false;
        }
        return true;
    }

    public void reset() {
        filename = null;
        contentType = null;
        data = null;
    }

    // Use mime magic to find the "real" content type - but if there is an exception
    // (which is expected because JMimeMagic is crap) - use the browser-supplied type.
    protected void resolveContentType() {
        String mimeType = null;
        try {
            mimeType = Magic.getMagicMatch(data).getMimeType();
        } catch (Exception ex) {}
        contentType = mimeType != null ? mimeType : contentType;
    }

}
TOP

Related Classes of org.jboss.seam.wiki.core.upload.Uploader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.