All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.Application Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * 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.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.wicket.application.IComponentInitializationListener;
import org.apache.wicket.application.IComponentInstantiationListener;
import org.apache.wicket.application.IComponentOnAfterRenderListener;
import org.apache.wicket.application.IComponentOnBeforeRenderListener;
import org.apache.wicket.javascript.DefaultJavascriptCompressor;
import org.apache.wicket.markup.IMarkupCache;
import org.apache.wicket.markup.html.EmptySrcAttributeCheckFilter;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.IHeaderResponseDecorator;
import org.apache.wicket.markup.html.image.resource.DefaultButtonImageResourceFactory;
import org.apache.wicket.markup.parser.filter.RelativePathPrefixHandler;
import org.apache.wicket.markup.parser.filter.WicketMessageTagHandler;
import org.apache.wicket.markup.resolver.AutoComponentResolver;
import org.apache.wicket.markup.resolver.BorderBodyResolver;
import org.apache.wicket.markup.resolver.EnclosureResolver;
import org.apache.wicket.markup.resolver.FragmentResolver;
import org.apache.wicket.markup.resolver.HtmlHeaderResolver;
import org.apache.wicket.markup.resolver.MarkupInheritanceResolver;
import org.apache.wicket.markup.resolver.ParentResolver;
import org.apache.wicket.markup.resolver.WicketContainerResolver;
import org.apache.wicket.markup.resolver.WicketLinkResolver;
import org.apache.wicket.markup.resolver.WicketMessageResolver;
import org.apache.wicket.protocol.http.IRequestLogger;
import org.apache.wicket.protocol.http.RequestLogger;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.session.ISessionStore;
import org.apache.wicket.settings.IApplicationSettings;
import org.apache.wicket.settings.IDebugSettings;
import org.apache.wicket.settings.IExceptionSettings;
import org.apache.wicket.settings.IFrameworkSettings;
import org.apache.wicket.settings.IMarkupSettings;
import org.apache.wicket.settings.IPageSettings;
import org.apache.wicket.settings.IRequestCycleSettings;
import org.apache.wicket.settings.IRequestLoggerSettings;
import org.apache.wicket.settings.IResourceSettings;
import org.apache.wicket.settings.ISecuritySettings;
import org.apache.wicket.settings.ISessionSettings;
import org.apache.wicket.settings.Settings;
import org.apache.wicket.util.convert.ConverterLocator;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.lang.Objects;
import org.apache.wicket.util.lang.PropertyResolver;
import org.apache.wicket.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class for all Wicket applications. To create a Wicket application, you generally should
 * not  directly subclass this class. Instead, you will want to subclass some subclass of
 * Application, like WebApplication, which is appropriate for the protocol and markup type you are
 * working with.
 * 

* Application has the following interesting features / attributes: *

    *
  • Name - The Application's name, which is the same as its class name. * *
  • Home Page - The Application's home Page class. Subclasses must override getHomePage() * to provide this property value. * *
  • Settings - Application settings are partitioned into sets of related settings using * interfaces in the org.apache.wicket.settings package. These interfaces are returned by the * following methods, which should be used to configure framework settings for your application: * getApplicationSettings(), getDebugSettings(), getExceptionSettings(), getMarkupSettings(), * getPageSettings(), getRequestCycleSettings(), getSecuritySettings and getSessionSettings(). These * settings are configured by default through the constructor or internalInit methods. Default the * application is configured for DEVELOPMENT. You can configure this globally to DEPLOYMENT or * override specific settings by implementing the init() method. * *
  • Shared Resources - Resources added to an Application's SharedResources have * application-wide scope and can be referenced using a logical scope and a name with the * ResourceReference class. ResourceReferences can then be used by multiple components in the same * application without additional overhead (beyond the ResourceReference instance held by each * referee) and will yield a stable URL, permitting efficient browser caching of the resource (even * if the resource is dynamically generated). Resources shared in this manner may also be localized. * See {@link org.apache.wicket.ResourceReference} for more details. * *
  • Custom Session Subclasses- In order to install your own {@link Session} subclass you * must override Application{@link #newSession(Request, Response)}. For subclasses of * {@link WebApplication} you will want to subclass {@link WebSession}. * *
* * @see org.apache.wicket.protocol.http.WebApplication * @author Jonathan Locke */ public abstract class Application { /** Configuration constant for the 2 types */ public static final String CONFIGURATION = "configuration"; /** * Configuration type constant for getting the context path out of the web.xml */ public static final String CONTEXTPATH = "contextpath"; /** Configuration type constant for deployment */ public static final String DEPLOYMENT = "deployment"; /** Configuration type constant for development */ public static final String DEVELOPMENT = "development"; /** * Applications keyed on the {@link #getApplicationKey()} so that they can be retrieved even * without being in a request/ being set in the thread local (we need that e.g. for when we are * in a destruction thread). */ private static final Map applicationKeyToApplication = new HashMap( 1); /** Thread local holder of the application object. */ private static final ThreadLocal current = new ThreadLocal(); /** Log. */ private static final Logger log = LoggerFactory.getLogger(Application.class); /** */ private List componentPreOnBeforeRenderListeners; /** */ private List componentPostOnBeforeRenderListeners; /** */ private List componentOnAfterRenderListeners; /** */ private List renderHeadListeners; /** * The decorator this application uses to decorate any header responses created by Wicket */ private IHeaderResponseDecorator headerResponseDecorator; /** * Checks if the Application threadlocal is set in this thread * * @return true if {@link Application#get()} can return the instance of application, false * otherwise */ public static boolean exists() { return current.get() != null; } /** * Get Application for current thread. * * @return The current thread's Application */ public static Application get() { final Application application = current.get(); if (application == null) { throw new WicketRuntimeException("There is no application attached to current thread " + Thread.currentThread().getName()); } return application; } /** * Gets the Application based on the application key of that application. You typically never * have to use this method unless you are working on an integration project. * * @param applicationKey * The unique key of the application within a certain context (e.g. a web * application) * @return The application or null if application has not been found */ public static Application get(String applicationKey) { Application application = applicationKeyToApplication.get(applicationKey); return application; } /** * Gets the keys of the currently registered Wicket applications for this web application. You * typically never have to use this method unless you are working on an integration project. * * @return unmodifiable set with keys that correspond with {@link #getApplicationKey()}. Never * null, but possibly empty */ public static Set getApplicationKeys() { return Collections.unmodifiableSet(applicationKeyToApplication.keySet()); } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT. * * @param application * The current application or null for this thread */ public static void set(final Application application) { if (application == null) { throw new IllegalArgumentException("Argument application can not be null"); } current.set(application); } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT. */ public static void unset() { current.set(null); } /** list of {@link IComponentInstantiationListener}s. */ private IComponentInstantiationListener[] componentInstantiationListeners = new IComponentInstantiationListener[0]; /** list of {@link IComponentInitializationListener}s. */ private final CopyOnWriteArrayList componentInitializationListeners = new CopyOnWriteArrayList(); /** The converter locator instance. */ private IConverterLocator converterLocator; /** list of initializers. */ private final List initializers = new ArrayList(); /** Application level meta data. */ private MetaDataEntry[] metaData; /** Name of application subclass. */ private final String name; /** Request logger instance. */ private IRequestLogger requestLogger; /** The session facade. */ private ISessionStore sessionStore; /** Settings for this application. */ private Settings settings; /** can the settings object be set/used. */ private boolean settingsAccessible; /** Shared resources for this application */ private final SharedResources sharedResources; /** * Constructor. Use {@link #init()} for any configuration of your application instead of * overriding the constructor. */ public Application() { // Create name from subclass name = Classes.simpleName(getClass()); // Create shared resources repository sharedResources = new SharedResources(); // Install default component instantiation listener that uses // authorization strategy to check component instantiations. addComponentInstantiationListener(new IComponentInstantiationListener() { /** * @see org.apache.wicket.application.IComponentInstantiationListener#onInstantiation(org.apache.wicket.Component) */ public void onInstantiation(final Component component) { final Class cl = component.getClass(); // If component instantiation is not authorized if (!Session.get().getAuthorizationStrategy().isInstantiationAuthorized(cl)) { // then call any unauthorized component instantiation // listener getSecuritySettings().getUnauthorizedComponentInstantiationListener() .onUnauthorizedInstantiation(component); } } }); } /** * Adds a component instantiation listener. This method should typically only be called during * application startup; it is not thread safe. *

* Note: wicket does not guarantee the execution order of added listeners * * @param listener * the listener to add */ public final void addComponentInstantiationListener( final IComponentInstantiationListener listener) { if (listener == null) { throw new IllegalArgumentException("argument listener may not be null"); } // if an instance of this listener is already present ignore this call for (int i = 0; i < componentInstantiationListeners.length; i++) { if (listener == componentInstantiationListeners[i]) { return; } } final IComponentInstantiationListener[] newListeners = new IComponentInstantiationListener[componentInstantiationListeners.length + 1]; System.arraycopy(componentInstantiationListeners, 0, newListeners, 0, componentInstantiationListeners.length); newListeners[componentInstantiationListeners.length] = listener; componentInstantiationListeners = newListeners; } /** * Adds a component initialization listener. This method should typically only be called during * application startup; it is not thread safe. *

* Each added listener will be notified after Component's {@link Component#onInitialize()} * method has been executed. *

*

* Note: wicket does not guarantee the execution order of added listeners * * @param listener * the listener to add */ public final void addComponentInitializationListener( final IComponentInitializationListener listener) { if (listener == null) { throw new IllegalArgumentException("argument listener may not be null"); } if (componentInitializationListeners.contains(listener)) { return; } componentInitializationListeners.add(listener); } /** * Fires registered {@link IComponentInitializationListener}s on the component * * @param component * * @see #addComponentInitializationListener(IComponentInitializationListener) */ public final void fireComponentInitializationListeners(Component component) { for (IComponentInitializationListener listener : componentInitializationListeners) { listener.onInitialize(component); } } /** * Configures application settings to good defaults. */ public final void configure() { final String configurationType = getConfigurationType(); // As long as this is public api the development and deployment mode // should counter act each other for all properties. if (DEVELOPMENT.equalsIgnoreCase(configurationType)) { getResourceSettings().setResourcePollFrequency(Duration.ONE_SECOND); getDebugSettings().setComponentUseCheck(true); getMarkupSettings().setStripWicketTags(false); getExceptionSettings().setUnexpectedExceptionDisplay( IExceptionSettings.SHOW_EXCEPTION_PAGE); getDebugSettings().setAjaxDebugModeEnabled(true); getDebugSettings().setDevelopmentUtilitiesEnabled(true); // getDebugSettings().setOutputMarkupContainerClassName(true); getResourceSettings().setJavascriptCompressor(null); getRequestCycleSettings().addResponseFilter(EmptySrcAttributeCheckFilter.INSTANCE); } else if (DEPLOYMENT.equalsIgnoreCase(configurationType)) { getResourceSettings().setResourcePollFrequency(null); getDebugSettings().setComponentUseCheck(false); getMarkupSettings().setStripWicketTags(true); getExceptionSettings().setUnexpectedExceptionDisplay( IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE); getDebugSettings().setAjaxDebugModeEnabled(false); getDebugSettings().setDevelopmentUtilitiesEnabled(false); getResourceSettings().setJavascriptCompressor(new DefaultJavascriptCompressor()); } else { throw new IllegalArgumentException("Invalid configuration type: '" + configurationType + "'. Must be \"development\" or \"deployment\"."); } } /** * Gets the unique key of this application within a given context (like a web application). NOT * INTENDED FOR FRAMEWORK CLIENTS. * * @return The unique key of this application */ public abstract String getApplicationKey(); /** * @return Application's application-wide settings * @see IApplicationSettings * @since 1.2 */ public IApplicationSettings getApplicationSettings() { return getSettings(); } /** * Gets the configuration mode to use for configuring the app, either {@link #DEVELOPMENT} or * {@link #DEPLOYMENT}. *

* The configuration type. Must currently be either DEVELOPMENT or DEPLOYMENT. Currently, if the * configuration type is DEVELOPMENT, resources are polled for changes, component usage is * checked, wicket tags are not stripped from output and a detailed exception page is used. If * the type is DEPLOYMENT, component usage is not checked, wicket tags are stripped from output * and a non-detailed exception page is used to display errors. *

* Note that you should not run Wicket in DEVELOPMENT mode on production servers - the various * debugging checks and resource polling is inefficient and may leak resources, particularly on * webapp redeploy. * *

*

* To change the deployment mode, add the following to your web.xml, inside your * mapping (or mapping if you're using 1.3.x): * *

	 * <init-param>
	 *             <param-name>configuration</param-name>
	 *             <param-value>deployment</param-value>
	 * </init-param>
	 * 
* *

* You can alternatively set this as a <context-param> on the whole context. * *

* Another option is to set the "wicket.configuration" system property to either "deployment" or * "development". The value is not case-sensitive. * *

* The system property is checked first, allowing you to add a web.xml param for deployment, and * a command-line override when you want to run in development mode during development. * *

* You may also override Application.getConfigurationType() to provide your own custom switch, * in which case none of the above logic is used.

* *

* IMPORTANT NOTE *

* THIS METHOD IS CALLED OFTEN FROM MANY DIFFERENT POINTS IN CODE, INCLUDING DURING THE RENDER * PROCESS, THEREFORE THE IMPLEMENTATION SHOULD BE FAST - PREFERRABLY USING A FAST-TO-RETRIEVE * CACHED VALUE * * * * @return configuration * @since 1.2.3 (function existed as a property getter) * @since 1.3.0 (abstract, used to configure things) */ public abstract String getConfigurationType(); /** * @return The converter locator for this application */ public final IConverterLocator getConverterLocator() { return converterLocator; } /** * @return Application's debug related settings * @see IDebugSettings * @since 1.2 */ public IDebugSettings getDebugSettings() { return getSettings(); } /** * @return Application's exception handling settings * @see IExceptionSettings * @since 1.2 */ public IExceptionSettings getExceptionSettings() { return getSettings(); } /** * @return Wicket framework settings * @see IFrameworkSettings * @since 1.2 */ public IFrameworkSettings getFrameworkSettings() { return getSettings(); } /** * Application subclasses must specify a home page class by implementing this abstract method. * * @return Home page class for this application */ public abstract Class getHomePage(); /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT. * * @return The markup cache associated with the application * @deprecated please use {@link IMarkupSettings#getMarkupCache()} instead */ @Deprecated public final IMarkupCache getMarkupCache() { return getMarkupSettings().getMarkupCache(); } /** * @return Application's markup related settings * @see IMarkupSettings * @since 1.2 */ public IMarkupSettings getMarkupSettings() { return getSettings(); } /** * Gets metadata for this application using the given key. * * @param * @param key * The key for the data * @return The metadata * @see MetaDataKey */ public final T getMetaData(final MetaDataKey key) { return key.get(metaData); } /** * Gets the name of this application. * * @return The application name. */ public final String getName() { return name; } /** * @return Application's page related settings * @see IPageSettings * @since 1.2 */ public IPageSettings getPageSettings() { return getSettings(); } /** * @return Application's request cycle related settings * @see IDebugSettings * @since 1.2 */ public IRequestCycleSettings getRequestCycleSettings() { return getSettings(); } /** * Gets the {@link RequestLogger}. * * @return The RequestLogger */ public final IRequestLogger getRequestLogger() { if (getRequestLoggerSettings().isRequestLoggerEnabled()) { if (requestLogger == null) { requestLogger = newRequestLogger(); } } else { requestLogger = null; } return requestLogger; } /** * @return Application's resources related settings * @see IResourceSettings * @since 1.3 */ public IRequestLoggerSettings getRequestLoggerSettings() { return getSettings(); } /** * @return Application's resources related settings * @see IResourceSettings * @since 1.2 */ public IResourceSettings getResourceSettings() { return getSettings(); } /** * @return Application's security related settings * @see ISecuritySettings * @since 1.2 */ public ISecuritySettings getSecuritySettings() { return getSettings(); } /** * @return Application's session related settings * @see ISessionSettings * @since 1.2 */ public ISessionSettings getSessionSettings() { return getSettings(); } /** * Gets the facade object for working getting/ storing session instances. * * @return The session facade */ public final ISessionStore getSessionStore() { return sessionStore; } /** * Gets the shared resources. * * @return The SharedResources for this application. */ public final SharedResources getSharedResources() { return sharedResources; } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL. * * Initializes wicket components. */ public final void initializeComponents() { // Load any wicket properties files we can find try { // Load properties files used by all libraries final Iterator resources = getApplicationSettings().getClassResolver() .getResources("wicket.properties"); while (resources.hasNext()) { InputStream in = null; try { final URL url = resources.next(); final Properties properties = new Properties(); in = url.openStream(); properties.load(in); load(properties); } finally { if (in != null) { in.close(); } } } } catch (IOException e) { throw new WicketRuntimeException("Unable to load initializers file", e); } // now call any initializers we read callInitializers(); } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL. * * @param target */ public void logEventTarget(IRequestTarget target) { } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL. * * @param requestTarget */ public void logResponseTarget(IRequestTarget requestTarget) { } /** * Creates a new RequestCycle object. Override this method if you want to provide a custom * request cycle. * * @param request * The request * @param response * The response * @return The request cycle * * @since 1.3 */ public abstract RequestCycle newRequestCycle(final Request request, final Response response); /** * FOR DEPRECATION ONLY. * * @param application * @param request * @param response * @return nothing * @throws UnsupportedOperationException * always * @deprecated Applications wishing to provide custom request cycles should override method * {@link #newRequestCycle(Request, Response)} */ @Deprecated public final RequestCycle newRequestCycle(Application application, Request request, Response response) { throw new UnsupportedOperationException(); } /** * Creates a new session. Override this method if you want to provide a custom session. * * @param request * The request that will create this session. * @param response * The response to initialize, for example with cookies. This is important to use * cases involving unit testing because those use cases might want to be able to sign * a user in automatically when the session is created. * * @return The session * * @since 1.3 */ public abstract Session newSession(Request request, Response response); /** * Removes a component instantiation listener. This method should typicaly only be called during * application startup; it is not thread safe. * * @param listener * the listener to remove */ public final void removeComponentInstantiationListener( final IComponentInstantiationListener listener) { final IComponentInstantiationListener[] listeners = componentInstantiationListeners; final int len = listeners.length; if (listener != null && len > 0) { int pos = 0; for (pos = 0; pos < len; pos++) { if (listener == listeners[pos]) { break; } } if (pos < len) { listeners[pos] = listeners[len - 1]; final IComponentInstantiationListener[] newListeners = new IComponentInstantiationListener[len - 1]; System.arraycopy(listeners, 0, newListeners, 0, newListeners.length); componentInstantiationListeners = newListeners; } } } /** * Sets the metadata for this application using the given key. If the metadata object is not of * the correct type for the metadata key, an IllegalArgumentException will be thrown. For * information on creating MetaDataKeys, see {@link MetaDataKey}. * * @param * @param key * The singleton key for the metadata * @param object * The metadata object * @throws IllegalArgumentException * @see MetaDataKey */ // TODO: Replace the Serializable type with Object for next wicket version public final synchronized void setMetaData(final MetaDataKey key, final Object object) { metaData = key.set(metaData, object); } /** * Construct and add initializer from the provided class name. * * @param className */ private final void addInitializer(String className) { IInitializer initializer = (IInitializer)Objects.newInstance(className); if (initializer != null) { initializers.add(initializer); } } /** * Iterate initializers list, calling any {@link org.apache.wicket.IDestroyer} instances found * in it. */ private final void callDestroyers() { for (Iterator iter = initializers.iterator(); iter.hasNext();) { IInitializer initializer = iter.next(); if (initializer instanceof IDestroyer) { log.info("[" + getName() + "] destroy: " + initializer); ((IDestroyer)initializer).destroy(this); } } } /** * Iterate initializers list, calling any instances found in it. */ private final void callInitializers() { for (Iterator iter = initializers.iterator(); iter.hasNext();) { IInitializer initializer = iter.next(); log.info("[" + getName() + "] init: " + initializer); initializer.init(this); } } /** * This method is still here for backwards compatibility with 1.1 source code. The * getXXXSettings() methods are now preferred. This method will be removed post 1.2 version. * * @return Application settings * * @see Application#getApplicationSettings() * @see Application#getDebugSettings() * @see Application#getExceptionSettings() * @see Application#getMarkupSettings() * @see Application#getPageSettings() * @see Application#getRequestCycleSettings() * @see Application#getResourceSettings() * @see Application#getSecuritySettings() * @see Application#getSessionSettings() */ private Settings getSettings() { if (!settingsAccessible) { throw new WicketRuntimeException( "Use Application.init() method for configuring your application object"); } if (settings == null) { settings = new Settings(this); } return settings; } /** * @param properties * Properties map with names of any library initializers in it */ private final void load(final Properties properties) { addInitializer(properties.getProperty("initializer")); addInitializer(properties.getProperty(getName() + "-initializer")); } /** * Called when wicket servlet is destroyed. Overrides do not have to call super. * * @deprecated use {@link #onDestroy()} instead */ // TODO remove after deprecation release @Deprecated protected final void destroy() { } /** * Called when wicket servlet is destroyed. Overrides do not have to call super. */ protected void onDestroy() { } /** * @return Request cycle factory for this kind of session. * @deprecated replaced by {@link #newRequestCycle(Request, Response)} */ // TODO remove after deprecation release @Deprecated protected final Object getRequestCycleFactory() { throw new UnsupportedOperationException(); } /** * Gets the factory for creating session instances. * * @return Factory for creating session instances * @deprecated replaced by {@link #newSession(Request, Response)} */ // TODO remove after deprecation release @Deprecated protected final Object getSessionFactory() { throw new UnsupportedOperationException(); } /** * Allows for initialization of the application by a subclass. Use this method for any * application setup instead of the constructor. */ protected void init() { } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL IT. */ protected void internalDestroy() { // destroy detach listener final IDetachListener detachListener = getFrameworkSettings().getDetachListener(); if (detachListener != null) { detachListener.onDestroyListener(); } // Clear caches of Class keys so the classloader can be garbage // collected (WICKET-625) PropertyResolver.destroy(this); getMarkupSettings().getMarkupCache().shutdown(); onDestroy(); callDestroyers(); applicationKeyToApplication.remove(getApplicationKey()); Session.unset(); RequestContext.unset(); RequestCycle.set(null); } /** * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT OVERRIDE OR CALL. * * Internal initialization. */ protected void internalInit() { settingsAccessible = true; IPageSettings pageSettings = getPageSettings(); // Install default component resolvers pageSettings.addComponentResolver(new ParentResolver()); pageSettings.addComponentResolver(new AutoComponentResolver()); pageSettings.addComponentResolver(new MarkupInheritanceResolver()); pageSettings.addComponentResolver(new HtmlHeaderResolver()); pageSettings.addComponentResolver(new WicketLinkResolver()); pageSettings.addComponentResolver(new WicketMessageResolver()); pageSettings.addComponentResolver(new WicketMessageTagHandler()); pageSettings.addComponentResolver(new FragmentResolver()); pageSettings.addComponentResolver(new RelativePathPrefixHandler()); pageSettings.addComponentResolver(new EnclosureResolver()); pageSettings.addComponentResolver(new WicketContainerResolver()); pageSettings.addComponentResolver(new BorderBodyResolver()); // Install button image resource factory getResourceSettings().addResourceFactory("buttonFactory", new DefaultButtonImageResourceFactory()); String applicationKey = getApplicationKey(); applicationKeyToApplication.put(applicationKey, this); sessionStore = newSessionStore(); converterLocator = newConverterLocator(); } /** * Creates and returns a new instance of {@link IConverterLocator}. * * @return A new {@link IConverterLocator} instance */ protected IConverterLocator newConverterLocator() { return new ConverterLocator(); } /** * creates a new request logger when requests logging is enabled. * * @return The new request logger * */ protected IRequestLogger newRequestLogger() { return new RequestLogger(); } /** * Creates a new session facade. Is called once per application, and is typically not something * clients reimplement. * * @return The session facade */ protected abstract ISessionStore newSessionStore(); /** * Notifies the registered component instantiation listeners of the construction of the provided * component * * @param component * the component that is being instantiated */ final void notifyComponentInstantiationListeners(final Component component) { final int len = componentInstantiationListeners.length; for (int i = 0; i < len; i++) { componentInstantiationListeners[i].onInstantiation(component); } } /** * Adds an {@link IComponentOnBeforeRenderListener}. This method should typically only be called * during application startup; it is not thread safe. * * @param listener */ final public void addPreComponentOnBeforeRenderListener( final IComponentOnBeforeRenderListener listener) { if (componentPreOnBeforeRenderListeners == null) { componentPreOnBeforeRenderListeners = new ArrayList(); } if (componentPreOnBeforeRenderListeners.contains(listener) == false) { componentPreOnBeforeRenderListeners.add(listener); } } /** * Removes an {@link IComponentOnBeforeRenderListener}. * * @param listener */ final public void removePreComponentOnBeforeRenderListener( final IComponentOnBeforeRenderListener listener) { if (componentPreOnBeforeRenderListeners != null) { componentPreOnBeforeRenderListeners.remove(listener); if (componentPreOnBeforeRenderListeners.isEmpty()) { componentPreOnBeforeRenderListeners = null; } } } /** * Notifies the {@link IComponentOnBeforeRenderListener}s. * * @param component */ final void notifyPreComponentOnBeforeRenderListeners(final Component component) { if (componentPreOnBeforeRenderListeners != null) { for (Iterator iter = componentPreOnBeforeRenderListeners.iterator(); iter.hasNext();) { IComponentOnBeforeRenderListener listener = iter.next(); listener.onBeforeRender(component); } } } /** * Adds an {@link IComponentOnBeforeRenderListener}. This method should typically only be called * during application startup; it is not thread safe. * * @param listener */ final public void addPostComponentOnBeforeRenderListener( final IComponentOnBeforeRenderListener listener) { if (componentPostOnBeforeRenderListeners == null) { componentPostOnBeforeRenderListeners = new ArrayList(); } if (componentPostOnBeforeRenderListeners.contains(listener) == false) { componentPostOnBeforeRenderListeners.add(listener); } } /** * Removes an {@link IComponentOnBeforeRenderListener}. * * @param listener */ final public void removePostComponentOnBeforeRenderListener( final IComponentOnBeforeRenderListener listener) { if (componentPostOnBeforeRenderListeners != null) { componentPostOnBeforeRenderListeners.remove(listener); if (componentPostOnBeforeRenderListeners.isEmpty()) { componentPostOnBeforeRenderListeners = null; } } } /** * Notifies the {@link IComponentOnBeforeRenderListener}s. * * @param component */ final void notifyPostComponentOnBeforeRenderListeners(final Component component) { if (componentPostOnBeforeRenderListeners != null) { for (Iterator iter = componentPostOnBeforeRenderListeners.iterator(); iter.hasNext();) { IComponentOnBeforeRenderListener listener = iter.next(); listener.onBeforeRender(component); } } } /** * Adds an {@link IComponentOnAfterRenderListener}. This method should typically only be called * during application startup; it is not thread safe. * * @param listener */ final public void addComponentOnAfterRenderListener( final IComponentOnAfterRenderListener listener) { if (componentOnAfterRenderListeners == null) { componentOnAfterRenderListeners = new ArrayList(); } if (componentOnAfterRenderListeners.contains(listener) == false) { componentOnAfterRenderListeners.add(listener); } } /** * Removes an {@link IComponentOnAfterRenderListener}. * * @param listener */ final public void removeComponentOnAfterRenderListener( final IComponentOnAfterRenderListener listener) { if (componentOnAfterRenderListeners != null) { componentOnAfterRenderListeners.remove(listener); if (componentOnAfterRenderListeners.isEmpty()) { componentOnAfterRenderListeners = null; } } } /** * Notifies the {@link IComponentOnAfterRenderListener}s. * * @param component */ final void notifyComponentOnAfterRenderListeners(final Component component) { if (componentOnAfterRenderListeners != null) { for (Iterator iter = componentOnAfterRenderListeners.iterator(); iter.hasNext();) { IComponentOnAfterRenderListener listener = iter.next(); listener.onAfterRender(component); } } } /** * Adds a listener that will be invoked for every header response * * @param listener */ public final void addRenderHeadListener(final IHeaderContributor listener) { if (renderHeadListeners == null) { renderHeadListeners = new ArrayList(); } renderHeadListeners.add(listener); } /** * * @param listener */ public void removeRenderHeadListener(final IHeaderContributor listener) { if (renderHeadListeners != null) { renderHeadListeners.remove(listener); if (renderHeadListeners.isEmpty()) { renderHeadListeners = null; } } } /** * INTERNAL * * @param response */ public void notifyRenderHeadListener(final IHeaderResponse response) { if (renderHeadListeners != null) { for (Iterator iter = renderHeadListeners.iterator(); iter.hasNext();) { IHeaderContributor listener = iter.next(); listener.renderHead(response); } } } /** * Sets an {@link IHeaderResponseDecorator} that you want your application to use to decorate * header responses. * * @param headerResponseDecorator * your custom decorator */ public void setHeaderResponseDecorator(IHeaderResponseDecorator headerResponseDecorator) { this.headerResponseDecorator = headerResponseDecorator; } /** * INTERNAL METHOD - You shouldn't need to call this. This is called every time Wicket creates * an IHeaderResponse. It gives you the ability to incrementally add features to an * IHeaderResponse implementation by wrapping it in another implementation. * * To decorate an IHeaderResponse in your application, set the {@link IHeaderResponseDecorator} * on the application. * * @see IHeaderResponseDecorator * @param response * the response Wicket created * @return the response Wicket should use in IHeaderContributor traversal */ public final IHeaderResponse decorateHeaderResponse(IHeaderResponse response) { IHeaderResponse hr = headerResponseDecorator == null ? response : headerResponseDecorator.decorate(response); notifyRenderHeadListener(hr); return hr; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy