/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.wicket; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.core.request.handler.ListenerInvocationNotAllowedException; import org.apache.wicket.request.component.IRequestableComponent; import org.apache.wicket.util.lang.Classes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Base class for request listener interfaces. * * @author Jonathan Locke * @deprecated This class is not used by the framework anymore. Will be removed in Wicket 9.0.0 */ @Deprecated public class RequestListenerInterface { /** Map from name to request listener interface */ private static final Map<String, RequestListenerInterface> interfaces = Collections.synchronizedMap(new HashMap<String, RequestListenerInterface>()); /** Log. */ private static final Logger log = LoggerFactory.getLogger(RequestListenerInterface.class); /** * Looks up a request interface listener by name. * * @param interfaceName * The interface name * @return The RequestListenerInterface object, or null if none is found * */ public static RequestListenerInterface forName(final String interfaceName) { return interfaces.get(interfaceName); } /** The name of this listener interface */ private final String name; /** * Whether the render count should be included in URL. This should be true for every listener * interface URL that should only be active on last rendered page (links, etc) and false for * other (resources); */ private boolean includeRenderCount = true; /** * Whether the page should be rendered by default after the invocation of this listener * interface. Applies only during non-ajax requests. */ private boolean renderPageAfterInvocation = true; final Class<? extends IRequestListener> listenerInterfaceClass; /** * Constructor. * * @param listenerInterfaceClass * The interface class, which must extend IRequestListener. */ public RequestListenerInterface(final Class<? extends IRequestListener> listenerInterfaceClass) { this.listenerInterfaceClass = listenerInterfaceClass; // Ensure that it extends IRequestListener if (!IRequestListener.class.isAssignableFrom(listenerInterfaceClass)) { throw new IllegalArgumentException("Class " + listenerInterfaceClass + " must extend IRequestListener"); } // Save short class name name = Classes.simpleName(listenerInterfaceClass); // Register this listener register(); } /** * @return The interface class, which must extend IRequestListener. */ public Class<? extends IRequestListener> getListenerInterfaceClass() { return listenerInterfaceClass; } /** * @param includeRenderCount * @return self */ public RequestListenerInterface setIncludeRenderCount(boolean includeRenderCount) { this.includeRenderCount = includeRenderCount; return this; } /** * @return whether the render count should be included in url */ public boolean isIncludeRenderCount() { return includeRenderCount; } /** * @param renderPageAfterInvocation * @return self */ public RequestListenerInterface setRenderPageAfterInvocation(boolean renderPageAfterInvocation) { this.renderPageAfterInvocation = renderPageAfterInvocation; return this; } /** * @return whether the page should be rendered after invocation of this interface (during * non-ajax requests) */ public boolean isRenderPageAfterInvocation() { return renderPageAfterInvocation; } /** * @return The name of this request listener interface */ public final String getName() { return name; } /** * Invokes a given interface on a component. * * @param rcomponent * The component * * @throws ListenerInvocationNotAllowedException * when listener invocation attempted on a component that does not allow it */ public final void invoke(final IRequestableComponent rcomponent) { // we are in Wicket core land final Component component = (Component)rcomponent; if (!component.canCallListener()) { // just return so that we have a silent fail and just re-render the // page log.info("component not enabled or visible; ignoring call. Component: " + component); throw new ListenerInvocationNotAllowedException(component, null, "Component rejected interface invocation"); } internalInvoke(component, component); } /** * Invokes a given interface on a component's behavior. * * @param rcomponent * The component * @param behavior * @throws ListenerInvocationNotAllowedException * when listener invocation attempted on a component that does not allow it */ public final void invoke(final IRequestableComponent rcomponent, final Behavior behavior) { // we are in Wicket core land final Component component = (Component)rcomponent; if (!behavior.canCallListener(component)) { log.warn("behavior not enabled; ignore call. Behavior {} at component {}", behavior, component); throw new ListenerInvocationNotAllowedException(component, behavior, "Behavior rejected interface invocation. "); } internalInvoke(component, behavior); } private void internalInvoke(final Component component, final Object target) { // save a reference to the page because the component can be removed // during the invocation of the listener and thus lose its parent Page page = component.getPage(); // initialization is required for stateless pages if (!page.isInitialized()) { page.internalInitialize(); } ((IRequestListener)target).onRequest(); } /** * Method to call to register this interface for use */ public void register() { // Register this listener interface registerRequestListenerInterface(this); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return "[RequestListenerInterface name=" + name + "]"; } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL IT. * <p> * In previous versions of Wicket, request listeners were manually registered by calling this * method. Now there is a first class RequestListenerInterface object which should be * constructed as a constant member of the interface to enable automatic interface registration. * <p> * Adds a request listener interface to the map of interfaces that can be invoked by outsiders. * * @param requestListenerInterface * The request listener interface object */ private void registerRequestListenerInterface(final RequestListenerInterface requestListenerInterface) { // Check that a different interface method with the same name has not // already been registered final RequestListenerInterface existingInterface = RequestListenerInterface.forName(requestListenerInterface.getName()); if (existingInterface == null) { // Save this interface method by the non-qualified class name interfaces.put(requestListenerInterface.getName(), requestListenerInterface); log.info("registered listener interface " + this); } } /** * * @return collection of all registered interfaces */ public static Collection<RequestListenerInterface> getRegisteredInterfaces() { return Collections.unmodifiableCollection(interfaces.values()); } }