@Override
  public void encodeMarkupEnd(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    // If the component should show the progress table, then
    InputFile inputFile = (InputFile) uiComponent;
    ResponseWriter responseWriter = facesContext.getResponseWriter();

    if (inputFile.isShowProgress()) {

      // Finish encoding of the outermost <div> element. Since the template contains its own "Select
      // Files"
      // button, delegation must not occur.
      responseWriter.endElement("div");
    }

    // Otherwise, if the component should show the preview table, then
    else if (inputFile.isShowPreview()) {

      encodePreview(facesContext, responseWriter, inputFile);

      // Finish encoding of the outermost <div> element.
      responseWriter.endElement("div");
    }

    // Otherwise, delegate writing of the entire <input type="file"...> ... </input> element to the
    // delegate
    // renderer.
    else {
      DelegationResponseWriter delegationResponseWriter =
          new InputFileDelegationResponseWriter(responseWriter, inputFile.isAuto());
      super.encodeMarkupEnd(facesContext, uiComponent, delegationResponseWriter);
    }
  }
  protected void encodePreview(
      FacesContext facesContext, ResponseWriter responseWriter, InputFile inputFile)
      throws IOException {

    // Delegate writing of the entire <input type="file"...> ... </input> element to the delegate
    // renderer.
    DelegationResponseWriter delegationResponseWriter =
        new InputFileDelegationResponseWriter(responseWriter, inputFile.isAuto());
    super.encodeMarkupEnd(facesContext, inputFile, delegationResponseWriter);

    // Format the preview-table.html template and write it to the response.
    Locale locale = facesContext.getViewRoot().getLocale();
    String clientId = inputFile.getClientId(facesContext);
    responseWriter.startElement("div", inputFile);
    responseWriter.startElement("table", inputFile);
    responseWriter.writeAttribute("id", clientId + "_table", null);
    responseWriter.writeAttribute("class", "table table-bordered", null);
    responseWriter.startElement("thead", inputFile);
    responseWriter.writeAttribute("class", "table-columns", null);
    responseWriter.startElement("tr", inputFile);
    responseWriter.startElement("th", inputFile);

    MessageContextFactory messageContextFactory =
        (MessageContextFactory) FactoryExtensionFinder.getFactory(MessageContextFactory.class);
    MessageContext messageContext = messageContextFactory.getMessageContext();
    String i18nFileName = messageContext.getMessage(locale, "file-name");
    responseWriter.writeText(i18nFileName, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", inputFile);

    String i18nFileType = messageContext.getMessage(locale, "file-type");
    responseWriter.writeText(i18nFileType, null);
    responseWriter.endElement("th");
    responseWriter.startElement("th", inputFile);

    String i18nFileSize = messageContext.getMessage(locale, "file-size");
    responseWriter.writeText(i18nFileSize, null);
    responseWriter.endElement("th");
    responseWriter.endElement("tr");
    responseWriter.endElement("thead");
    responseWriter.startElement("tfoot", inputFile);
    responseWriter.startElement("tr", inputFile);
    responseWriter.startElement("td", inputFile);
    responseWriter.writeAttribute("colspan", "3", null);

    String i18nNoFilesSelected = messageContext.getMessage(locale, "no-files-selected");
    responseWriter.writeText(i18nNoFilesSelected, null);
    responseWriter.endElement("td");
    responseWriter.endElement("tr");
    responseWriter.endElement("tfoot");
    responseWriter.startElement("tbody", inputFile);
    responseWriter.startElement("tr", inputFile);
    responseWriter.endElement("tr");
    responseWriter.endElement("tbody");
    responseWriter.endElement("table");
    responseWriter.endElement("div");
  }
  @Override
  public void encodeJavaScriptCustom(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();
    InputFile inputFile = (InputFile) uiComponent;
    JavaScriptFragment alloyNamespace = new JavaScriptFragment("A");

    // Determine the valid content-types and maximum file size from the validator (if specified).
    JavaScriptFragment contentTypes = new JavaScriptFragment("[]");
    String validContentTypes = inputFile.getContentTypes();

    if (validContentTypes != null) {
      contentTypes = toJavaScriptArray(validContentTypes.split(","));
    }

    String clientId = inputFile.getClientId(facesContext);
    Long maxFileSize = inputFile.getMaxFileSize();

    if (maxFileSize == null) {
      maxFileSize = Long.MAX_VALUE;
    }

    // If the component should render the upload progress table, then initialize the YUI progress
    // uploader widget.
    if (inputFile.isShowProgress()) {

      String clientVarName = getClientVarName(facesContext, inputFile);
      String clientKey = inputFile.getClientKey();

      if (clientKey == null) {
        clientKey = clientVarName;
      }

      UIViewRoot viewRoot = facesContext.getViewRoot();
      Locale locale = viewRoot.getLocale();
      String formClientId = getParentFormClientId(inputFile);
      Application application = facesContext.getApplication();
      ViewHandler viewHandler = application.getViewHandler();
      String actionURL = viewHandler.getActionURL(facesContext, viewRoot.getViewId());
      String partialActionURL = facesContext.getExternalContext().encodePartialActionURL(actionURL);
      String namingContainerId = "";

      if (viewRoot instanceof NamingContainer) {
        namingContainerId = viewRoot.getContainerClientId(facesContext);
      }

      AjaxParameters ajaxParameters = new AjaxParameters(inputFile, clientId, formClientId);
      String execute = ajaxParameters.getExecute();
      String render = ajaxParameters.getRender();

      String notStartedMessage = getMessageContext().getMessage(locale, "not-started");
      JavaScriptFragment clientComponent =
          new JavaScriptFragment("Liferay.component('" + clientKey + "')");
      encodeFunctionCall(
          responseWriter,
          "LFAI.initProgressUploader",
          alloyNamespace,
          clientComponent,
          contentTypes,
          clientId,
          formClientId,
          namingContainerId,
          inputFile.isAuto(),
          execute,
          render,
          partialActionURL,
          maxFileSize,
          notStartedMessage);
    }

    // Otherwise, if the component should render the upload preview table, then format the
    // preview-uploader.js
    // template and write it to the response.
    else if (inputFile.isShowPreview()) {

      encodeFunctionCall(
          responseWriter,
          "LFAI.initPreviewUploader",
          alloyNamespace,
          contentTypes,
          clientId,
          maxFileSize);
    }
  }