/** * Copyright (C) 2011 JTalks.org Team * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jtalks.poulpe.web.controller; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.Nonnull; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.zkoss.util.resource.Labels; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Path; import org.zkoss.zk.ui.select.Selectors; import org.zkoss.zk.ui.util.ConventionWires; /** * Helper class for zk-based view objects - mainly for easing the testing. It encapsulates static method calls and * methods inherited from zk classes. <br> * <br> * * Helps with:<br> * <ul> * * <li>Initializing components and wiring its variables to actual ui components ({@link #wireByConvention()} and * {@link #wireToZul(String)}</li> * * <li>Managing child objects via {@link #addComponent(Component)} and the like</li> * * </ul> * * @author Alexey Grigorev */ public class ZkHelper { private final Component component; /** * Creates a helper with a component to work with. * * @param component the component this helper will be working with */ public ZkHelper(@Nonnull Component component) { this.component = component; } /** * Wires zk objects to their ui representation for events handling.<br> * Adds forward conditions to myid source component so onXxx source event received by myid component can be * forwarded to the specified target component with the target event name onXxx$myid. */ public void wireByConvention() { ConventionWires.wireVariables(component, component); ConventionWires.addForwards(component, component); } /** * Wires view to zul file * * @param zul file to be wired to * @return created component */ public Component wireToZul(String zul) { return Executions.createComponents(zul, component, null); } /** * Wire components to controller. * * @param component the reference component for selector * @param controller the controller object to be injected with variables */ public void wireComponents(Component component, Object controller) { Selectors.wireComponents(component, controller, false); } /** * Removes all children of the given class * * @param cls elements of which are to be removed */ public <E extends Component> void removeAll(Class<E> cls) { List<Component> childrenToSave = filterOut(cls); removeAllChildComponents(); addComponents(childrenToSave); } /** * Returns the first component that match the selector. * * @param selector the selector string * @return component matching the selector */ public Component findComponent(String selector) { List<Component> comps = Selectors.find(component, selector); if (comps.size() > 0){ return comps.get(0); } return null; } /** * Find the component by id. * * @param id component's Id * @return found component or null */ public Component getCurrentComponent(String id) { for (Component c : Executions.getCurrent().getDesktop().getComponents()) { if (c.getId().equals(id)) { return c; } } return null; } /** * Gets all the elements but none of the given class * * @param classToFilterOut element of which are to be excluded from result * @return list of {@link Component} objects */ private <E extends Component> List<Component> filterOut(Class<E> classToFilterOut) { List<Component> forKeeping = new ArrayList<Component>(); for (Component cmp : component.getChildren()) { if (!classToFilterOut.isInstance(cmp)) { forKeeping.add(cmp); } } return forKeeping; } /** * Clears the list of children */ private void removeAllChildComponents() { component.getChildren().clear(); } /** * Adds new child component * * @param cmp component to be added */ public void addComponent(Component cmp) { component.appendChild(cmp); } /** * Adds a collection of components * * @param components to be added */ public void addComponents(Collection<Component> components) { component.getChildren().addAll(components); } /** * Returns the label of the specified key based on the current Locale, or null if no found. * * @param key the label code to return its value * @return the label value according to current locale * @see Labels#getLabel(String) */ public String getLabel(String key) { return Labels.getLabel(key); } /** * Sends a temporary redirect response to the client using the specified redirect location URL by use of the current * execution, {@link Executions#getCurrent}. * * @param uri the URI to redirect to, or null to reload the same page */ public void sendRedirect(String uri) { Executions.sendRedirect(uri); } /** * Reloads current page. */ public void reloadPage() { Executions.sendRedirect(null); } /** * Returns an instance of javax.servlet.ServletResponse, or null if not available. * * @return the native response */ public HttpServletResponse getResponse() { return (HttpServletResponse) Executions.getCurrent().getNativeResponse(); } /** * Constructs a cookie with a specified name and value. See {@link Cookie#Cookie(String, String)}. The method is * used to ease testing. * * @param name a <code>String</code> specifying the name of the cookie * @param value a <code>String</code> specifying the value of the cookie * @return new cookie */ public Cookie createCookie(String name, String value) { return new Cookie(name, value); } /** * Returns a component, that is allocated by specified path * @param path where to look for component * @return component, that is allocated by specified path */ public Component getComponentByPath(String path) { return Path.getComponent(path); } }