/*
* Databinder: a simple bridge from Wicket to Hibernate
* Copyright (C) 2006 Nathan Hamblen nathan@technically.us
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.databinder.hib;
import java.util.HashMap;
import net.databinder.DataApplicationBase;
import net.databinder.components.hib.DataBrowser;
import org.apache.wicket.Application;
import org.apache.wicket.Request;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Response;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.protocol.http.WebRequest;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
/**
* Optional Databinder base Application class for configuration and session management.
* Supports multiple session factories with key objects.
* @author Nathan Hamblen
*/
public abstract class DataApplication extends DataApplicationBase implements HibernateApplication {
/** App-wide session factories */
private HashMap<Object, SessionFactory> hibernateSessionFactories = new HashMap<Object, SessionFactory>();
/**
* Initializes a default Hibernate session factory and mounts a page for
* the data browser. This is called automatically during start-up. Applications
* with one session factory will not normally need to override this method;
* see related methods to override specific tasks.
* @see #buildHibernateSessionFactory(Object) aoe
* @see #mountDataBrowser()
*/
protected void dataInit() {
buildHibernateSessionFactory(null);
if (isDataBrowserAllowed())
mountDataBrowser();
}
/**
* Bookmarkable subclass of DataBrowser page. Access to the page is permitted
* only if the current application is assignable to DataApplication
* and returns true for isDataBrowserAllowed().
* @see DataBrowser
*/
public static class BmarkDataBrowser extends DataBrowser {
public BmarkDataBrowser() {
super(((DataApplication)Application.get()).isDataBrowserAllowed());
}
}
/**
* Mounts Data Diver to /dbrowse. Override to mount elsewhere, or not mount at all.
* This method is only called if isDataBrowserAllowed() returns true in init().
*/
protected void mountDataBrowser() {
mountBookmarkablePage("/dbrowse", BmarkDataBrowser.class);
}
/**
* Called by init to create Hibernate session factory and load a configuration. Passes
* an empty new AnnotationConfiguration to buildHibernateSessionFactory(key, config) by
* default. Override if creating a configuration externally.
* @param key session factory key; the default key is null
*/
public void buildHibernateSessionFactory(Object key) {
buildHibernateSessionFactory(key, new AnnotationConfiguration());
}
/**
* Builds and a session factory with the given configuration. Passes config
* through configureHibernate methods.
* @param key session factory key; the default key is null
* @param config annotation conifuration
* @see #configureHibernateEssentials(AnnotationConfiguration)
* @see #configureHibernate(AnnotationConfiguration, Object)
*/
final public void buildHibernateSessionFactory(Object key, AnnotationConfiguration config) {
configureHibernateEssentials(config);
configureHibernate(config, key);
setHibernateSessionFactory(key, config.buildSessionFactory());
}
/**
* Configures the session factory associated with the key. The default implementation
* calls the configureHibernate(config) method and ignores the key.
* For applications with multiple session factories, override this method to
* perform key-specific configuration here instead.
* @param config configuration to update
* @param key object, or null for the default factory
*/
protected void configureHibernate(AnnotationConfiguration config, Object key) {
configureHibernate(config);
}
/**
* For Hibernate settings that should not normally be overriden by client
* applications. Specifically, this method sets Hibernate for a ManagedSessionContext,
* the session lookup method used by DataRequestCycle.
* @param config Hibernate configuration
*/
protected void configureHibernateEssentials(AnnotationConfiguration config) {
config.setProperty("hibernate.current_session_context_class","managed");
}
/**
* Configures the default session factory; override to add annotated classes
* but don't forget to call this super-implementation if you want its defaults.
* When running in development the session factory is set for
* hbm2ddl auto-updating to create and add columns to tables
* as required. For deployment it is configured for C3P0 connection pooling.
* @param config used to build Hibernate session factory
*/
protected void configureHibernate(AnnotationConfiguration config) {
if (isDevelopment())
config.setProperty("hibernate.hbm2ddl.auto", "update");
else {
config
.setProperty("hibernate.connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider")
.setProperty("hibernate.c3p0.max_size", "20")
.setProperty("hibernate.c3p0.timeout","3000")
.setProperty("hibernate.c3p0.idle_test_period", "300");
}
}
/**
* @param key object, or null for the default factory
* @return the retained session factory
*/
public SessionFactory getHibernateSessionFactory(Object key) {
SessionFactory sf = hibernateSessionFactories.get(key);
if (sf == null)
if (key == null)
throw new WicketRuntimeException("The default Hibernate session factory has not been " +
"initialized. This is normally done in DataApplication.init().");
else
throw new WicketRuntimeException("Session factory not found for key: " + key);
return sf;
}
/**
* @param key object, or null for the default factory
* @param sf session factory to retain
*/
protected void setHibernateSessionFactory(Object key, SessionFactory sf) {
hibernateSessionFactories.put(key, sf);
}
/**
* @return a DataRequestCycle
* @see DataRequestCycle
*/
@Override
public RequestCycle newRequestCycle(Request request, Response response) {
return new DataRequestCycle(this, (WebRequest) request, response);
}
/**
* Returns true if development mode is enabled. Override for other behavior.
* @return true if the Data Browser page should be enabled
*/
protected boolean isDataBrowserAllowed() {
return isDevelopment();
}
}