zk/src/main/java/org/zkoss/zk/ui/Components.java
/* 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.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.xel.Evaluator;
/**
* Utilities to access {@link Component}.
*
* @author tomyeh
*/
public class Components {
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)) {
ComponentDefinition definitionIfAny = ld.getComponentDefinitionIfAny(
cls);
if (definitionIfAny != null) {
return definitionIfAny;
}
}
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);
}
/**
* 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 ("executionScope".equals(name)) {
final Execution exec = Executions.getCurrent();
return exec != null ? exec.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();
}
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);
}
}
}