/* * JBoss, Home of Professional Open Source * Copyright 2010-2016, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.richfaces.tests.metamer.bean; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.PostConstruct; import javax.el.ELContext; import javax.el.ExpressionFactory; import javax.el.ValueExpression; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import javax.faces.event.AjaxBehaviorEvent; import javax.faces.event.ValueChangeEvent; import javax.faces.model.SelectItem; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.richfaces.event.ItemChangeEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; /** * Managed bean storing glogal setting for the application, e.g. skin. * * @author <a href="mailto:ppitonak@redhat.com">Pavol Pitonak</a> */ @ManagedBean @SessionScoped public class RichBean implements Serializable { private static final Logger logger = LoggerFactory.getLogger(RichBean.class); private static final long serialVersionUID = 5590865106686406193L; private String activeTabOnIndex = "a4j"; private Map<String, String> allComponentsPermanentList; private String component; private String componentFormEnctype; private List<SelectItem> componentFormEnctypes; private String container; private int delay; private boolean dummyBooleanResp; private Map<String, String> filteredComponents; private boolean log; private boolean reComponent; private boolean reDefault; private boolean reTests; private String selectedComponent; private String skin; private Skinning skinning; private List<SelectItem> skinningList; private List<String> skins; private boolean stateless; private boolean uiDebugEnabled; public static void logToPage(String msg) { FacesContext ctx = FacesContext.getCurrentInstance(); ExpressionFactory factory = ctx.getApplication().getExpressionFactory(); ELContext elContext = ctx.getELContext(); ValueExpression exp = factory.createValueExpression(elContext, "#{phasesBean.phases}", List.class); List<String> phases = (List<String>) exp.getValue(elContext); phases.add(msg); } private static Map<String, String> sortComponents(Map<String, String> map) { Map<String, String> result; ArrayList<Map.Entry<String, String>> entries = Lists.newArrayList(map.entrySet()); Collections.sort(entries, new Comparator<Map.Entry<String, String>>() { @Override public int compare(Map.Entry<String, String> a, Map.Entry<String, String> b) { return a.getValue().compareTo(b.getValue()); } }); result = new LinkedHashMap<String, String>(); for (Map.Entry<String, String> entry : entries) { result.put(entry.getKey(), entry.getValue()); } return result; } /** * An action listener that does nothing. * * @param event an event representing the activation of a user interface component (not used) */ public void actionListener(AjaxBehaviorEvent event) { logToPage("* action listener invoked"); } /** * An action listener that does nothing. * * @param event an event representing the activation of a user interface component (not used) */ public void actionListener2(AjaxBehaviorEvent event) { logToPage("* action listener *2 invoked"); } public void causeAjaxErrorAction() { sendErrorResponse(); } public void causeAjaxErrorActionListener(ActionEvent event) { sendErrorResponse(); } public void causeAjaxErrorListener(AjaxBehaviorEvent event) { sendErrorResponse(); } public void causeAjaxErrorValueChangeListener(ValueChangeEvent event) { sendErrorResponse(); } /** * A change event listener that logs to the page old and new value. This is 2nd ValueChacgeListener. Use 2 different * listeners is useful when testing more than one listener definition for one component * * @param event an event representing the activation of a user interface component */ public void changeEventListener(AjaxBehaviorEvent event) { logToPage("* 2 value changed "); } private void createComponentsMap() { filteredComponents = new LinkedHashMap<String, String>(90); allComponentsPermanentList = new LinkedHashMap<String, String>(90); allComponentsPermanentList.put("a4jActionListener", "A4J Action Listener"); allComponentsPermanentList.put("a4jAjax", "A4J Ajax"); allComponentsPermanentList.put("a4jAttachQueue", "A4J Attach Queue"); allComponentsPermanentList.put("a4jCommandLink", "A4J Command Link"); allComponentsPermanentList.put("a4jCommandButton", "A4J Command Button"); allComponentsPermanentList.put("a4jJSFunction", "A4J JavaScript Function"); allComponentsPermanentList.put("a4jLog", "A4J Log"); allComponentsPermanentList.put("a4jMediaOutput", "A4J Media Output"); allComponentsPermanentList.put("a4jOutputPanel", "A4J Output Panel"); allComponentsPermanentList.put("a4jParam", "A4J Action Parameter"); allComponentsPermanentList.put("a4jPoll", "A4J Poll"); allComponentsPermanentList.put("a4jPush", "A4J Push"); allComponentsPermanentList.put("a4jQueue", "A4J Queue"); allComponentsPermanentList.put("a4jRegion", "A4J Region"); allComponentsPermanentList.put("a4jRepeat", "A4J Repeat"); allComponentsPermanentList.put("a4jStatus", "A4J Status"); allComponentsPermanentList.put("richAccordion", "Rich Accordion"); allComponentsPermanentList.put("richAccordionItem", "Rich Accordion Item"); allComponentsPermanentList.put("richAutocomplete", "Rich Autocomplete"); allComponentsPermanentList.put("richCalendar", "Rich Calendar"); allComponentsPermanentList.put("richChart", "Rich Chart"); allComponentsPermanentList.put("richCollapsiblePanel", "Rich Collapsible Panel"); allComponentsPermanentList.put("richCollapsibleSubTable", "Rich Collapsible Sub Table"); allComponentsPermanentList.put("richCollapsibleSubTableToggler", "Rich Collapsible Sub Table Toggler"); allComponentsPermanentList.put("richColumn", "Rich Column"); allComponentsPermanentList.put("richColumnGroup", "Rich Column Group"); allComponentsPermanentList.put("richComponentControl", "Rich Component Control"); allComponentsPermanentList.put("richContextMenu", "Rich Context Menu"); allComponentsPermanentList.put("richDataGrid", "Rich Data Grid"); allComponentsPermanentList.put("richDataScroller", "Rich Data Scroller"); allComponentsPermanentList.put("richDataTable", "Rich Data Table"); allComponentsPermanentList.put("richDragSource", "Rich Drag Source"); allComponentsPermanentList.put("richDragIndicator", "Rich Drag Indicator"); allComponentsPermanentList.put("richDropTarget", "Rich Drop Target"); allComponentsPermanentList.put("richDropDownMenu", "Rich Drop Down Menu"); allComponentsPermanentList.put("richEditor", "Rich Editor"); allComponentsPermanentList.put("richExtendedDataTable", "Rich Extended Data Table"); allComponentsPermanentList.put("richFileUpload", "Rich File Upload"); allComponentsPermanentList.put("richFocus", "Rich Focus"); allComponentsPermanentList.put("richFunctions", "Rich Functions"); allComponentsPermanentList.put("richGraphValidator", "Rich Graph Validator"); allComponentsPermanentList.put("richHashParam", "Rich Hash Parameter"); allComponentsPermanentList.put("richHotKey", "Rich Hot Key"); allComponentsPermanentList.put("richInplaceInput", "Rich Inplace Input"); allComponentsPermanentList.put("richInplaceSelect", "Rich Inplace Select"); allComponentsPermanentList.put("richItemChangeListener", "Rich Item Change Listener"); allComponentsPermanentList.put("richInputNumberSlider", "Rich Input Number Slider"); allComponentsPermanentList.put("richInputNumberSpinner", "Rich Input Number Spinner"); allComponentsPermanentList.put("richJQuery", "Rich jQuery"); allComponentsPermanentList.put("richList", "Rich List"); allComponentsPermanentList.put("richMenuGroup", "Rich Menu Group"); allComponentsPermanentList.put("richMenuItem", "Rich Menu Item"); allComponentsPermanentList.put("richMenuSeparator", "Rich Menu Separator"); allComponentsPermanentList.put("richMessage", "Rich Message"); allComponentsPermanentList.put("richMessages", "Rich Messages"); allComponentsPermanentList.put("richNotify", "Rich Notify"); allComponentsPermanentList.put("richNotifyMessage", "Rich Notify Message"); allComponentsPermanentList.put("richNotifyMessages", "Rich Notify Messages"); allComponentsPermanentList.put("richNotifyStack", "Rich Notify Stack"); allComponentsPermanentList.put("richOrderingList", "Rich Ordering List"); allComponentsPermanentList.put("richPanel", "Rich Panel"); allComponentsPermanentList.put("richPanelMenu", "Rich Panel Menu"); allComponentsPermanentList.put("richPanelMenuGroup", "Rich Panel Menu Group"); allComponentsPermanentList.put("richPanelMenuItem", "Rich Panel Menu Item"); allComponentsPermanentList.put("richPanelToggleListener", "Rich Panel Toggle Listener"); allComponentsPermanentList.put("richPickList", "Rich Pick List"); allComponentsPermanentList.put("richPlaceholder", "Rich Placeholder"); allComponentsPermanentList.put("richPopupPanel", "Rich Popup Panel"); allComponentsPermanentList.put("richProgressBar", "Rich Progress Bar"); allComponentsPermanentList.put("richSelect", "Rich Select"); allComponentsPermanentList.put("richTab", "Rich Tab"); allComponentsPermanentList.put("richTabPanel", "Rich Tab Panel"); allComponentsPermanentList.put("richToggleControl", "Rich Toggle Control"); allComponentsPermanentList.put("richTogglePanel", "Rich Toggle Panel"); allComponentsPermanentList.put("richTogglePanelItem", "Rich Toggle Panel Item"); allComponentsPermanentList.put("richToolbar", "Rich Toolbar"); allComponentsPermanentList.put("richToolbarGroup", "Rich Toolbar Group"); allComponentsPermanentList.put("richTooltip", "Rich Tooltip"); allComponentsPermanentList.put("richTree", "Rich Tree"); allComponentsPermanentList.put("richTreeSelectionChangeListener", "Rich Tree Selection Change Listener"); allComponentsPermanentList.put("richTreeToggleListener", "Rich Tree Toggle Listener"); allComponentsPermanentList.put("richValidator", "Rich Validator"); allComponentsPermanentList = sortComponents(allComponentsPermanentList); allComponentsPermanentList.put("expressionLanguage", "Expression Language"); allComponentsPermanentList.put("commandButton", "JSF Command Button"); allComponentsPermanentList.put("hDataTable", "JSF Data Table"); allComponentsPermanentList.put("jsfReproducers", "JSF Issues Reproducers"); allComponentsPermanentList.put("skinning", "Skinning"); allComponentsPermanentList.put("uiRepeat", "UI Repeat"); allComponentsPermanentList.put("myComponent", "My sample component samples"); filteredComponents.putAll(allComponentsPermanentList); } private void createSkinList() { skins = new ArrayList<String>(); skins.add("blueSky"); skins.add("classic"); skins.add("deepMarine"); skins.add("emeraldTown"); skins.add("japanCherry"); skins.add("ruby"); skins.add("wine"); skins.add("plain"); } /** * An action that does nothing. * * @return null */ public String dummyAction() { logToPage("* action invoked"); return null; } /** * An action listener that does nothing. * * @param event an event representing the activation of a user interface component (not used) */ public void dummyActionListener(ActionEvent event) { logToPage("* action listener invoked"); } /** * An action that does nothing but has delay * * @return null */ public String dummyActionWithDelay() { logToPage("* action invoked [start]"); try { Thread.sleep(3000); } catch (InterruptedException e) { logToPage(" *** Error while dummy action handler sleeps."); } logToPage("* action invoked [end]"); dummyBooleanResp = !dummyBooleanResp; return null; } /** * An action that just logs message to the page. */ public void dummyListener(AjaxBehaviorEvent event) { RichBean.logToPage("* listener invoked"); // force phasesPanel to render FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add("phasesPanel"); } private void filterComponents() { // reset all displayed components this.filteredComponents.clear(); // if filter is not set up then put all components in it. if (selectedComponent == null || selectedComponent.trim().isEmpty()) { filteredComponents.putAll(allComponentsPermanentList); } else { String valueToFind = selectedComponent.toLowerCase(); filteredComponents.putAll(findRelevantComponents(valueToFind, allComponentsPermanentList)); } } /** * This method create Map of components to display. If input parameter searchString match in value of any component from * map, then add this component to new map. * * @param searchString patter to find. if null then empty map is returned. * @param map of all components. If null then empty map is returned. * @return Map of components with string key and string value which value match with patter in searchString. */ private Map<String, String> findRelevantComponents(String searchString, Map<String, String> map) { Map<String, String> result = new TreeMap<String, String>(); if (searchString != null && map != null) { for (String key : map.keySet()) { String value = map.get(key); Pattern patter = Pattern.compile(searchString); Matcher matcher = patter.matcher(value.toLowerCase()); if (matcher.find()) { result.put(key, value); } } } return result; } public String getActiveTabOnIndex() { return activeTabOnIndex; } public String getComponent() { return component; } public String getComponentFormEnctype() { return componentFormEnctype; } public List<SelectItem> getComponentFormEnctypes() { return componentFormEnctypes; } public String getContainer() { return container; } public int getDelay() { return delay; } public boolean getDummyBooleanResp() { return dummyBooleanResp; } public boolean getExecuteChecker() { return true; } public Map<String, String> getFilteredComponents() { return filteredComponents; } public Object[] getFilteredComponentsList() { return filteredComponents.keySet().toArray(); } public String getSelectedComponent() { return selectedComponent; } /** * Getter for user's skin. * * @return a RichFaces skin */ public String getSkin() { return skin; } public String getSkinning() { if (skinning == Skinning.SKINNING) { return "enabled"; } else { return "disabled"; } } public String getSkinningClasses() { if (skinning == Skinning.SKINNING_CLASSES) { return "enabled"; } else { return "disabled"; } } public List<SelectItem> getSkinningList() { return skinningList; } public List<String> getSkins() { return skins; } public String getTestsPage() { if (component.equals("none")) { return "/blank.xhtml"; } else { return String.format("/components/%s/tests.xhtml", component); } } @PostConstruct public void init() { logger.debug("initializing bean " + getClass().getName()); createSkinList(); createComponentsMap(); component = "none"; container = "plain"; skin = "blueSky"; skinningList = new ArrayList<SelectItem>(); skinningList.add(new SelectItem(Skinning.NONE)); skinningList.add(new SelectItem(Skinning.SKINNING)); skinningList.add(new SelectItem(Skinning.SKINNING_CLASSES)); skinning = Skinning.SKINNING; reTests = false; reComponent = true; uiDebugEnabled = false; this.stateless = Boolean.valueOf(System.getProperty("statelessViews", "false")); this.delay = 0; componentFormEnctypes = Lists.newArrayList( new SelectItem("application/x-www-form-urlencoded", "default"), new SelectItem("multipart/form-data", "multipart")); componentFormEnctype = componentFormEnctypes.get(0).getValue().toString(); } public String invalidateSession() { ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); Object session = ec.getSession(false); if (session == null) { return "/index"; } if (session instanceof HttpSession) { ((HttpSession) session).invalidate(); return FacesContext.getCurrentInstance().getViewRoot().getViewId(); } throw new IllegalStateException(); } public boolean isLog() { return log; } public boolean isReDefault() { return reDefault; } public boolean isStateless() { return stateless; } public boolean isUiDebugEnabled() { return uiDebugEnabled; } /** * An item change listener that logs to the page old and new value. * * @param event an event representing the activation of a user interface component */ public void itemChangeListener(ItemChangeEvent event) { logToPage("* 1 item changed: " + (event.getOldItem() == null ? null : event.getOldItem().getId()) + " -> " + (event.getNewItem() != null ? event.getNewItem().getId() : null)); } private void sendErrorResponse() { FacesContext context = FacesContext.getCurrentInstance(); HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); try { response.sendError(501, "Intentional error"); // complete the response to prevent throwing of IllegalStateException (response already committed) context.responseComplete(); } catch (IOException ex) { logger.error("Was not able to send error response.", ex); } } public void setActiveTabOnIndex(String activeTabOnIndex) { this.activeTabOnIndex = activeTabOnIndex; } public void setComponent(String component) { this.component = component; } public void setComponentFormEnctype(String componentFormEnctype) { this.componentFormEnctype = componentFormEnctype; } public void setContainer(String container) { this.container = container; } public void setDelay(int delay) { this.delay = delay; } public void setDummyBooleanResp(boolean dummyBooleanResp) { this.dummyBooleanResp = dummyBooleanResp; } public void setExecuteChecker(boolean executeChecker) { logToPage("* executeChecker"); } public void setFilteredComponents(Map<String, String> allComponents) { this.filteredComponents = allComponents; } public void setLog(boolean log) { this.log = log; } public void setReComponent(boolean reComponent) { this.reComponent = reComponent; } public void setReDefault(boolean reDefault) { this.reDefault = reDefault; } public void setReTests(boolean reTests) { this.reTests = reTests; } public void setSelectedComponent(String selectedComponent) { this.selectedComponent = selectedComponent; filterComponents(); } /** * Setter for user's skin. * * @param skin a RichFaces skin */ public void setSkin(String skin) { this.skin = skin; } public void setSkinning(String skinning) { this.skinning = Skinning.valueOf(skinning); } public void setSkinningClasses(String skinningClasses) { this.skinning = Skinning.valueOf(skinningClasses); } public void setSkins(List<String> skins) { this.skins = skins; } public void setStateless(boolean stateless) { this.stateless = stateless; } public void setUiDebugEnabled(boolean uiDebugEnabled) { this.uiDebugEnabled = uiDebugEnabled; } /** * A value change listener that logs to the page old and new value. * * @param event an event representing the activation of a user interface component */ public void valueChangeListener(ValueChangeEvent event) { logToPage("* 1 value changed: " + event.getOldValue() + " -> " + event.getNewValue()); } /** * A value change listener that logs to the page old and new value. But if event value was longer that 20 chars, only first * 20 chars will be logged * * @param event an event representing the activation of a user interface component */ public void valueChangeListenerImproved(ValueChangeEvent event) { String oldVal = event.getOldValue() != null ? event.getOldValue().toString() : null; String newVal = event.getNewValue() != null ? event.getNewValue().toString() : null; // need to escape these values before logging to the page as it can contain e.g. \r \n if (oldVal != null) { oldVal = oldVal.replace("\r", "").replace("\n", ""); } if (newVal != null) { newVal = newVal.replace("\r", "").replace("\n", ""); } logToPage("* 3 value changed: " + (oldVal != null && oldVal.length() > 21 ? oldVal.substring(0, 20) : oldVal != null ? oldVal : "null") + " -> " + (newVal != null && newVal.length() > 21 ? newVal.substring(0, 20) : newVal != null ? newVal : "null")); } public enum Skinning { NONE, SKINNING, SKINNING_CLASSES } }