All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.renderkit.html.FileChooserRenderer Maven / Gradle / Ivy

There is a newer version: 4.4.0.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2007-2018 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://oss.oracle.com/licenses/CDDL+GPL-1.1
 * or LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

/*
 * FileChooserRenderer.java
 *
 * Created on Jan 11, 2005, 3:40 PM
 */
package com.sun.webui.jsf.renderkit.html;

import com.sun.faces.annotation.Renderer;
import java.io.IOException;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.convert.ConverterException;
import com.sun.webui.jsf.component.Button;
import com.sun.webui.jsf.component.FileChooser;
import com.sun.webui.jsf.component.Icon;
import com.sun.webui.jsf.component.DropDown;
import com.sun.webui.jsf.component.Label;
import com.sun.webui.jsf.component.StaticText;
import com.sun.webui.jsf.component.TextField;
import com.sun.webui.jsf.component.HelpInline;
import com.sun.webui.theme.Theme;
import com.sun.webui.jsf.theme.ThemeImages;
import com.sun.webui.jsf.theme.ThemeStyles;
import com.sun.webui.jsf.util.ThemeUtilities;
import com.sun.webui.jsf.util.JavaScriptUtilities;
import com.sun.webui.jsf.util.RenderingUtilities;
import com.sun.webui.jsf.util.ClientSniffer;
import com.sun.webui.jsf.util.LogUtil;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * 

Renderer for a {@link com.sun.webui.jsf.component.FileChooser} component.

*

* The FileChooser renders the following logical elements to effect * the FileChooser behavoior. *

*
    *
  • An input field to accept and display the current open folder path.
  • *
  • An input field to accept and display a string used to filter the * contents of the current open folder.
  • *
  • An input field to accept and display the files to select.
  • *
  • A list box to display the contents of the current open folder.
  • *
  • A drop down menu of sort options to control the order of the * open folder's contents.
  • *
  • An open folder button to open and display a selected folder in the * list box.
  • *
  • A move up button to navigate and display the currently open folder's * parent folder.
  • *
*

* The expected submitted value is an array of Strings. If there are * selections a request parameter called ":_selections" * where "clientId" is the client id of the FileChooser component * and "id" is the component id of the FileChooser component. *

*/ @Renderer(@Renderer.Renders(componentFamily = "com.sun.webui.jsf.FileChooser")) public class FileChooserRenderer extends AbstractRenderer { private final static boolean DEBUG = false; // the "-" string constant public static final String HYFEN = "-"; //NOI18N /** Creates a new instance of FileChooserRenderer */ public FileChooserRenderer() { } /** *

Decode any new state of the specified UIComponent * from the request contained in the specified FacesContext, * and store that state on the UIComponent.

* *

The default implementation calls setSubmittedValue() * on components that implement EditableValueHolder (i.e. input fields)

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * */ @Override public void decode(FacesContext context, UIComponent component) { if (DEBUG) { log("decode(context, component)"); //NOI18N } if (isDisabled(component) || isReadOnly(component)) { if (DEBUG) { log("component is readonly..."); //NOI18N } return; } if (!(component instanceof FileChooser)) { throw new FacesException("FileChooserRenderer can only " + //NOI18N "render FileChooser components."); //NOI18N } FileChooser chooser = (FileChooser) component; // If the submitted value is not null then the // selectFieldValidator has decodeed the selections and // set the file chooser's submitted value. // All future processing should occur as if the value was // decoded here. // if (chooser.getSubmittedValue() == null) { decodeSubmittedValue(context, chooser); } } /** * The hidden field is encoded with an operation and the * selections separated by "," * * This must be reworked to not depend on an operation * and a delimiter. Use a select element so that named * array can returned in the request. */ private void decodeSubmittedValue(FacesContext context, FileChooser chooser) { // Look for the submitted dynamically created select element. // This will be set for the // // dblclicked - dblclick a file selection in file chooser mode // selectedFileEntered - selectFileField enter pressed // in file mode and folder mode // // These are the selection actions // If not set no selection has been made and effectively // no change, as far as file choosers value. // // Probable want to always create the hidded select element // to reduce dependence on javascript. // String selectionsId = chooser.getClientId(context) + ":" + chooser.getId() + "_selections"; Map requestParameters = context.getExternalContext().getRequestParameterValuesMap(); /* java.util.Set keyset = requestParameters.keySet(); Object[] keys = keyset.toArray(); */ String[] selections = (String[]) requestParameters.get(selectionsId); if (selections != null) { chooser.setSubmittedValue(selections); } else { chooser.setSubmittedValue(null); } } /** * Create a value for the fileChooser component based on the * submitted value, which are the user selections. * The selections may be absolute or relative paths. * The result is an array of objects. * * @return - an object that reflects the value of the fileChooser * component. * */ @Override public java.lang.Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException { // This implementation of getConvertedValue calls back into // the component's getConvertedValue. We do this because // we are also writing the renderer and it is more convenient // and useful to place the real implementation in the // component. However if someone else writes a renderer // they may want to implement it. Therefore the component // will call the renderer's getConveredValue first if // a renderer is configured, which in effect will be a call // back to an overloaded FileChooser.getConvertedValue(). // // public Object getConvertedValue(FacesContext, FileChooser, Object); // if (!(component instanceof FileChooser)) { String msg = "Can only convert values for FileChooser component."; //NOI18N throw new ConverterException(msg); } return ((FileChooser) component).getConvertedValue(context, (FileChooser) component, submittedValue); } /** *

Render the children of the specified UIComponent * to the output stream or writer associated with the response we are * creating.

* *

The default implementation iterates through the children of * this component and renders them.

* * @param context FacesContext for the current request * @param component UIComponent to be decoded * * @exception NullPointerException if context or * component is null * * @exception IOException if an input/output error occurs */ // We shouldn't bother with a default implementation - this is exactly // what happens when you rendersChildren = false. Why duplicate the // code here? @Override public void encodeChildren(FacesContext context, UIComponent component) throws IOException { } /** *

The FileChooser component is responsible for rendering * its own children, they should not be rendered automatically.

* * @return true because this component will render its own * children explicitly. */ @Override public boolean getRendersChildren() { return true; } /* Render the start of the filechooser * * @param context The current FacesContext * @param component The FileChooser object to use * @param writer The current ResponseWriter * * @exception IOException if an input/output error occurss */ @Override protected void renderEnd(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { try { FileChooser chooser = null; if (component instanceof FileChooser) { chooser = (FileChooser) component; } else { String message = "Component " + component.toString() + //NOI18N " has been associated with a FileChooser. " + //NOI18N " This renderer can only be used by components " + //NOI18N " that extend com.sun.webui.jsf.component.FileChooser."; //NOI18N throw new FacesException(message); } if (!chooser.isRendered()) { return; } Theme theme = ThemeUtilities.getTheme(context); // start the div the entire filechooser is wrapped in writer.startElement("div", component); //NOI18N writer.writeAttribute("id", component.getClientId(context), null); String style = chooser.getStyle(); if (style != null) { writer.writeAttribute("style", style, null); //NOI18N } RenderingUtilities.renderStyleClass(context, writer, component, null); writer.writeText("\n", null); //NOI18N // render title in a table renderChooserTitle(context, chooser, writer, theme); //NOI18N // render file chooser in a div writer.startElement("div", component); //NOI18N writer.writeAttribute("class", //NOI18N theme.getStyleClass(ThemeStyles.FILECHOOSER_CONMGN), null); writer.writeText("\n", null); //NOI18N writer.startElement("table", chooser); //NOI18N writer.writeAttribute("border", "0", "border"); //NOI18N writer.writeAttribute("cellpadding", "0", "cellpadding"); //NOI18N writer.writeAttribute("cellspacing", "0", "cellspacing"); //NOI18N writer.writeAttribute("title", " ", "title"); //NOI18N writer.writeText("\n", null); writer.startElement("tr", chooser); // NOI18N writer.startElement("td", chooser); // NOI18N // check if facets are available and if not add a default one. // renderEmptyLine(context, chooser, writer, null, 1, 20, theme); //NOI18N renderServerName(context, chooser, writer, theme); //NOI18N renderClearDiv(context, chooser, writer, theme); renderLookinTextField(context, chooser, writer, theme); renderClearDiv(context, chooser, writer, theme); renderFilterField(context, chooser, writer, theme); renderClearDiv(context, chooser, writer, theme); String helpMessage = theme.getMessage("filechooser.enterKeyHelp"); //NOI18N renderInlineHelp(context, chooser, writer, helpMessage, theme); //NOI18N renderClearDiv(context, chooser, writer, theme); writer.endElement("td"); writer.endElement("tr"); writer.writeText("\n", null); writer.startElement("tr", chooser); writer.startElement("td", chooser); writer.startElement("hr", chooser); writer.writeAttribute("color", "#98a0a5", null); writer.writeAttribute("size", "1", null); writer.endElement("hr"); writer.endElement("td"); writer.endElement("tr"); writer.writeText("\n", null); writer.startElement("tr", chooser); writer.startElement("td", chooser); renderButtons(context, chooser, writer, theme); //NOI18N renderSortFields(context, chooser, writer, theme); //NOI18N writer.endElement("td"); writer.endElement("tr"); writer.writeText("\n", null); writer.startElement("tr", chooser); writer.startElement("td", chooser); writer.startElement("div", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LST_HDR), null); writer.startElement("div", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_NAME_HDR), null); writer.write(theme.getMessage("filechooser.name_column_header")); writer.endElement("div"); writer.writeText("\n", null); writer.startElement("div", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_SIZE_HDR), null); writer.write(theme.getMessage("filechooser.size_column_header")); writer.endElement("div"); writer.writeText("\n", null); writer.startElement("div", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_DATE_TIME_HDR), null); writer.write(theme.getMessage("filechooser.date_time_column_header")); writer.endElement("div"); writer.writeText("\n", null); writer.endElement("div"); writer.endElement("td"); writer.endElement("tr"); writer.writeText("\n", null); writer.startElement("tr", chooser); //NOI18N writer.startElement("td", chooser); //NOI18N renderFileList(context, chooser, writer, theme); writer.endElement("td"); //NOI18N writer.endElement("tr"); //NOI18N renderMultiSelectHelp(context, chooser, writer, theme); writer.startElement("tr", chooser); //NOI18N writer.startElement("td", chooser); //NOI18N writer.writeText("\n", null); renderSelectText(context, chooser, writer, theme); writer.endElement("td"); //NOI18N writer.endElement("tr"); //NOI18N writer.writeText("\n", null); writer.startElement("tr", chooser); //NOI18N writer.startElement("td", chooser); //NOI18N writer.startElement("hr", chooser); //NOI18N writer.writeAttribute("color", "#98a0a5", null); writer.writeAttribute("size", "1", null); writer.endElement("hr"); //NOI18N writer.endElement("td"); //NOI18N writer.endElement("tr"); //NOI18N writer.writeText("\n", null); writer.endElement("table"); //NOI18N writer.endElement("div"); //NOI18N writer.endElement("div"); //NOI18N // end of filechooser layout, now add the two hidden fields. String hiddenID = chooser.getClientId(context) + ":" + chooser.getId() + FileChooser.FILECHOOSER_HIDDENFIELD_ID; writer.startElement("input", chooser); writer.writeAttribute("id", hiddenID, null); //NOI18N writer.writeAttribute("name", hiddenID, null); //NOI18N writer.writeAttribute("type", "hidden", null); //NOI18N writer.writeAttribute("value", "NOACTION", null); //NOI18N writer.endElement("input"); Button hiddenButton = (Button) chooser.getHiddenFCButton(); hiddenButton.setStyleClass(theme.getStyleClass(ThemeStyles.HIDDEN)); RenderingUtilities.renderComponent(hiddenButton, context); // Render a hidden select to hold the currently selected // values. // Not sure if this really needs to done. // No change should be indicated by no submitted value // or if the selected file field contains exactly what it // did when it was rendered. // //renderSelectedSelections(context, chooser, writer, theme); // This may be useful at some point. // I was going to use this to detect entries that // where typed into the selected file field. // It would be a way to determine if an entry // was a full path. The problem is that you can't // detect when the file chooser is actually submitted // since the submit may have occured from an element // outside the file chooser. Then only way to do this // then would be onchange events and key press events // on the selected file field. // //renderRoots(context, chooser, writer, theme); renderJavaScript(chooser, context, writer, theme); } catch (Exception e) { throw new FacesException("Filechooser throws exception while" + "rendering: " + e.getMessage()); } } private void renderSelectedSelections(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { writer.startElement("select", chooser); //NOI18N String id = chooser.getClientId(context) + ":" + //NOI18N chooser.getId() + "_selections"; //NOI18N writer.writeAttribute("id", id, null); //NOI18N writer.writeAttribute("name", id, null); //NOI18N writer.writeAttribute("style", "{display:none}", null); //NOI18N writer.writeAttribute("multiple", "multiple", null); //NOI18N // If this select is going to hold the current selections // need to get conversion hooked up to convert from the // app's type writer.endElement("select"); //NOI18N } // Render the possible roots. // private void renderRoots(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { String[] roots = chooser.getRoots(); writer.startElement("select", chooser); //NOI18N String id = chooser.getClientId(context) + ":" + //NOI18N chooser.getId() + "_roots"; //NOI18N writer.writeAttribute("id", id, null); //NOI18N writer.writeAttribute("name", id, null); //NOI18N writer.writeAttribute("style", "{display:none}", null); //NOI18N writer.writeAttribute("multiple", "multiple", null); //NOI18N for (int i = 0; i < roots.length; ++i) { writer.startElement("option", chooser); //NOI18N writer.writeAttribute("value", roots[i], null); //NOI18N writer.endElement("option"); //NOI18N } // If this select is going to hold the current selections // need to get conversion hooked up to convert from the // app's type writer.endElement("select"); //NOI18N } /** * This method appends the servername from where the files are being * listed to the filechooser layout. */ protected void renderServerName(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { UIOutput uio = (UIOutput) chooser.getServerNameText(); Label label = (Label) chooser.getServerNameLabel(); // If either not rendered, render neither. if (!uio.isRendered() || !label.isRendered()) { return; } writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_SRV_DIV), null); // Render server name label writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LEV2_DIV), null); RenderingUtilities.renderComponent(label, context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N // Render server name text RenderingUtilities.renderComponent(uio, context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the fileChooser label. */ protected void renderChooserTitle(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { // Append alert icon html. try { StaticText title = (StaticText) chooser.getFileChooserTitle(); if (!title.isRendered()) { return; } writer.startElement("table", chooser); //NOI18N writer.writeAttribute("width", "100%", "width"); //NOI18N writer.writeAttribute("border", "0", "border"); //NOI18N writer.writeAttribute("cellpadding", "0", "cellpadding"); //NOI18N writer.writeAttribute("cellspacing", "0", "cellspacing"); //NOI18N writer.writeAttribute("title", "", "title"); //NOI18N writer.startElement("tr", chooser); //NOI18N writer.writeAttribute("valign", "bottom", "valign"); //NOI18N writer.startElement("td", chooser); //NOI18N writer.writeAttribute("valign", "bottom", "valign"); //NOI18N writer.startElement("div", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.TITLE_TEXT_DIV), "class"); writer.startElement("h1", chooser); writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.TITLE_TEXT), "class"); RenderingUtilities.renderComponent(title, context); writer.endElement("h1"); //NOI18N writer.endElement("div"); //NOI18N writer.endElement("td"); //NOI18N writer.endElement("tr"); //NOI18N writer.endElement("table"); writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders help message in small font to * the filechooser layout. */ protected void renderInlineHelp(FacesContext context, FileChooser chooser, ResponseWriter writer, String messageKey, Theme theme) throws Exception { try { UIComponent help = chooser.getEnterInlineHelp(); writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_FLT_HLP_DIV), null); if (help.isRendered()) { RenderingUtilities.renderComponent(help, context); } writer.writeText("\n", null); //NOI18N writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method appends a help message in small font to * the filechooser layout. */ protected void renderLookinTextField(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { TextField lookinField = (TextField) chooser.getLookInTextField(); if (!lookinField.isRendered()) { return; } writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LOOK_IN_DIV), null); writer.writeText("\n", null); //NOI18N writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LEV2_DIV), null); writer.writeText("\n", null); //NOI18N // render the lookin textfield label RenderingUtilities.renderComponent(chooser.getLookInLabel(), context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N // render the lookin textfield setEnterKeyPressHandler(context, chooser, lookinField); RenderingUtilities.renderComponent(lookinField, context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method appends a help message in small font to * the filechooser layout. */ protected void renderFilterField(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { TextField filterOnField = (TextField) chooser.getFilterTextField(); if (!filterOnField.isRendered()) { return; } writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_FLT_DIV), null); writer.writeText("\n", null); //NOI18N writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LEV2_DIV), null); RenderingUtilities.renderComponent(chooser.getFilterLabel(), context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N // render the lookin textfield setEnterKeyPressHandler(context, chooser, filterOnField); RenderingUtilities.renderComponent(filterOnField, context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the sort field drop down menu * for the filechooser component. */ protected void renderSortFields(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_SORT_BY_DIV), null); writer.writeText("\n", null); //NOI18N Label sortLabel = (Label) chooser.getSortComponentLabel(); DropDown jdd = (DropDown) chooser.getSortComponent(); if (!jdd.isRendered()) { return; } if (sortLabel.isRendered()) { RenderingUtilities.renderComponent(sortLabel, context); } RenderingUtilities.renderComponent(jdd, context); writer.writeText("\n", null); //NOI18N writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the list of files/folders in * a listbox. */ protected void renderFileList(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_LST_DIV), null); UIComponent fileList = chooser.getListComponent(); createJavaScriptForFileList(chooser, context, fileList); setEnterKeyPressHandler(context, chooser, fileList); RenderingUtilities.renderComponent(fileList, context); writer.endElement("div"); //NOI18N writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the multiselect help if supplied */ protected void renderMultiSelectHelp(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { HelpInline help = (HelpInline) chooser.getMultiSelectHelp(); if (help != null && help.isRendered()) { writer.startElement("tr", chooser); //NOI18N writer.startElement("td", chooser); //NOI18N writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_MULT_HLP_DIV), null); RenderingUtilities.renderComponent(help, context); writer.endElement("div"); renderClearDiv(context, chooser, writer, theme); writer.endElement("td"); writer.endElement("tr"); } } catch (Exception e) { throw e; } } /** * This method renders the buttons used to traverse the file/folder * list. */ protected void renderButtons(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_BTN_GRP_DIV), null); /* HelpInline help = (HelpInline)chooser.getMultiSelectHelp(); if (help == null) { writer.write(" "); //NOI18N } else{ if (help.isRendered()) { RenderingUtilities.renderComponent(help, context); } } */ renderUpLevelButton(context, chooser, writer, theme); //NOI18N renderOpenFolderButton(context, chooser, writer, theme); //NOI18N writer.endElement("div"); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the button to traverse the resource list * up one level. */ protected void renderUpLevelButton(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { writer.writeText("\n", null); //NOI18N Button child = (Button) chooser.getUpLevelButton(false); if (!child.isRendered()) { return; } StringBuffer jsBuffer = new StringBuffer(256); jsBuffer.append(JavaScriptUtilities.getDomNode(context, chooser)); jsBuffer.append(".moveUpButtonClicked();"); child.setOnClick(jsBuffer.toString()); RenderingUtilities.renderComponent(child, context); writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the button to open a folder. */ protected void renderOpenFolderButton(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { writer.writeText("\n", null); //NOI18N Button child = (Button) chooser.getOpenFolderButton(); if (!child.isRendered()) { return; } StringBuffer jsBuffer = new StringBuffer(256); jsBuffer.append(JavaScriptUtilities.getDomNode(context, chooser)); jsBuffer.append(".openFolderClicked();"); child.setOnClick(jsBuffer.toString()); RenderingUtilities.renderComponent(child, context); writer.writeText("\n", null); //NOI18N } catch (Exception e) { throw e; } } /** * This method renders the test field which lists the selected * file(s) or folder(s). * It must satisfy the following UI properties: * If a file is selected in the list, display the name of the file * in the Selected File text field. If multiple files are selected, * display all of the files names separated by commas. Do not display * folder names in the Selected File text field. Replace existing text * in the Selected File text field only when the user selects a new * file name from the list or types a new file name. No other action * should replace existing text in the Selected File text field. * * Allow the user to specify a new path in the Selected File text * field. After the user enters the new path and hits enter, update * the list and the Look In text field to reflect the new path. If a * user types a path that begins with '/' or '\', take that as the * full path name. Otherwise, append what the user types to the path * in the Look In text field. * * Allow the user to specify a file name in the Selected File text * field by typing a full path, or without a path if the file is * contained in the current Look In folder. Once the user types in a * valid file name and presses the Enter key, the window should react * appropriately: pop-up windows should close and return the file name * to the application while inline file choosers should return the file * name, clear the Selected file text field, and either close or await * additional user input at the application designer's discretion. * If the file chooser is in a pop-up window, set the keyboard focus * inside the Selected File text field when the pop-up window * initially comes up. * */ protected void renderSelectText(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) throws Exception { try { TextField selectedTextField = (TextField) chooser.getSelectedTextField(); if (!selectedTextField.isRendered()) { return; } writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_SEL_FILE_DIV), null); writer.writeText("\n", null); //NOI18N writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.FILECHOOSER_SEL_FILE_LEV2_DIV), null); RenderingUtilities.renderComponent(chooser.getSelectLabel(), context); writer.endElement("div"); //NOI18N setEnterKeyPressHandler(context, chooser, selectedTextField); RenderingUtilities.renderComponent(selectedTextField, context); writer.endElement("div"); //NOI18N renderClearDiv(context, chooser, writer, theme); //NOI18N } catch (Exception e) { throw e; } } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private methods // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * This method renders JavaScript to initialize dom node. */ private void renderJavaScript(FileChooser chooser, FacesContext context, ResponseWriter writer, Theme theme) throws IOException { // boolean folderChooser = chooser.isFolderChooser(); String chooserType = null; if (chooser.isFolderChooser()) { chooserType = "folderChooser"; } else if (chooser.isFileAndFolderChooser()) { chooserType = "fileAndFolderChooser"; } else { chooserType = "fileChooser"; } // Arguments are // The client id // The chooser mode, folder chooser "true", file chooser "false" // The move up dir or the parent directory of the displayed // directory. This may be the same as the current directory. // The escape char, the string to use to escape the delimiter when // it appears in a file name. // The delimiter, the string to use to separate entries in // the selected file field. // Need to escape the escapeChar // There are other possible issue characters like "'" // and '"' but let's not deal with that now. // String esc = chooser.getEscapeChar(); if (esc.equals("\\")) { //NOI18N esc = "\\\\"; //NOI18N } // getParentFolder can return null. // If null is returned, use getCurrentFolder(). // FileChooserModel.getCurrentDir no longer returns null. // and will return the the root directory. // String parentDir = chooser.getParentFolder(); String currentFolder = chooser.getCurrentFolder(); if (parentDir == null) { parentDir = currentFolder; } // If parentDir is still null, set it to empty string. // probably not FileChooserModel. // String sep = chooser.getSeparatorString(); if (parentDir == null) { parentDir = ""; } else { // Need to escape separator String // if (sep.equals("\\")) { //NOI18N sep = sep + sep; parentDir = parentDir.replaceAll(sep, sep + sep); } } sep = chooser.getSeparatorString(); if (currentFolder == null) { currentFolder = ""; } else { // Need to escape separator String // if (sep.equals("\\")) { //NOI18N sep = sep + sep; currentFolder = currentFolder.replaceAll(sep, sep + sep); } } try { // Append properties. String id = chooser.getClientId(context); StringBuffer buff = new StringBuffer(256); JSONObject json = new JSONObject(); json.put("id", id).put("chooserType", chooserType).put("parentFolder", parentDir).put("separatorChar", sep).put("escapeChar", esc).put("delimiter", chooser.getDelimiterChar()).put("currentFolder", currentFolder); // Append JavaScript. buff.append(JavaScriptUtilities.getModule("fileChooser")).append("\n") // NOI18N .append(JavaScriptUtilities.getModuleName("fileChooser.init")) // NOI18N .append("(") //NOI18N .append(json.toString(JavaScriptUtilities.INDENT_FACTOR)).append(");"); //NOI18N // Render JavaScript. JavaScriptUtilities.renderJavaScript(chooser, writer, buff.toString()); } catch (JSONException e) { e.printStackTrace(); } } /** * Create the javascript for file list to handle onchange */ private void createJavaScriptForFileList(FileChooser chooser, FacesContext context, UIComponent fileList) { String jsObject = JavaScriptUtilities.getDomNode(context, chooser); // generate the JavaScript that will disable DBL clicks // on files in a folderchooser. StringBuffer dblClickBuffer = new StringBuffer(256); dblClickBuffer.append(jsObject); dblClickBuffer.append(".handleDblClick();"); //NOI18N fileList.getAttributes().put("onDblClick", dblClickBuffer.toString()); //NOI18N // The user gets to choose the child name, label, tooltip for // the control button that is placed at the bottom of the // filechooser tag. The following few lines of code disables // this button based on certain conditions. For example, the // button would be disabled if the user selects a file but // the choose button is meant to choose a folder. // The following code disabled the open folder button // based on the following situations: // a) user selects more than one from the list of files/folders // b) user selects a file // c) user does not select anything // This javascript also performs the following additional // function. Add the file/folder to the selected file/folder // textfield if its of the appropriate type and has been selected. StringBuffer jsBuffer = new StringBuffer(256); jsBuffer.append(jsObject); jsBuffer.append(".handleOnChange();"); //NOI18N fileList.getAttributes().put("onChange", jsBuffer.toString()); //NOI18N } /** * This method returns the string of size maxLen by padding the * appropriate amount of spaces next to str. */ private void setEnterKeyPressHandler(FacesContext context, FileChooser chooser, UIComponent child) { StringBuffer scriptBuffer = new StringBuffer(); scriptBuffer.append("return "); //NOI18N scriptBuffer.append(JavaScriptUtilities.getDomNode(context, chooser)); scriptBuffer.append(".enterKeyPressed(this);"); //NOI18N String js = getReturnKeyJavascriptWrapper(scriptBuffer.toString()); scriptBuffer.setLength(0); scriptBuffer.append(js); child.getAttributes().put("onKeyPress", scriptBuffer.toString()); } /** * Return the HTML equivalent of a single table row of empty space. */ private void renderEmptyLine(FacesContext context, FileChooser chooser, ResponseWriter writer, String colSpan, int wd, int ht, Theme theme) { try { writer.startElement("tr", chooser); //NOI18N renderDotImage(writer, chooser, context, colSpan, wd, ht, theme); writer.endElement("tr"); //NOI18N writer.writeText("\n", null); } catch (Exception e) { e.printStackTrace(); } } /** * Return the HTML equivalent of a single table row of empty space. */ private void renderClearDiv(FacesContext context, FileChooser chooser, ResponseWriter writer, Theme theme) { try { writer.startElement("div", chooser); //NOI18N writer.writeAttribute("class", theme.getStyleClass(ThemeStyles.CLEAR), null); writer.endElement("div"); //NOI18N writer.writeText("\n", null); } catch (Exception e) { e.printStackTrace(); } } /** * Return the HTML equivalent of a single table data of empty space. */ private void renderDotImage(ResponseWriter writer, FileChooser chooser, FacesContext context, String colSpan, int wd, int ht, Theme theme) { try { writer.startElement("td", chooser); //NOI18N if (colSpan != null) { writer.writeAttribute("colspan", colSpan, null); //NOI18N } Icon dot = ThemeUtilities.getIcon(theme, ThemeImages.DOT); dot.setWidth(wd); dot.setHeight(ht); dot.setBorder(0); dot.setAlt(""); RenderingUtilities.renderComponent(dot, context); // close the td tag writer.endElement("td"); //NOI18N writer.writeText("\n", null); } catch (Exception e) { e.printStackTrace(); } } /** * Log an error - only used during development time. */ void log(String s) { if (LogUtil.fineEnabled(FileChooserRenderer.class)) { LogUtil.fine(FileChooserRenderer.class, s); } } /** * Helper method to get Javascript to submit the "go" button when the user * clicks enter in the page field. * * @return The Javascript used to submit the "go" button. */ private String getReturnKeyJavascriptWrapper(String body) { ClientSniffer cs = ClientSniffer.getInstance(getFacesContext()); // Get key code. String keyCode = cs.isNav() ? "event.which" : "event.keyCode"; //NOI18N // Append JS to capture the event. StringBuffer buff = new StringBuffer(128).append("if (") //NOI18N .append(keyCode).append("==13) {"); //NOI18N // To prevent an auto-submit, Netscape 6.x and netscape 7.0 require // setting the cancelBubble property. However, Netscape 7.1, // Mozilla 1.x, IE 5.x for SunOS/Windows do not use this property. if (cs.isNav6() || cs.isNav70()) { buff.append("event.cancelBubble = true;"); //NOI18N } buff.append(body).append("} else { return true; }"); //NOI18N return buff.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy