/*
* Copyright 2011-2012 Blazebit
*/
package com.blazebit.blazefaces.component.inputfiles;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import com.blazebit.blazefaces.apt.JsfRenderer;
import com.blazebit.blazefaces.renderkit.OutputRenderer;
import com.blazebit.blazefaces.util.HTML5;
import com.blazebit.blazefaces.util.RendererUtils;
@JsfRenderer
public class InputFilesRenderer extends OutputRenderer {
@Override
public void decode(FacesContext context, UIComponent component) {
InputFiles inputFile = (InputFiles) component;
if(!inputFile.isDisabled()) {
String clientId = inputFile.getClientId(context);
List<Part> parts = new ArrayList<Part>();
try {
for(Part p : ((HttpServletRequest)context.getExternalContext().getRequest()).getParts()) {
if(clientId.equals(p.getName())) {
parts.add(p);
}
}
} catch (IOException ex) {
throw new FacesException("Could not get the parts", ex);
} catch (ServletException ex) {
throw new FacesException("Could not get the parts", ex);
}
inputFile.setSubmittedValue(parts.toArray(new Part[0]));
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
String clientId = component.getClientId(context);
InputFiles inputFile = (InputFiles) component;
encodeMarkup(context, inputFile, clientId);
encodeScript(context, inputFile, clientId);
}
public void encodeMarkup(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("id", clientId, null);
writer.writeAttribute("class", "ui-fileupload", null);
encodeComponentContainer(context, component, clientId);
encodeFileContainer(context, component, clientId);
encodeGalleryWidget(context, component, clientId);
encodeUploadTemplate(context, component, clientId);
encodeDownloadTemplate(context, component, clientId);
writer.endElement("div");
}
public void encodeStartButton(FacesContext context, InputFiles component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("button", null);
writer.writeAttribute("type", "submit", null);
writer.writeAttribute("class", "ui-fileupload-upload", null);
writer.writeText("Start upload", null);
writer.endElement("button");
}
public void encodeResetButton(FacesContext context, InputFiles component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("button", null);
writer.writeAttribute("type", "reset", null);
writer.writeAttribute("class", "ui-fileupload-cancel", null);
writer.writeText("Cancel upload", null);
writer.endElement("button");
}
public void encodeDeleteButton(FacesContext context, InputFiles component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("button", null);
writer.writeAttribute("type", "button", null);
writer.writeAttribute("class", "ui-fileupload-delete", null);
writer.writeText("Delete", null);
writer.endElement("button");
}
public void encodeCheckbox(FacesContext context, InputFiles component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", null);
writer.writeAttribute("type", "checkbox", null);
writer.writeAttribute("class", "toggle", null);
writer.endElement("input");
}
public void encodeComponentContainer(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("class", "ui-fileupload-buttonbar", null);
writer.startElement("div", null);
writer.writeAttribute("class", "fileupload-buttons", null);
writer.startElement("span", null);
writer.writeAttribute("class", "ui-fileupload-choose", null);
writer.startElement("span", null);
writer.writeText("Add files...", null);
writer.endElement("span");
encodeInput(context, component, clientId);
writer.endElement("span");
encodeStartButton(context, component);
encodeResetButton(context, component);
encodeDeleteButton(context, component);
encodeCheckbox(context, component);
// writer.startElement("span", null);
// writer.writeAttribute("class", "fileinput-button", null);
// writer.endElement("span");
writer.endElement("div");
writer.startElement("div", null);
writer.writeAttribute("class", "fileupload-progress fade", null);
writer.writeAttribute("style", "display: none", null);
writer.startElement("div", null);
writer.writeAttribute("class", "progress", null);
writer.writeAttribute("role", "progressbar", null);
writer.writeAttribute("aria-valuemin", "0", null);
writer.writeAttribute("aria-valuemax", "100", null);
writer.endElement("div");
writer.startElement("div", null);
writer.writeAttribute("class", "progress-extended", null);
writer.writeText(" ", null);
writer.endElement("div");
writer.endElement("div");
writer.endElement("div");
}
public void encodeInput(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", component);
RendererUtils.encodeAttribute(writer, "id", clientId + "_input", null);
RendererUtils.encodeAttribute(writer, "name", clientId + "_input", null);
RendererUtils.encodeAttribute(writer, "type", "file", null);
// RendererUtils.encodeAttribute(writer, "class", component.getStyleClass(), null, "styleClass");
RendererUtils.encodeBooleanAttribute(writer, "disabled", component.isDisabled(), false, "disabled");
RendererUtils.encodeBooleanAttribute(writer, "multiple", true, false, null);
// Style-Attribute is included here
// renderPassThruAttributes(context, component, HTML5.COMMON_ATTRIBUTES);
// renderPassThruAttributes(context, component, HTML5.COMMON_TAG_ATTRIBUTES);
// renderDataMapAttributes(context, component);
writer.endElement("input");
}
public void encodeFileContainer(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("class", "ui-fileupload-content", null);
writer.startElement("table", null);
writer.writeAttribute("class", "ui-fileupload-files", null);
writer.writeAttribute("role", "presentation", null);
writer.startElement("tbody", null);
writer.writeAttribute("class", "files", null);
writer.endElement("tbody");
writer.endElement("table");
writer.endElement("div");
}
public void encodeGalleryWidget(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("id", "blueimp-gallery", null);
writer.writeAttribute("class", "blueimp-gallery blueimp-gallery-controls", null);
writer.writeAttribute("data-filters", ":even", null);
writer.startElement("div", null);
writer.writeAttribute("class", "sliders", null);
writer.endElement("div");
writer.startElement("h3", null);
writer.writeAttribute("class", "title", null);
writer.endElement("h3");
writer.startElement("a", null);
writer.writeAttribute("class", "prev", null);
writer.writeText("‹", null);
writer.endElement("a");
writer.startElement("a", null);
writer.writeAttribute("class", "next", null);
writer.writeText("›", null);
writer.endElement("a");
writer.startElement("a", null);
writer.writeAttribute("class", "close", null);
writer.writeText("×", null);
writer.endElement("a");
writer.startElement("a", null);
writer.writeAttribute("class", "play-pause", null);
writer.endElement("a");
writer.startElement("ol", null);
writer.writeAttribute("class", "indicator", null);
writer.endElement("ol");
writer.endElement("div");
}
public void encodeUploadTemplate(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("script", null);
writer.writeAttribute("id", clientId + "_template_upload", null);
writer.writeAttribute("type", "text/x-tmpl", null);
writer.writeText("{% for (var i=0, file; file=o.files[i]; i++) { %}", null);
if(component.getFacet("uploadTemplate") == null) {
encodeDefaultUploadTemplate(context, component, clientId);
}
writer.writeText("{% } %}", null);
writer.endElement("script");
}
public void encodeDownloadTemplate(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("script", null);
writer.writeAttribute("id", clientId + "_template_download", null);
writer.writeAttribute("type", "text/x-tmpl", null);
writer.writeText("{% for (var i=0, file; file=o.files[i]; i++) { %}", null);
if(component.getFacet("downloadTemplate") == null) {
encodeDefaultDownloadTemplate(context, component, clientId);
}
writer.writeText("{% } %}", null);
writer.endElement("script");
}
public void encodeDefaultUploadTemplate(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("tr", null);
writer.writeAttribute("class", "template-upload fade", null);
writer.startElement("td", null);
writer.startElement("span", null);
writer.writeAttribute("class", "preview", null);
writer.endElement("span");
writer.endElement("td");
writer.startElement("td", null);
writer.startElement("p", null);
writer.writeAttribute("class", "name", null);
writer.writeText("{%=file.name%}", null);
writer.endElement("p");
writer.writeText("{% if (file.error) { %}", null);
writer.startElement("div", null);
writer.startElement("span", null);
writer.writeAttribute("class", "error", null);
writer.writeText("Error:", null);
writer.endElement("span");
writer.writeText("{%=file.error%}", null);
writer.endElement("div");
writer.writeText("{% } %}", null);
writer.endElement("td");
writer.startElement("td", null);
writer.startElement("p", null);
writer.writeAttribute("class", "size", null);
writer.writeText("{%=o.formatFileSize(file.size)%}", null);
writer.endElement("p");
writer.writeText("{% if (!o.file.error) { %}", null);
writer.startElement("div", null);
writer.writeAttribute("class", "progress", null);
writer.endElement("div");
writer.writeText("{% } %}", null);
writer.endElement("td");
writer.startElement("td", null);
writer.writeText("{% if (!o.files.error && !i && !o.options.autoUpload) { %}", null);
writer.startElement("button", null);
writer.writeAttribute("class", "start", null);
writer.writeText("Start", null);
writer.endElement("button");
writer.writeText("{% } %}", null);
writer.writeText("{% if (!i) { %}", null);
writer.startElement("button", null);
writer.writeAttribute("class", "cancel", null);
writer.writeText("Cancel", null);
writer.endElement("button");
writer.writeText("{% } %}", null);
writer.endElement("td");
writer.endElement("tr");
}
public void encodeDefaultDownloadTemplate(FacesContext context, InputFiles component, String clientId) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("tr", null);
writer.writeAttribute("class", "template-download fade", null);
writer.startElement("td", null);
writer.startElement("span", null);
writer.writeAttribute("class", "preview", null);
writer.writeText("{% if (file.thumbnailUrl) { %}", null);
writer.startElement("a", null);
writer.writeAttribute("href", "{%=file.url%}", null);
writer.writeAttribute("title", "{%=file.name%}", null);
writer.writeAttribute("download", "{%=file.name%}", null);
writer.writeAttribute("data-gallery", "data-gallery", null);
writer.startElement("img", null);
writer.writeAttribute("src", "{%=file.thumbnailUrl%}", null);
writer.endElement("img");
writer.endElement("a");
writer.writeText("{% } %}", null);
writer.endElement("span");
writer.endElement("td");
writer.startElement("td", null);
writer.startElement("p", null);
writer.writeAttribute("class", "name", null);
writer.writeText("{% if (file.thumbnailUrl) { %}", null);
writer.startElement("a", null);
writer.writeAttribute("href", "{%=file.url%}", null);
writer.writeAttribute("title", "{%=file.name%}", null);
writer.writeAttribute("download", "{%=file.name%}", null);
writer.writeAttribute("data-gallery", "data-gallery", null);
writer.writeText("{%=file.name%}", null);
writer.endElement("a");
writer.writeText("{% } else { %}", null);
writer.startElement("a", null);
writer.writeAttribute("href", "{%=file.url%}", null);
writer.writeAttribute("title", "{%=file.name%}", null);
writer.writeAttribute("download", "{%=file.name%}", null);
writer.writeText("{%=file.name%}", null);
writer.endElement("a");
writer.writeText("{% } %}", null);
writer.endElement("p");
writer.writeText("{% if (file.error) { %}", null);
writer.startElement("div", null);
writer.startElement("span", null);
writer.writeAttribute("class", "error", null);
writer.writeText("Error", null);
writer.endElement("span");
writer.writeText("{%=file.error%}", null);
writer.endElement("div");
writer.writeText("{% } %}", null);
writer.endElement("td");
writer.startElement("td", null);
writer.startElement("p", null);
writer.writeAttribute("class", "size", null);
writer.writeText("{%=o.formatFileSize(file.size)%}", null);
writer.endElement("p");
writer.endElement("td");
writer.startElement("td", null);
writer.writeText("{% if (file.deleteWithCredentials) { %}", null);
writer.startElement("button", null);
writer.writeAttribute("class", "delete", null);
writer.writeAttribute("data-type", "{%=file.deleteType%}", null);
writer.writeAttribute("data-url", "{%=file.deleteUrl%}", null);
writer.writeAttribute("data-xhr-fields", "{'withCredentials':true}", null);
writer.writeText("Delete", null);
writer.endElement("button");
writer.writeText("{% } else { %}", null);
writer.startElement("button", null);
writer.writeAttribute("class", "delete", null);
writer.writeAttribute("data-type", "{%=file.deleteType%}", null);
writer.writeAttribute("data-url", "{%=file.deleteUrl%}", null);
writer.writeText("Delete", null);
writer.endElement("button");
writer.writeText("{% } %}", null);
writer.startElement("input", null);
writer.writeAttribute("type", "checkbox", null);
writer.writeAttribute("name", "delete", null);
writer.writeAttribute("value", "1", null);
writer.writeAttribute("class", "toggle", null);
writer.endElement("input");
writer.endElement("td");
writer.endElement("tr");
}
public void encodeScript(FacesContext context, InputFiles component, String clientId) throws IOException {
StringBuilder scriptBuilder = new StringBuilder();
scriptBuilder.append("BlazeFaces.cw('FileUpload',")
.append("'").append(component.getClientId()).append("',")
.append("{ id: '").append(component.getClientId()).append("',")
.append("maxFileSize: ").append(component.getMaxFileSize()).append(",")
.append("uploadTemplateId: '").append(clientId).append("_template_upload").append("',")
.append("downloadTemplateId: '").append(clientId).append("_template_download").append("',")
.append("dnd: false")
// .append("acceptFileType: ").append(component.getAllowedExtensions())
.append("});");
RendererUtils.addBodyBottomScript(context, scriptBuilder.toString());
}
}