org.apache.wicket.Page Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.ops4j.pax.wicket.service Show documentation
Show all versions of org.ops4j.pax.wicket.service Show documentation
Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and
unloading of Wicket components and pageSources.
/*
* 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.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.authorization.UnauthorizedActionException;
import org.apache.wicket.authorization.strategies.page.SimplePageAuthorizationStrategy;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.MarkupType;
import org.apache.wicket.markup.resolver.IComponentResolver;
import org.apache.wicket.model.IModel;
import org.apache.wicket.page.IPageManager;
import org.apache.wicket.pageStore.IPageStore;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.session.ISessionStore;
import org.apache.wicket.settings.IDebugSettings;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.lang.Generics;
import org.apache.wicket.util.lang.WicketObjects;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract base class for pages. As a MarkupContainer subclass, a Page can contain a component
* hierarchy and markup in some markup language such as HTML. Users of the framework should not
* attempt to subclass Page directly. Instead they should subclass a subclass of Page that is
* appropriate to the markup type they are using, such as WebPage (for HTML markup).
*
* - Construction - When a page is constructed, it is automatically added to the current
* PageMap in the Session. When a Page is added to the Session's PageMap, the PageMap assigns the
* Page an id. A PageMap is roughly equivalent to a browser window and encapsulates a set of pages
* accessible through that window. When a popup window is created, a new PageMap is created for the
* popup.
*
*
- Identity - The Session that a Page is contained in can be retrieved by calling
* Page.getSession(). Page identifiers start at 0 for each PageMap in the Session and increment as
* new pages are added to the map. The PageMap-(and Session)-unique identifier assigned to a given
* Page can be retrieved by calling getId(). So, the first Page added to a new user Session will
* always be named "0".
*
*
- LifeCycle - Subclasses of Page which are interested in lifecycle events can override
* onBeginRequest, onEndRequest() and onModelChanged(). The onBeginRequest() method is inherited
* from Component. A call to onBeginRequest() is made for every Component on a Page before page
* rendering begins. At the end of a request (when rendering has completed) to a Page, the
* onEndRequest() method is called for every Component on the Page.
*
*
- Nested Component Hierarchy - The Page class is a subclass of MarkupContainer. All
* MarkupContainers can have "associated markup", which resides alongside the Java code by default.
* All MarkupContainers are also Component containers. Through nesting, of containers, a Page can
* contain any arbitrary tree of Components. For more details on MarkupContainers, see
* {@link org.apache.wicket.MarkupContainer}.
*
*
- Bookmarkable Pages - Pages can be constructed with any constructor when they are being
* used in a Wicket session, but if you wish to link to a Page using a URL that is "bookmarkable"
* (which implies that the URL will not have any session information encoded in it, and that you can
* call this page directly without having a session first directly from your browser), you need to
* implement your Page with a no-arg constructor or with a constructor that accepts a PageParameters
* argument (which wraps any query string parameters for a request). In case the page has both
* constructors, the constructor with PageParameters will be used.
*
*
- Models - Pages, like other Components, can have models (see {@link IModel}). A Page
* can be assigned a model by passing one to the Page's constructor, by overriding initModel() or
* with an explicit invocation of setModel(). If the model is a
* {@link org.apache.wicket.model.CompoundPropertyModel}, Components on the Page can use the Page's
* model implicitly via container inheritance. If a Component is not assigned a model, the
* initModel() override in Component will cause that Component to use the nearest CompoundModel in
* the parent chain, in this case, the Page's model. For basic CompoundModels, the name of the
* Component determines which property of the implicit page model the component is bound to. If more
* control is desired over the binding of Components to the page model (for example, if you want to
* specify some property expression other than the component's name for retrieving the model
* object), BoundCompoundPropertyModel can be used.
*
*
- Back Button - Pages can support the back button by enabling versioning with a call to
* setVersioned(boolean). If a Page is versioned and changes occur to it which need to be tracked, a
* version manager will be installed using the {@link ISessionStore}'s factory method
* newVersionManager().
*
*
- Security - See {@link IAuthorizationStrategy}, {@link SimplePageAuthorizationStrategy}
*
* @see org.apache.wicket.markup.html.WebPage
* @see org.apache.wicket.MarkupContainer
* @see org.apache.wicket.model.CompoundPropertyModel
* @see org.apache.wicket.Component
*
* @author Jonathan Locke
* @author Chris Turner
* @author Eelco Hillenius
* @author Johan Compagner
*
*/
public abstract class Page extends MarkupContainer implements IRedirectListener, IRequestablePage
{
/** True if the page hierarchy has been modified in the current request. */
private static final int FLAG_IS_DIRTY = FLAG_RESERVED3;
/** Set to prevent marking page as dirty under certain circumstances. */
private static final int FLAG_PREVENT_DIRTY = FLAG_RESERVED4;
/** True if the page should try to be stateless */
private static final int FLAG_STATELESS_HINT = FLAG_RESERVED5;
/** TODO WICKET-NG JAVADOC */
private static final int FLAG_WAS_CREATED_BOOKMARKABLE = FLAG_RESERVED8;
/** Log. */
private static final Logger log = LoggerFactory.getLogger(Page.class);
private static final long serialVersionUID = 1L;
/** Used to create page-unique numbers */
private int autoIndex;
/** Numeric version of this page's id */
private int numericId;
/** Set of components that rendered if component use checking is enabled */
private transient Set
renderedComponents;
/**
* Boolean if the page is stateless, so it doesn't have to be in the page map, will be set in
* urlFor
*/
private transient Boolean stateless = null;
/** Page parameters used to construct this page */
private final PageParameters pageParameters;
/**
* The purpose of render count is to detect stale listener interface links. For example: there
* is a page A rendered in tab 1. Then page A is opened also in tab 2. During render page state
* changes (i.e. some repeater gets rebuilt). This makes all links on tab 1 stale - because they
* no longer match the actual page state. This is done by incrementing render count. When link
* is clicked Wicket checks if it's render count matches the render count value of page
*/
private int renderCount = 0;
/**
* Constructor.
*/
protected Page()
{
this(null, null);
}
/**
* Constructor.
*
* @param model
* See Component
* @see Component#Component(String, IModel)
*/
protected Page(final IModel> model)
{
this(null, model);
}
/**
* The {@link PageParameters} parameter will be stored in this page and then those parameters
* will be used to create stateless links to this bookmarkable page.
*
* @param parameters
* externally passed parameters
* @see PageParameters
*/
protected Page(final PageParameters parameters)
{
this(parameters, null);
}
/**
* Construct.
*
* @param parameters
* @param model
*/
private Page(final PageParameters parameters, IModel> model)
{
super(null, model);
if (parameters == null)
{
pageParameters = new PageParameters();
}
else
{
pageParameters = parameters;
}
init();
}
/**
* The {@link PageParameters} object that was used to construct this page. This will be used in
* creating stateless/bookmarkable links to this page
*
* @return {@link PageParameters} The construction page parameter
*/
public PageParameters getPageParameters()
{
return pageParameters;
}
/**
* Adds a component to the set of rendered components.
*
* @param component
* The component that was rendered
*/
public final void componentRendered(final Component component)
{
// Inform the page that this component rendered
if (getApplication().getDebugSettings().getComponentUseCheck())
{
if (renderedComponents == null)
{
renderedComponents = new HashSet();
}
if (renderedComponents.add(component) == false)
{
throw new MarkupException(
"The component " +
component +
" was rendered already. You can render it only once during a render phase. Class relative path: " +
component.getClassRelativePath());
}
if (log.isDebugEnabled())
{
log.debug("Rendered " + component);
}
}
}
/**
* Detaches any attached models referenced by this page.
*/
@Override
public void detachModels()
{
super.detachModels();
}
/**
* @see org.apache.wicket.Component#internalPrepareForRender(boolean)
*/
@Override
public void internalPrepareForRender(boolean setRenderingFlag)
{
if (!isInitialized())
{
// initialize the page if not yet initialized
internalInitialize();
}
super.internalPrepareForRender(setRenderingFlag);
}
/**
* @see #dirty(boolean)
*/
public final void dirty()
{
dirty(false);
}
/** {@inheritDoc} */
public boolean setFreezePageId(boolean freeze)
{
boolean frozen = getFlag(FLAG_PREVENT_DIRTY);
setFlag(FLAG_PREVENT_DIRTY, freeze);
return frozen;
}
/**
* Mark this page as modified in the session. If versioning is supported then a new version of
* the page will be stored in {@link IPageStore page store}
*
* @param isInitialization
* a flag whether this is a page instantiation
*/
public void dirty(final boolean isInitialization)
{
checkHierarchyChange(this);
if (getFlag(FLAG_PREVENT_DIRTY))
{
return;
}
final IPageManager pageManager = getSession().getPageManager();
if (!getFlag(FLAG_IS_DIRTY) && (isVersioned() && pageManager.supportsVersioning() ||
// we need to get pageId for new page instances even when the page doesn't need
// versioning, otherwise pages override each other in the page store and back button
// support is broken
isInitialization))
{
setFlag(FLAG_IS_DIRTY, true);
setNextAvailableId();
pageManager.touchPage(this);
}
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
*
* This method is called when a component was rendered standalone. If it is a
* MarkupContainer
then the rendering for that container is checked.
*
* @param component
*/
public final void endComponentRender(Component component)
{
if (component instanceof MarkupContainer)
{
checkRendering((MarkupContainer)component);
}
else
{
renderedComponents = null;
}
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL IT.
*
* Get a page unique number, which will be increased with each call.
*
* @return A page unique number
*/
public final int getAutoIndex()
{
return autoIndex++;
}
/**
* @see org.apache.wicket.Component#getId()
*/
@Override
public final String getId()
{
return Integer.toString(numericId);
}
/**
*
* @return page class
*/
public final Class extends Page> getPageClass()
{
return getClass();
}
/**
* @return Size of this page in bytes
*/
@Override
public final long getSizeInBytes()
{
return WicketObjects.sizeof(this);
}
/**
* Returns whether the page should try to be stateless. To be stateless, getStatelessHint() of
* every component on page (and it's behavior) must return true and the page must be
* bookmarkable.
*
* @see org.apache.wicket.Component#getStatelessHint()
*/
@Override
public final boolean getStatelessHint()
{
return getFlag(FLAG_STATELESS_HINT);
}
/**
* @return This page's component hierarchy as a string
*/
public final String hierarchyAsString()
{
final StringBuilder buffer = new StringBuilder();
buffer.append("Page ").append(getId());
visitChildren(new IVisitor()
{
public void component(final Component component, final IVisit visit)
{
int levels = 0;
for (Component current = component; current != null; current = current.getParent())
{
levels++;
}
buffer.append(StringValue.repeat(levels, " "))
.append(component.getPageRelativePath())
.append(":")
.append(Classes.simpleName(component.getClass()));
}
});
return buffer.toString();
}
/**
* Bookmarkable page can be instantiated using a bookmarkable URL.
*
* @return Returns true if the page is bookmarkable.
*/
public boolean isBookmarkable()
{
return getApplication().getPageFactory().isBookmarkable(getClass());
}
/**
* Override this method and return true if your page is used to display Wicket errors. This can
* help the framework prevent infinite failure loops.
*
* @return True if this page is intended to display an error to the end user.
*/
public boolean isErrorPage()
{
return false;
}
/**
* Determine the "statelessness" of the page while not changing the cached value.
*
* @return boolean value
*/
private boolean peekPageStateless()
{
Boolean old = stateless;
Boolean res = isPageStateless();
stateless = old;
return res;
}
/**
* Gets whether the page is stateless. Components on stateless page must not render any stateful
* urls, and components on stateful page must not render any stateless urls. Stateful urls are
* urls, which refer to a certain (current) page instance.
*
* @return Whether this page is stateless
*/
public final boolean isPageStateless()
{
if (isBookmarkable() == false)
{
stateless = Boolean.FALSE;
if (getStatelessHint())
{
log.warn("Page '" + this + "' is not stateless because it is not bookmarkable, " +
"but the stateless hint is set to true!");
}
}
if (getStatelessHint() == false)
{
return false;
}
if (stateless == null)
{
if (isStateless() == false)
{
stateless = Boolean.FALSE;
}
}
if (stateless == null)
{
Component statefulComponent = visitChildren(Component.class,
new IVisitor()
{
public void component(final Component component, final IVisit visit)
{
if (!component.isStateless())
{
visit.stop(component);
}
}
});
stateless = statefulComponent == null;
if (log.isDebugEnabled() && !stateless.booleanValue() && getStatelessHint())
{
log.debug("Page '{}' is not stateless because of component with path '{}'.", this,
statefulComponent.getPageRelativePath());
}
}
return stateless;
}
/**
* Redirect to this page.
*
* @see org.apache.wicket.IRedirectListener#onRedirect()
*/
public final void onRedirect()
{
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
*
* Set the id for this Page. This method is called by PageMap when a Page is added because the
* id, which is assigned by PageMap, is not known until this time.
*
* @param id
* The id
*/
public final void setNumericId(final int id)
{
numericId = id;
}
/**
* Sets whether the page should try to be stateless. To be stateless, getStatelessHint() of
* every component on page (and it's behavior) must return true and the page must be
* bookmarkable.
*
* @param value
* whether the page should try to be stateless
*/
public final void setStatelessHint(boolean value)
{
if (value && !isBookmarkable())
{
throw new WicketRuntimeException(
"Can't set stateless hint to true on a page when the page is not bookmarkable, page: " +
this);
}
setFlag(FLAG_STATELESS_HINT, value);
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
*
* This method is called when a component will be rendered standalone.
*
* @param component
*
*/
public final void startComponentRender(Component component)
{
renderedComponents = null;
}
/**
* Get the string representation of this container.
*
* @return String representation of this container
*/
@Override
public String toString()
{
return "[Page class = " + getClass().getName() + ", id = " + getId() + ", render count = " +
getRenderCount() + "]";
}
/**
* Throw an exception if not all components rendered.
*
* @param renderedContainer
* The page itself if it was a full page render or the container that was rendered
* standalone
*/
private void checkRendering(final MarkupContainer renderedContainer)
{
// If the application wants component uses checked and
// the response is not a redirect
final IDebugSettings debugSettings = getApplication().getDebugSettings();
if (debugSettings.getComponentUseCheck())
{
final List unrenderedComponents = new ArrayList();
final StringBuilder buffer = new StringBuilder();
renderedContainer.visitChildren(new IVisitor()
{
public void component(final Component component, final IVisit visit)
{
// If component never rendered
if (renderedComponents == null || !renderedComponents.contains(component))
{
// If not an auto component ...
if (!component.isAuto() && component.isVisibleInHierarchy())
{
// Increase number of unrendered components
unrenderedComponents.add(component);
// Add to explanatory string to buffer
buffer.append(Integer.toString(unrenderedComponents.size()))
.append(". ")
.append(component)
.append("\n");
String metadata = component.getMetaData(Component.CONSTRUCTED_AT_KEY);
if (metadata != null)
{
buffer.append(metadata);
}
metadata = component.getMetaData(Component.ADDED_AT_KEY);
if (metadata != null)
{
buffer.append(metadata);
}
}
else
{
// if the component is not visible in hierarchy we
// should not visit its children since they are also
// not visible
visit.dontGoDeeper();
}
}
}
});
// Throw exception if any errors were found
if (unrenderedComponents.size() > 0)
{
renderedComponents = null;
List transparentContainerChildren = Generics.newArrayList();
Iterator iterator = unrenderedComponents.iterator();
outerWhile : while (iterator.hasNext())
{
Component component = iterator.next();
// If any of the transparentContainerChildren is a parent to component, then
// ignore it.
for (Component transparentContainerChild : transparentContainerChildren)
{
MarkupContainer parent = component.getParent();
while (parent != null)
{
if (parent == transparentContainerChild)
{
iterator.remove();
continue outerWhile;
}
parent = parent.getParent();
}
}
if (hasInvisibleTransparentChild(component.getParent(), component))
{
// If we found a transparent container that isn't visible then ignore this
// component and only do a debug statement here.
if (log.isDebugEnabled())
{
log.debug(
"Component {} wasn't rendered but might have a transparent parent.",
component);
}
transparentContainerChildren.add(component);
iterator.remove();
continue outerWhile;
}
}
// if still > 0
if (unrenderedComponents.size() > 0)
{
// Throw exception
throw new WicketRuntimeException(
"The component(s) below failed to render. A common problem is that you have added a component in code but forgot to reference it in the markup (thus the component will never be rendered).\n\n" +
buffer.toString());
}
}
}
// Get rid of set
renderedComponents = null;
}
private boolean hasInvisibleTransparentChild(final MarkupContainer root, final Component self)
{
for (Component sibling : root)
{
if ((sibling != self) && (sibling instanceof IComponentResolver) &&
(sibling instanceof MarkupContainer))
{
if (!sibling.isVisible())
{
return true;
}
else
{
boolean rtn = hasInvisibleTransparentChild((MarkupContainer)sibling, self);
if (rtn == true)
{
return true;
}
}
}
}
return false;
}
/**
* Initializes Page by adding it to the Session and initializing it.
*/
private void init()
{
if (isBookmarkable())
{
setStatelessHint(true);
}
// Set versioning of page based on default
setVersioned(getApplication().getPageSettings().getVersionPagesByDefault());
// All Pages are born dirty so they get clustered right away
dirty(true);
// this is a bit of a dirty hack, but calling dirty(true) results in isStateless called
// which is bound to set the stateless cache to true as there are no components yet
stateless = null;
}
/**
*
*/
private void setNextAvailableId()
{
setNumericId(getSession().nextPageId());
}
/**
* This method will be called for all components that are changed on the page So also auto
* components or components that are not versioned.
*
* If the parent is given that it was a remove or add from that parent of the given component.
* else it was just a internal property change of that component.
*
* @param component
* @param parent
*/
protected void componentChanged(Component component, MarkupContainer parent)
{
if (!component.isAuto())
{
dirty();
}
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL OR OVERRIDE.
*
* @see org.apache.wicket.Component#internalOnModelChanged()
*/
@Override
protected final void internalOnModelChanged()
{
visitChildren(new IVisitor()
{
public void component(final Component component, final IVisit visit)
{
// If form component is using form model
if (component.sameInnermostModel(Page.this))
{
component.modelChanged();
}
}
});
}
@Override
void internalOnAfterConfigure()
{
super.internalOnAfterConfigure();
// check if the page can be rendered
if (!isActionAuthorized(RENDER))
{
if (log.isDebugEnabled())
{
log.debug("Page not allowed to render: " + this);
}
throw new UnauthorizedActionException(this, Component.RENDER);
}
}
/**
*
* @see org.apache.wicket.Component#onBeforeRender()
*/
@Override
protected void onBeforeRender()
{
// Make sure it is really empty
renderedComponents = null;
// if the page is stateless, reset the flag so that it is tested again
if (Boolean.TRUE.equals(stateless))
{
stateless = null;
}
super.onBeforeRender();
// If any of the components on page is not stateless, we need to bind the session
// before we start rendering components, as then jsessionid won't be appended
// for links rendered before first stateful component
if (getSession().isTemporary() && !peekPageStateless())
{
getSession().bind();
}
}
/**
* @see org.apache.wicket.Component#onAfterRender()
*/
@Override
protected void onAfterRender()
{
super.onAfterRender();
// Check rendering if it happened fully
checkRendering(this);
// clean up debug meta data if component check is on
if (getApplication().getDebugSettings().getComponentUseCheck())
{
visitChildren(new IVisitor()
{
public void component(final Component component, final IVisit visit)
{
component.setMetaData(Component.CONSTRUCTED_AT_KEY, null);
component.setMetaData(Component.ADDED_AT_KEY, null);
}
});
}
if (!isPageStateless())
{
// trigger creation of the actual session in case it was deferred
getSession().getSessionStore().getSessionId(RequestCycle.get().getRequest(), true);
// Add/touch the response page in the session.
getSession().getPageManager().touchPage(this);
}
if (getApplication().getDebugSettings().isOutputMarkupContainerClassName())
{
Class> klass = getClass();
while (klass.isAnonymousClass())
{
klass = klass.getSuperclass();
}
getResponse().write("\n");
}
}
/**
* @see org.apache.wicket.Component#onDetach()
*/
@Override
protected void onDetach()
{
if (log.isDebugEnabled())
{
log.debug("ending request for page " + this + ", request " + getRequest());
}
setFlag(FLAG_IS_DIRTY, false);
super.onDetach();
}
/**
* @see org.apache.wicket.MarkupContainer#onRender()
*/
@Override
protected void onRender()
{
// Loop through the markup in this container
MarkupStream markupStream = new MarkupStream(getMarkup());
renderAll(markupStream, null);
}
/**
* A component was added.
*
* @param component
* The component that was added
*/
final void componentAdded(final Component component)
{
if (!component.isAuto())
{
dirty();
}
}
/**
* A component's model changed.
*
* @param component
* The component whose model is about to change
*/
final void componentModelChanging(final Component component)
{
dirty();
}
/**
* A component was removed.
*
* @param component
* The component that was removed
*/
final void componentRemoved(final Component component)
{
if (!component.isAuto())
{
dirty();
}
}
/**
*
* @param component
*/
final void componentStateChanging(final Component component)
{
if (!component.isAuto())
{
dirty();
}
}
/**
* Set page stateless
*
* @param stateless
*/
void setPageStateless(Boolean stateless)
{
this.stateless = stateless;
}
/**
* @see org.apache.wicket.MarkupContainer#getMarkupType()
*/
@Override
public MarkupType getMarkupType()
{
throw new UnsupportedOperationException(
"Page does not support markup. This error can happen if you have extended Page directly, instead extend WebPage");
}
/**
* Gets page instance's unique identifier
*
* @return instance unique identifier
*/
public PageReference getPageReference()
{
setStatelessHint(false);
return new PageReference(numericId);
}
/**
* @see org.apache.wicket.page.IManageablePage#getPageId()
*/
public int getPageId()
{
return numericId;
}
/**
* @see org.apache.wicket.request.component.IRequestablePage#getRenderCount()
*/
public int getRenderCount()
{
return renderCount;
}
/**
* TODO WICKET-NG javadoc
*
* @param wasCreatedBookmarkable
*/
public final void setWasCreatedBookmarkable(boolean wasCreatedBookmarkable)
{
setFlag(FLAG_WAS_CREATED_BOOKMARKABLE, wasCreatedBookmarkable);
}
/** TODO WICKET-NG javadoc */
public final boolean wasCreatedBookmarkable()
{
return getFlag(FLAG_WAS_CREATED_BOOKMARKABLE);
}
/**
* @see org.apache.wicket.request.component.IRequestablePage#renderPage()
*/
public void renderPage()
{
// page id is frozen during the render
final boolean frozen = setFreezePageId(true);
try
{
++renderCount;
render();
}
finally
{
setFreezePageId(frozen);
}
}
/**
* THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
*
* @param component
* @return if this component was render in this page
*/
public final boolean wasRendered(Component component)
{
return renderedComponents != null && renderedComponents.contains(component);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy