org.apache.wicket.session.DefaultPageFactory 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.session;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.wicket.IPageFactory;
import org.apache.wicket.Page;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.authorization.AuthorizationException;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.request.RequestHandlerStack.ReplaceHandlerException;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.lang.Generics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A factory that constructs Pages.
*
* @see org.apache.wicket.settings.ISessionSettings#setPageFactory(org.apache.wicket.IPageFactory)
* @see IPageFactory
*
* @author Juergen Donnerstag
* @author Jonathan Locke
*/
public final class DefaultPageFactory implements IPageFactory
{
/** Log for reporting. */
private static final Logger log = LoggerFactory.getLogger(DefaultPageFactory.class);
/** Map of Constructors for Page subclasses */
private final Map, Constructor>> constructorForClass = Generics.newConcurrentHashMap();
/**
* {@link #isBookmarkable(Class)} is expensive, we cache the result here
*/
private final ConcurrentMap pageToBookmarkableCache = new ConcurrentHashMap();
public final Page newPage(final Class pageClass)
{
try
{
// throw an exception in case default constructor is missing
// => improved error message
Constructor extends IRequestablePage> constructor = pageClass.getConstructor((Class[])null);
return processPage(newPage(constructor, null), null);
}
catch (NoSuchMethodException e)
{
// a bit of a hack here..
Constructor> constructor = constructor(pageClass, PageParameters.class);
if (constructor != null)
{
PageParameters pp = new PageParameters();
return processPage(newPage(constructor, pp), pp);
}
else
{
throw new WicketRuntimeException("Unable to create page from " + pageClass +
". Class does not have a visible default contructor.", e);
}
}
}
public final Page newPage(final Class pageClass,
final PageParameters parameters)
{
// Try to get constructor that takes PageParameters
Constructor> constructor = constructor(pageClass, PageParameters.class);
// If we got a PageParameters constructor
if (constructor != null)
{
final PageParameters nullSafeParams = parameters == null ? new PageParameters() : parameters;
// return new Page(parameters)
return processPage(newPage(constructor, nullSafeParams), nullSafeParams);
}
// Always try default constructor if one exists
return processPage(newPage(pageClass), parameters);
}
/**
* Looks up a one-arg Page constructor by class and argument type.
*
* @param pageClass
* The class of page
* @param argumentType
* The argument type
* @return The page constructor, or null if no one-arg constructor can be found taking the given
* argument type.
*/
private final Constructor> constructor(final Class pageClass,
final Class argumentType)
{
// Get constructor for page class from cache
Constructor> constructor = constructorForClass.get(pageClass);
// Need to look up?
if (constructor == null)
{
try
{
// Try to find the constructor
constructor = pageClass.getConstructor(new Class[] { argumentType });
// Store it in the cache
constructorForClass.put(pageClass, constructor);
if (log.isDebugEnabled())
{
log.debug("Found constructor for Page of type '{}' and argument of type '{}'.",
pageClass, argumentType);
}
}
catch (NoSuchMethodException e)
{
if (log.isDebugEnabled())
{
log.debug(
"Page of type '{}' has not visible constructor with an argument of type '{}'.",
pageClass, argumentType);
}
return null;
}
}
return constructor;
}
/**
* Creates a new Page using the given constructor and argument.
*
* @param constructor
* The constructor to invoke
* @param argument
* The argument to pass to the constructor or null to pass no arguments
* @return The new page
* @throws WicketRuntimeException
* Thrown if the Page cannot be instantiated using the given constructor and
* argument.
*/
private final Page newPage(final Constructor> constructor, final Object argument)
{
try
{
if (argument != null)
{
return (Page)constructor.newInstance(argument);
}
else
{
return (Page)constructor.newInstance();
}
}
catch (InstantiationException e)
{
throw new WicketRuntimeException(createDescription(constructor, argument), e);
}
catch (IllegalAccessException e)
{
throw new WicketRuntimeException(createDescription(constructor, argument), e);
}
catch (InvocationTargetException e)
{
if (e.getTargetException() instanceof ReplaceHandlerException ||
e.getTargetException() instanceof AuthorizationException ||
e.getTargetException() instanceof MarkupException)
{
throw (RuntimeException)e.getTargetException();
}
throw new WicketRuntimeException(createDescription(constructor, argument), e);
}
}
private Page processPage(final Page page, final PageParameters pageParameters)
{
// the page might have not propagate page parameters from constructor. if that's the case
// we force the parameters
if ((pageParameters != null) && (page.getPageParameters() != pageParameters))
{
page.getPageParameters().overwriteWith(pageParameters);
}
page.setWasCreatedBookmarkable(true);
return page;
}
private String createDescription(final Constructor> constructor, final Object argument)
{
String msg;
if (argument != null)
{
msg = "Can't instantiate page using constructor '" + constructor + "' and argument '" +
argument;
}
else
{
msg = "Can't instantiate page using constructor '" + constructor;
}
return msg + "'. Might be it doesn't exist, may be it is not visible (public).";
}
public boolean isBookmarkable(Class pageClass)
{
Boolean bookmarkable = pageToBookmarkableCache.get(pageClass.getName());
if (bookmarkable == null)
{
try
{
if (pageClass.getConstructor(new Class[] { }) != null)
{
bookmarkable = Boolean.TRUE;
}
}
catch (Exception ignore)
{
try
{
if (pageClass.getConstructor(new Class[] { PageParameters.class }) != null)
{
bookmarkable = Boolean.TRUE;
}
}
catch (Exception ignored)
{
}
}
if (bookmarkable == null)
{
bookmarkable = Boolean.FALSE;
}
pageToBookmarkableCache.put(pageClass.getName(), bookmarkable);
}
return bookmarkable;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy