/* Components.java Purpose: Description: History: Mon Jun 13 20:55:18 2005, Created by tomyeh Copyright (C) 2005 Potix Corporation. All Rights Reserved. {{IS_RIGHT This program is distributed under LGPL Version 2.1 in the hope that it will be useful, but WITHOUT ANY WARRANTY. }}IS_RIGHT */ package org.zkoss.zk.ui; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.security.Principal; import java.util.AbstractCollection; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zkoss.idom.Document; import org.zkoss.lang.Objects; import org.zkoss.util.CollectionsX; import org.zkoss.xel.ExpressionFactory; import org.zkoss.xel.VariableResolver; import org.zkoss.zk.au.AuResponse; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.ext.Scope; import org.zkoss.zk.ui.ext.ScopeListener; import org.zkoss.zk.ui.metainfo.ComponentDefinition; import org.zkoss.zk.ui.metainfo.DefinitionNotFoundException; import org.zkoss.zk.ui.metainfo.LanguageDefinition; import org.zkoss.zk.ui.metainfo.PageDefinition; import org.zkoss.zk.ui.sys.ExecutionCtrl; import org.zkoss.zk.ui.util.Composer; import org.zkoss.zk.ui.util.ConventionWires; import org.zkoss.zk.xel.Evaluator; /** * Utilities to access {@link Component}. * * @author tomyeh */ public class Components { private static final Logger log = LoggerFactory.getLogger(Components.class); private static final Logger _zklog = LoggerFactory.getLogger("org.zkoss.zk.log"); protected Components() { } /** Returns the parent of the ID space, or null if not found. * @since 5.0.0 */ public static IdSpace getParentIdSpace(IdSpace idspace) { if (idspace instanceof Component) { final Component c = (Component) idspace; final Component p = c.getParent(); return p != null ? p.getSpaceOwner() : c.getPage(); } return null; } /** Sorts the components in the list. * * <p>Note: you cannot use {@link Collections#sort} to sort * {@link Component#getChildren} because Collections.sort might cause * some replicated item in the list. * @see #sort(List, int, int, Comparator) */ public static void sort(List<? extends Component> list, Comparator<? super Component> cpr) { sort(list, 0, list.size(), cpr); } /** * Sorts the components in the list. * @param list the list to be sorted * @param from the index of the first element (inclusive) to be sorted * @param to the index of the last element (exclusive) to be sorted * @param cpr the comparator to determine the order of the list. * @since 3.5.0 */ public static void sort(List<? extends Component> list, int from, int to, Comparator<? super Component> cpr) { final Component[] ary = CollectionsX.toArray(list, new Component[0], from, to); Arrays.sort(ary, cpr); ListIterator<? extends Component> it = list.listIterator(from); int j = 0, k = to - from; for (; it.hasNext() && --k >= 0; ++j) { if (it.next() != ary[j]) { it.remove(); if (it.hasNext() && --k >= 0) { if (it.next() == ary[j]) continue; it.previous(); ++k; } break; } } while (it.hasNext() && --k >= 0) { it.next(); it.remove(); } for (; j < ary.length; ++j) add(list, from + j, ary[j]); } /** Replaces a component with another. * @param oldc the component to remove. * @param newc the component to add * @exception IllegalArgumentException if oldc's parent and page are * both null. * @since 3.5.2 */ public static void replace(Component oldc, Component newc) { final Component p = oldc.getParent(), sib = oldc.getNextSibling(); if (p != null) { oldc.detach(); p.insertBefore(newc, sib); } else { final Page page = oldc.getPage(); if (page == null) throw new IllegalArgumentException("Neither child nor attached, " + oldc); oldc.detach(); if (newc.getParent() != null) newc.detach(); newc.setPageBefore(page, sib); } } /** Replaces all children of the specified component. * It is the same as * <pre><code>parent.getChildren().clear(); *parent.getChildren().addAll(newChildren); *</code></pre> * @since 3.5.2 */ public static void replaceChildren(Component parent, Collection<Component> newChildren) { final Collection<Component> children = parent.getChildren(); children.clear(); children.addAll(newChildren); } @SuppressWarnings("unchecked") private static void add(List list, int index, Object o) { //to minimize the unchecked range list.add(index, o); } /** Returns the root component of the specified one. * Notice that it could return <code>comp</code>, if it is already * a root component (or it is null). * @since 3.6.3 */ public static Component getRoot(Component comp) { if (comp == null) return null; for (;;) { final Component p = comp.getParent(); if (p == null) return comp; comp = p; } } /** Tests whether node1 is an ancestor of node 2. * If node1 and node2 is the same, true is returned. */ public static boolean isAncestor(Component node1, Component node2) { for (; node2 != null; node2 = node2.getParent()) { if (node1 == node2) return true; } return false; } /** Removes all children of the specified component. * It is the same as <code>comp.getChildren().clear()</code>. */ public static void removeAllChildren(Component comp) { comp.getChildren().clear(); } /** Returns the component definition of the specified class in all * language of the specified device, or null if not found * * @param deviceType the device type ({@link org.zkoss.zk.device.Device}), * such as ajax. It cannot be null. * @param cls the implementation class of the component. * @since 5.0.0 */ public static final ComponentDefinition getDefinitionByDeviceType(String deviceType, Class cls) { for (LanguageDefinition ld : LanguageDefinition.getByDeviceType(deviceType)) { try { return ld.getComponentDefinition(cls); } catch (DefinitionNotFoundException ex) { //ignore } } return null; } /** Returns whether this component is real visible (all its parents * are visible). * <p>Note: true is returned if comp is null. * In other words, it can be used to examine parent's real visibility * even if it is a root component, * such as <code>Components.isRealVisible(getParent())</code>. * @see Component#isVisible */ public static boolean isRealVisible(Component comp) { for (; comp != null; comp = comp.getParent()) if (!comp.isVisible()) return false; return true; } /** Returns a collection of visible children. * <p>The performance of the returned collection's size() is NO GOOD. */ public static Collection<Component> getVisibleChildren(Component comp) { final Collection<Component> children = comp.getChildren(); return new AbstractCollection<Component>() { public int size() { int size = 0; for (Component c : children) { if (c.isVisible()) ++size; } return size; } public Iterator<Component> iterator() { return new Iterator<Component>() { final Iterator<Component> _it = children.iterator(); Component _next; public boolean hasNext() { if (_next != null) return true; _next = getNextVisible(false); return _next != null; } public Component next() { if (_next != null) { final Component c = _next; _next = null; return c; } return getNextVisible(true); } public void remove() { throw new UnsupportedOperationException(); } private Component getNextVisible(boolean blind) { while (blind || _it.hasNext()) { final Component c = _it.next(); if (c.isVisible()) return c; } return null; } }; } }; } /** Converts a string to an integer that can be used to access * {@link Component#getAttribute(String, int)} */ public static final int getScope(String scope) { if ("component".equals(scope)) return Component.COMPONENT_SCOPE; if ("space".equals(scope)) return Component.SPACE_SCOPE; if ("page".equals(scope)) return Component.PAGE_SCOPE; if ("desktop".equals(scope)) return Component.DESKTOP_SCOPE; if ("session".equals(scope)) return Component.SESSION_SCOPE; if ("application".equals(scope)) return Component.APPLICATION_SCOPE; if ("request".equals(scope)) return Component.REQUEST_SCOPE; throw new IllegalArgumentException("Unknown scope: " + scope); } /** Converts an integer to the string representing the scope. * @param scope one of {@link Component#COMPONENT_SCOPE}, * {@link Component#SPACE_SCOPE}, {@link Component#PAGE_SCOPE}, * {@link Component#DESKTOP_SCOPE}, {@link Component#SESSION_SCOPE}, * {@link Component#REQUEST_SCOPE}, and {@link Component#APPLICATION_SCOPE}. */ public static final String scopeToString(int scope) { switch (scope) { case Component.COMPONENT_SCOPE: return "component"; case Component.SPACE_SCOPE: return "space"; case Component.PAGE_SCOPE: return "page"; case Component.DESKTOP_SCOPE: return "desktop"; case Component.SESSION_SCOPE: return "session"; case Component.APPLICATION_SCOPE: return "application"; case Component.REQUEST_SCOPE: return "request"; } throw new IllegalArgumentException("Unknown scope: " + scope); } /** Converts a component to a path (relevant to another component). * It is usefully to implement a serializable component that contains * a reference to another component. In this case, we can not * serializes the reference directly (otherwise, another component will * be created, when deserialized). * * <p>Rather, it is better to store the path related, and then restore * it back to a component by calling {@link #pathToComponent}. * * @param comp the component to be converted to path. It cannot be null. * @param ref the component used to generated the path from. * It cannot be null. * @return the path. Notice that you have to use {@link #pathToComponent} * to convert it back. * @exception UnsupportedOperationException if we cannot find a path * to the component to write. * @since 3.0.0 */ public static final String componentToPath(Component comp, Component ref) { //Implementation Note: //The path being written is a bit different to Path, if ref //is not an space owner //For example, if comp is the space owner, "" is written. //If comp is the same as ref, "." is written. if (comp == null) { return null; } else if (comp == ref) { return "."; } else { final String id = comp.getId(); if (!(comp instanceof IdSpace) && id.length() == 0) throw new UnsupportedOperationException("comp must be assigned with ID or a space owner: " + comp); final StringBuffer sb = new StringBuffer(128); for (IdSpace space = ref.getSpaceOwner();;) { if (comp == space) { return sb.toString(); //could be "" //we don't generate id to make it work even if //its ID is changed } else if (space.getFellowIfAny(id) == comp) { if (sb.length() > 0) sb.append('/'); return sb.append(id).toString(); } if (sb.length() > 0) sb.append('/'); sb.append(".."); final Component parent = space instanceof Component ? ((Component) space).getParent() : null; if (parent == null) throw new UnsupportedOperationException("Unable to locate " + comp + " from " + ref); space = parent.getSpaceOwner(); } } } /** Converts a path, generated by {@link #componentToPath}, to * a component. * * @param ref the component used to generated the path from. * It cannot be null. It is the same as the one when calling * {@link #componentToPath}. * @since 3.0.0 */ public static final Component pathToComponent(String path, Component ref) { if (path == null) { return null; } else if (".".equals(path)) { return ref; } else if ("".equals(path)) { final IdSpace owner = ref.getSpaceOwner(); if (!(owner instanceof Component)) throw new IllegalStateException("The component is moved after serialized: " + ref); return (Component) owner; } return Path.getComponent(ref.getSpaceOwner(), path); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireFellows(IdSpace idspace, Object controller) { ConventionWires.wireFellows(idspace, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireFellows(IdSpace idspace, Object controller, char separator) { ConventionWires.wireFellows(idspace, controller, separator); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireFellows(IdSpace idspace, Object controller, char separator, boolean ignoreZScript, boolean ignoreXel) { ConventionWires.wireFellows(idspace, controller, separator, ignoreZScript, ignoreXel); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Component comp, Object controller) { ConventionWires.wireVariables(comp, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Component comp, Object controller, char separator) { ConventionWires.wireVariables(comp, controller, separator); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Component comp, Object controller, char separator, boolean ignoreZScript, boolean ignoreXel) { ConventionWires.wireVariables(comp, controller, separator, ignoreZScript, ignoreXel); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Page page, Object controller) { ConventionWires.wireVariables(page, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Page page, Object controller, char separator) { ConventionWires.wireVariables(page, controller, separator); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireVariables(Page page, Object controller, char separator, boolean ignoreZScript, boolean ignoreXel) { ConventionWires.wireVariables(page, controller, separator, ignoreZScript, ignoreXel); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireController(Component comp, Object controller) { ConventionWires.wireController(comp, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireController(Component comp, Object controller, char separator) { ConventionWires.wireController(comp, controller, separator); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireController(Component comp, Object controller, char separator, boolean ignoreZScript, boolean ignoreXel) { ConventionWires.wireController(comp, controller, separator); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static final void wireImplicit(Component comp, Object controller) { ConventionWires.wireImplicit(comp, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static void addForwards(Component comp, Object controller) { ConventionWires.addForwards(comp, controller); } /** @deprecated As of release 6.0.0, replaced with {@link ConventionWires}. */ public static void addForwards(Component comp, Object controller, char separator) { ConventionWires.addForwards(comp, controller, separator); } /** * Returns whether the given id is an implicit ZK object id. * * @param id Component id * @return whether the given name is a implicit object. * @since 3.5.2 */ public static boolean isImplicit(String id) { return IMPLICIT_NAMES.contains(id); } /** Returns a readonly collection of the names of the implicit objects. * @since 6.0.0 */ public static Collection<String> getImplicitNames() { return IMPLICIT_NAMES; } private static final Set<String> IMPLICIT_NAMES = new HashSet<String>(); static { final String[] names = { "application", "applicationScope", "arg", "componentScope", "desktop", "desktopScope", "execution", "event", //since 3.6.1, #bug 2681819: normal page throws exception after installed zkspring "self", "session", "sessionScope", "spaceOwner", "spaceScope", "page", "pageScope", "requestScope", "param" }; for (int j = 0; j < names.length; ++j) IMPLICIT_NAMES.add(names[j]); } /** Returns the implicit object of the specified name, or null * if not found. * * <p>Notice that it does check for the current scope * ({@link org.zkoss.zk.ui.ext.Scopes#getCurrent}). * Rather, {@link org.zkoss.zk.ui.ext.Scopes#getImplicit} * depends on this method. * * @param page the page. If page is null and comp is not, * comp.getPage() is assumed * @see org.zkoss.zk.ui.ext.Scopes#getImplicit * @since 5.0.0 */ public static Object getImplicit(Page page, Component comp, String name) { if (comp != null && page == null) page = getCurrentPage(comp); if ("log".equals(name)) return _zklog; if ("self".equals(name)) return comp != null ? comp : page; if ("spaceOwner".equals(name)) return comp != null ? comp.getSpaceOwner() : page; if ("page".equals(name)) return page; if ("desktop".equals(name)) return comp != null ? getDesktop(comp) : page.getDesktop(); if ("session".equals(name)) return comp != null ? getSession(comp) : page.getDesktop().getSession(); if ("application".equals(name)) return comp != null ? getWebApp(comp) : page.getDesktop().getWebApp(); if ("componentScope".equals(name)) return comp != null ? comp.getAttributes() : Collections.EMPTY_MAP; if ("spaceScope".equals(name)) { final Scope scope = comp != null ? comp.getSpaceOwner() : page; return scope != null ? scope.getAttributes() : Collections.EMPTY_MAP; } if ("pageScope".equals(name)) return page != null ? page.getAttributes() : Collections.EMPTY_MAP; if ("desktopScope".equals(name)) { final Desktop dt = comp != null ? getDesktop(comp) : page.getDesktop(); return dt != null ? dt.getAttributes() : Collections.EMPTY_MAP; } if ("sessionScope".equals(name)) { final Session sess = comp != null ? getSession(comp) : page.getDesktop().getSession(); return sess != null ? sess.getAttributes() : Collections.EMPTY_MAP; } if ("applicationScope".equals(name)) { final WebApp app = comp != null ? getWebApp(comp) : page.getDesktop().getWebApp(); return app != null ? app.getAttributes() : Collections.EMPTY_MAP; } if ("requestScope".equals(name)) return REQUEST_SCOPE_PROXY; if ("execution".equals(name)) return EXECUTION_PROXY; if ("arg".equals(name)) { final Execution exec = Executions.getCurrent(); return exec != null ? exec.getArg() : null; //bug 2937096: composer.arg shall be statically wired //arg is a Map prepared by application developer, so can be wired statically } if ("param".equals(name)) { final Execution exec = Executions.getCurrent(); return exec != null ? exec.getParameterMap() : null; //bug 2945974: composer.param shall be statically wired //Note that request parameter is prepared by servlet container, you shall not //copy the reference to this map; rather, you shall clone the key-value pair one-by-one. } //20090314, Henri Chen: No way to support "event" with an event proxy because org.zkoss.zk.Event is not an interface return null; } /** Returns the implicit object of the specified name, or null * if not found. * <p>It is the same as getImplicit(null, comp, name). * @since 3.6.0 */ public static Object getImplicit(Component comp, String name) { return getImplicit(null, comp, name); } /** Returns the implicit object of the specified name, or null * if not found. * <p>It is the same as getImplicit(page, null, name). * @since 3.6.0 */ public static Object getImplicit(Page page, String name) { return getImplicit(page, null, name); } /** Returns the composer object, or null * if not found. * @since 7.0.3 */ public static Composer getComposer(Component comp) { if (comp != null) { Object onm = comp.getAttribute("composerName"); if (onm instanceof String && ((String) onm).length() > 0) { return (Composer) comp.getAttribute((String) onm); } else { Composer result = (Composer) comp.getAttribute("_$composer$_"); if (result == null) { // just in case result = (Composer) comp.getAttribute("$composer"); } return result; } } return null; } /** * Adds the smartUpdate command to the specific component. * @since 7.0.3 */ public static void smartUpdate(Component comp, String key, Object value, boolean append) { if (comp instanceof AbstractComponent) ((AbstractComponent) comp).smartUpdate(key, value, append); } private static Desktop getDesktop(Component comp) { final Desktop dt = comp.getDesktop(); if (dt != null) return dt; final Execution exec = Executions.getCurrent(); return exec != null ? exec.getDesktop() : null; } private static WebApp getWebApp(Component comp) { final Desktop dt = getDesktop(comp); return dt != null ? dt.getWebApp() : null; } private static Session getSession(Component comp) { final Desktop dt = getDesktop(comp); return dt != null ? dt.getSession() : null; } /** Returns the page of the give component, or the current page if the * component is null or it doesn't belong to any page. * The current page is retrieved by {@link ExecutionCtrl#getCurrentPage} * or the current execution. This method returns null if no execution * or no current page at all. * @param comp the component to retrieve the page. Ignored if null. * @since 6.0.0 */ public static Page getCurrentPage(Component comp) { if (comp != null) { Page page = comp.getPage(); if (page != null) return page; } final Execution exec = Executions.getCurrent(); return exec != null ? ((ExecutionCtrl) exec).getCurrentPage() : null; } /** Execution Proxy */ public static final Exec EXECUTION_PROXY = new Exec(); /** Request Scope Proxy */ public static final RequestScope REQUEST_SCOPE_PROXY = new RequestScope(); //Proxy to read current execution private static class Exec implements Execution { private static final Execution exec() { return Executions.getCurrent(); } public void addAuResponse(AuResponse response) { exec().addAuResponse(response); } public void addAuResponse(String key, AuResponse response) { exec().addAuResponse(key, response); } public Component createComponents(PageDefinition pagedef, Component parent, Map<?, ?> arg) { return exec().createComponents(pagedef, parent, arg); } public Component createComponents(String uri, Component parent, Map<?, ?> arg) { return exec().createComponents(uri, parent, arg); } public Component createComponents(PageDefinition pagedef, Component parent, Component insertBefore, VariableResolver resolver) { return exec().createComponents(pagedef, parent, insertBefore, resolver); } public Component createComponents(String uri, Component parent, Component insertBefore, VariableResolver resolver) { return exec().createComponents(uri, parent, insertBefore, resolver); } public Component[] createComponents(PageDefinition pagedef, Map<?, ?> arg) { return exec().createComponents(pagedef, arg); } public Component[] createComponents(String uri, Map<?, ?> arg) { return exec().createComponents(uri, arg); } public Component[] createComponents(String uri, Page page, VariableResolver resolver, Map<?, ?> arg) { return exec().createComponents(uri, page, resolver, arg); } public Component[] createComponents(String uri, Component parent, Component insertBefore, VariableResolver resolver, Map<?, ?> arg) { return exec().createComponents(uri, parent, insertBefore, resolver, arg); } public Component createComponentsDirectly(String content, String extension, Component parent, Map<?, ?> arg) { return exec().createComponentsDirectly(content, extension, parent, arg); } public Component createComponentsDirectly(Document content, String extension, Component parent, Map<?, ?> arg) { return exec().createComponentsDirectly(content, extension, parent, arg); } public Component createComponentsDirectly(Reader reader, String extension, Component parent, Map<?, ?> arg) throws IOException { return exec().createComponentsDirectly(reader, extension, parent, arg); } public Component createComponentsDirectly(String content, String extension, Component parent, Component insertBefore, VariableResolver resolver) { return exec().createComponentsDirectly(content, extension, parent, insertBefore, resolver); } public Component createComponentsDirectly(Document content, String extension, Component parent, Component insertBefore, VariableResolver resolver) { return exec().createComponentsDirectly(content, extension, parent, insertBefore, resolver); } public Component createComponentsDirectly(Reader reader, String extension, Component parent, Component insertBefore, VariableResolver resolver) throws IOException { return exec().createComponentsDirectly(reader, extension, parent, insertBefore, resolver); } public Component[] createComponentsDirectly(String content, String extension, Map<?, ?> arg) { return exec().createComponentsDirectly(content, extension, arg); } public Component[] createComponentsDirectly(Document content, String extension, Map<?, ?> arg) { return exec().createComponentsDirectly(content, extension, arg); } public Component[] createComponentsDirectly(Reader reader, String extension, Map<?, ?> arg) throws IOException { return exec().createComponentsDirectly(reader, extension, arg); } public String encodeURL(String uri) { return exec().encodeURL(uri); } public Object evaluate(Component comp, String expr, Class expectedType) { return exec().evaluate(comp, expr, expectedType); } public Object evaluate(Page page, String expr, Class expectedType) { return exec().evaluate(page, expr, expectedType); } public void forward(Writer writer, String page, Map<String, ?> params, int mode) throws IOException { exec().forward(writer, page, params, mode); } public void forward(String page) throws IOException { exec().forward(page); } public Map<?, ?> getArg() { return exec().getArg(); } public Object getAttribute(String name) { return exec().getAttribute(name); } public Object getAttribute(String name, boolean recurse) { return exec().getAttribute(name, recurse); } public boolean hasAttribute(String name) { return exec().hasAttribute(name); } public boolean hasAttribute(String name, boolean recurse) { return exec().hasAttribute(name, recurse); } public Object setAttribute(String name, Object value, boolean recurse) { return exec().setAttribute(name, value, recurse); } public Object setAttribute(String name, Object value) { return exec().setAttribute(name, value); } public Object removeAttribute(String name, boolean recurse) { return exec().removeAttribute(name, recurse); } public Object removeAttribute(String name) { return exec().removeAttribute(name); } public boolean addScopeListener(ScopeListener listener) { return exec().addScopeListener(listener); } public boolean removeScopeListener(ScopeListener listener) { return exec().removeScopeListener(listener); } public Map<String, Object> getAttributes() { return exec().getAttributes(); } public String getContextPath() { return exec().getContextPath(); } public Desktop getDesktop() { return exec().getDesktop(); } public Evaluator getEvaluator(Page page, Class<? extends ExpressionFactory> expfcls) { return exec().getEvaluator(page, expfcls); } public Evaluator getEvaluator(Component comp, Class<? extends ExpressionFactory> expfcls) { return exec().getEvaluator(comp, expfcls); } public String getLocalAddr() { return exec().getLocalAddr(); } public String getLocalName() { return exec().getLocalName(); } public int getLocalPort() { return exec().getLocalPort(); } public Object getNativeRequest() { return exec().getNativeRequest(); } public Object getNativeResponse() { return exec().getNativeResponse(); } public PageDefinition getPageDefinition(String uri) { return exec().getPageDefinition(uri); } public PageDefinition getPageDefinitionDirectly(String content, String extension) { return exec().getPageDefinitionDirectly(content, extension); } public PageDefinition getPageDefinitionDirectly(Document content, String extension) { return exec().getPageDefinitionDirectly(content, extension); } public PageDefinition getPageDefinitionDirectly(Reader reader, String extension) throws IOException { return exec().getPageDefinitionDirectly(reader, extension); } public String getParameter(String name) { return exec().getParameter(name); } public Map<String, String[]> getParameterMap() { return exec().getParameterMap(); } public String[] getParameterValues(String name) { return exec().getParameterValues(name); } public String getRemoteAddr() { return exec().getRemoteAddr(); } public String getRemoteHost() { return exec().getRemoteHost(); } public String getRemoteUser() { return exec().getRemoteUser(); } public String getServerName() { return exec().getServerName(); } public int getServerPort() { return exec().getServerPort(); } public String getScheme() { return exec().getScheme(); } public String getUserAgent() { return exec().getUserAgent(); } public Principal getUserPrincipal() { return exec().getUserPrincipal(); } public VariableResolver getVariableResolver() { return exec().getVariableResolver(); } public void include(Writer writer, String page, Map<String, ?> params, int mode) throws IOException { exec().include(writer, page, params, mode); } public void include(String page) throws IOException { exec().include(page); } public boolean isAsyncUpdate(Page page) { return exec().isAsyncUpdate(page); } public Double getBrowser(String name) { return exec().getBrowser(name); } public String getBrowser() { return exec().getBrowser(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isBrowser() { return exec().isBrowser(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isBrowser(String type) { return exec().isBrowser(type); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isExplorer() { return exec().isExplorer(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isExplorer7() { return exec().isExplorer7(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isOpera() { return exec().isOpera(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isGecko() { return exec().isGecko(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isGecko3() { return exec().isGecko3(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isHilDevice() { return exec().isHilDevice(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isSafari() { return exec().isSafari(); } /** @deprecated As of release 6.0.0, replaced with {@link #getBrowser(String)}. */ public boolean isRobot() { return exec().isRobot(); } public boolean isForwarded() { return exec().isForwarded(); } public boolean isIncluded() { return exec().isIncluded(); } public boolean isUserInRole(String role) { return exec().isUserInRole(role); } public boolean isVoided() { return exec().isVoided(); } public void popArg() { exec().popArg(); } public void postEvent(Event evt) { exec().postEvent(evt); } public void postEvent(int priority, Event evt) { exec().postEvent(priority, evt); } public void postEvent(int priority, Component realTarget, Event evt) { exec().postEvent(priority, realTarget, evt); } public void pushArg(Map<?, ?> arg) { exec().pushArg(arg); } public void sendRedirect(String uri) { exec().sendRedirect(uri); } public void sendRedirect(String uri, String target) { exec().sendRedirect(uri, target); } public void sendRedirect(String uri, boolean respRedirect) { exec().sendRedirect(uri, respRedirect); } public void setVoided(boolean voided) { exec().setVoided(voided); } public String toAbsoluteURI(String uri, boolean skipInclude) { return exec().toAbsoluteURI(uri, skipInclude); } public void addResponseHeader(String name, String value) { exec().addResponseHeader(name, value); } public void addResponseHeader(String name, Date value) { exec().addResponseHeader(name, value); } public boolean containsResponseHeader(String name) { return exec().containsResponseHeader(name); } public String getHeader(String name) { return exec().getHeader(name); } public Iterable<String> getHeaderNames() { return exec().getHeaderNames(); } public Iterable<String> getHeaders(String name) { return exec().getHeaders(name); } public void setResponseHeader(String name, String value) { exec().setResponseHeader(name, value); } public void setResponseHeader(String name, Date value) { exec().setResponseHeader(name, value); } public Session getSession() { return exec().getSession(); } public String locate(String path) { return exec().locate(path); } public boolean addVariableResolver(VariableResolver resolver) { return exec().addVariableResolver(resolver); } public boolean removeVariableResolver(VariableResolver resolver) { return exec().removeVariableResolver(resolver); } public boolean hasVariableResolver(VariableResolver resolver) { return exec().hasVariableResolver(resolver); } public boolean hasVariableResolver(Class<? extends VariableResolver> cls) { return exec().hasVariableResolver(cls); } public String toString() { return Objects.toString(exec()); } public int hashCode() { return Objects.hashCode(exec()); } public boolean equals(Object o) { if (this == o) return true; if (o instanceof Exec) return Objects.equals(exec(), ((Exec) o).exec()); return Objects.equals(exec(), o); } public void log(String msg) { exec().log(msg); } public void log(String msg, Throwable ex) { exec().log(msg, ex); } } //Proxy to read current requestScope private static class RequestScope implements Map<String, Object> { protected Map<String, Object> req() { return Executions.getCurrent().getAttributes(); } public void clear() { req().clear(); } public boolean containsKey(Object key) { return req().containsKey(key); } public boolean containsValue(Object value) { return req().containsValue(value); } public Set<Map.Entry<String, Object>> entrySet() { return req().entrySet(); } public Object get(Object key) { return req().get(key); } public boolean isEmpty() { return req().isEmpty(); } public Set<String> keySet() { return req().keySet(); } public Object put(String key, Object value) { return req().put(key, value); } public void putAll(Map<? extends String, ? extends Object> arg0) { req().putAll(arg0); } public Object remove(Object key) { return req().remove(key); } public int size() { return req().size(); } public Collection<Object> values() { return req().values(); } public String toString() { return Objects.toString(req()); } public int hashCode() { return Objects.hashCode(req()); } public boolean equals(Object o) { if (this == o) return true; if (o instanceof RequestScope) return Objects.equals(req(), ((RequestScope) o).req()); return Objects.equals(req(), o); } } }