/* * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.platform.ui.web.component.file; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.faces.application.Application; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.component.html.HtmlInputFile; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.validator.Validator; import org.apache.commons.lang.StringUtils; import org.nuxeo.ecm.core.api.Blob; import org.nuxeo.ecm.platform.ui.web.util.ComponentUtils; /** * JSF File Upload mechanism based on a standard HTML {@code <input>} field. * * @since 7.2 */ public class HTMLBlobUploader implements JSFBlobUploader { protected static final String UPLOAD_FACET_NAME = "upload"; public HTMLBlobUploader(String id) { } @Override public String getChoice() { return InputFileChoice.UPLOAD; } @Override public void hookSubComponent(UIInput parent) { FacesContext faces = FacesContext.getCurrentInstance(); Application app = faces.getApplication(); ComponentUtils.initiateSubComponent(parent, UPLOAD_FACET_NAME, app.createComponent(faces, HtmlInputFile.COMPONENT_TYPE, NXFileRenderer.RENDERER_TYPE)); } @Override public void encodeBeginUpload(UIInput parent, FacesContext context, String onChange) throws IOException { UIComponent facet = parent.getFacet(UPLOAD_FACET_NAME); if (!(facet instanceof HtmlInputFile)) { return; } HtmlInputFile inputFile = (HtmlInputFile) facet; // not ours to close @SuppressWarnings("resource") ResponseWriter writer = context.getResponseWriter(); // encode validators info long sizeMax = 0L; String sizeConstraint = null; List<String> authorizedExtensions = new ArrayList<String>(); List<String> unauthorizedExtensions = new ArrayList<String>(); boolean hidden = false; for (Validator val : parent.getValidators()) { if (val instanceof InputFileSizeValidator) { InputFileSizeValidator sizeVal = (InputFileSizeValidator) val; long currentSizeMax = sizeVal.getMaxSizeBytes(); if (currentSizeMax > sizeMax) { sizeMax = currentSizeMax; sizeConstraint = sizeVal.getMaxSize(); } } else if (val instanceof InputFileMimetypeValidator) { InputFileMimetypeValidator extVal = (InputFileMimetypeValidator) val; hidden = extVal.isHidden(); if (extVal.isAuthorized()) { authorizedExtensions.addAll(Arrays.asList(extVal.getExtensions())); } else { unauthorizedExtensions.addAll(Arrays.asList(extVal.getExtensions())); } } } List<String> constraints = new ArrayList<String>(); if (sizeConstraint != null) { constraints.add(ComponentUtils.translate(context, "label.inputFile.maxSize", sizeConstraint)); } if (!hidden && (!authorizedExtensions.isEmpty() || !unauthorizedExtensions.isEmpty())) { if (!authorizedExtensions.isEmpty()) { constraints.add(ComponentUtils.translate(context, "label.inputFile.authorizedExtensions", StringUtils.join(authorizedExtensions.toArray(), ", "))); } if (!unauthorizedExtensions.isEmpty()) { constraints.add(ComponentUtils.translate(context, "label.inputFile.unauthorizedExtensions", StringUtils.join(unauthorizedExtensions.toArray(), ", "))); } } if (constraints.size() > 0) { writer.write("("); writer.write(StringUtils.join(constraints.toArray(), ", ")); writer.write(")"); writer.write(ComponentUtils.WHITE_SPACE_CHARACTER); } // encode upload component inputFile.setOnchange(onChange); // TODO: add size limit info ComponentUtils.encodeComponent(context, inputFile); } @Override public void validateUpload(UIInput parent, FacesContext context, InputFileInfo submitted) { UIComponent facet = parent.getFacet(UPLOAD_FACET_NAME); if (!(facet instanceof HtmlInputFile)) { return; } HtmlInputFile inputFile = (HtmlInputFile) facet; Object submittedFile = inputFile.getSubmittedValue(); if (!(submittedFile instanceof Blob)) { return; } Blob sblob = (Blob) submittedFile; if (sblob.getLength() == 0) { String message = context.getPartialViewContext().isAjaxRequest() ? InputFileInfo.INVALID_WITH_AJAX_MESSAGE : InputFileInfo.EMPTY_FILE_MESSAGE; ComponentUtils.addErrorMessage(context, parent, message); parent.setValid(false); return; } submitted.setBlob(sblob); submitted.setFilename(sblob.getFilename()); submitted.setMimeType(sblob.getMimeType()); } @Override public boolean isEnabled() { return true; } }