| /* |
| * $Id$ |
| * $Revision$ $Date$ |
| * |
| * ============================================================================== |
| * Licensed 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 wicket; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Map; |
| |
| import wicket.util.concurrent.ConcurrentHashMap; |
| |
| /** |
| * A factory that constructs Pages. |
| * |
| * @see ApplicationSettings#setDefaultPageFactory(IPageFactory) |
| * @see IPageFactory |
| * @author Juergen Donnerstag |
| * @author Jonathan Locke |
| */ |
| public final class DefaultPageFactory implements IPageFactory |
| { |
| /** Map of Constructors for Page subclasses */ |
| private final Map constructorForClass = new ConcurrentHashMap(); |
| |
| /** |
| * @see IPageFactory#newPage(Class) |
| */ |
| public final Page newPage(final Class pageClass) |
| { |
| try |
| { |
| // throw an exception in case default constructor is missing |
| // => improved error message |
| pageClass.getConstructor((Class[])null); |
| |
| return (Page)pageClass.newInstance(); |
| } |
| catch (NoSuchMethodException e) |
| { |
| throw new WicketRuntimeException("Unable to create page from " |
| + pageClass + ". Class does not have a default contructor", e); |
| } |
| catch (InstantiationException e) |
| { |
| throw new WicketRuntimeException("Unable to create page from " + pageClass, e); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw new WicketRuntimeException("Unable to create page from " + pageClass, e); |
| } |
| } |
| |
| /** |
| * @see IPageFactory#newPage(Class, PageParameters) |
| */ |
| 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) |
| { |
| // return new Page(parameters) |
| return newPage(constructor, parameters); |
| } |
| |
| // Always try default constructor if one exists |
| return newPage(pageClass); |
| } |
| |
| /** |
| * 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 = (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); |
| } |
| catch (NoSuchMethodException e) |
| { |
| 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 |
| * @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 |
| { |
| return (Page)constructor.newInstance(new Object[] { argument }); |
| } |
| catch (InstantiationException e) |
| { |
| throw new WicketRuntimeException("Can't instantiate page using constructor " |
| + constructor + " and argument " + argument, e); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw new WicketRuntimeException("Can't instantiate page using constructor " |
| + constructor + " and argument " + argument, e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw new WicketRuntimeException("Can't instantiate page using constructor " |
| + constructor + " and argument " + argument, e); |
| } |
| } |
| } |