package org.hibernate.eclipse.console.common; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.DriverManager; import java.sql.SQLException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.osgi.util.NLS; import org.hibernate.console.ConfigurationFactory; import org.hibernate.console.ConsoleConfigClassLoader; import org.hibernate.console.ConsoleMessages; import org.hibernate.console.FakeDelegatingDriver; import org.hibernate.console.QueryInputModel; import org.hibernate.console.QueryPage; import org.hibernate.console.execution.DefaultExecutionContext; import org.hibernate.console.execution.ExecutionContext; import org.hibernate.console.execution.ExecutionContext.Command; import org.hibernate.console.preferences.ConsoleConfigurationPreferences; import org.hibernate.console.preferences.PreferencesClassPathUtils; import org.jboss.tools.hibernate.runtime.spi.HibernateException; import org.jboss.tools.hibernate.runtime.spi.IConfiguration; import org.jboss.tools.hibernate.runtime.spi.IService; import org.jboss.tools.hibernate.runtime.spi.ISession; import org.jboss.tools.hibernate.runtime.spi.ISessionFactory; import org.jboss.tools.hibernate.runtime.spi.ServiceLookup; public class HibernateExtension { private IConfiguration configuration; private ConsoleConfigClassLoader classLoader = null; private ExecutionContext executionContext; private ConsoleConfigurationPreferences prefs; private ISessionFactory sessionFactory; private Map<String, FakeDelegatingDriver> fakeDrivers = new HashMap<String, FakeDelegatingDriver>(); private ConsoleExtension consoleExtension; public HibernateExtension(ConsoleConfigurationPreferences prefs) { this.prefs = prefs; consoleExtension = new ConsoleExtension(); consoleExtension.setHibernateExtention(this); } public ConsoleExtension getConsoleExtension() { return consoleExtension; } protected ConsoleConfigClassLoader createClassLoader(final URL[] customClassPathURLs) { ConsoleConfigClassLoader classLoader = AccessController.doPrivileged(new PrivilegedAction<ConsoleConfigClassLoader>() { public ConsoleConfigClassLoader run() { return new ConsoleConfigClassLoader(customClassPathURLs, getParentClassLoader()) { protected Class<?> findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException cnfe) { throw cnfe; } catch (IllegalStateException e){ e.printStackTrace(); throw e; } } protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { try { return super.loadClass(name, resolve); } catch (ClassNotFoundException cnfe) { throw cnfe; } } public Class<?> loadClass(String name) throws ClassNotFoundException { try { return super.loadClass(name); } catch (ClassNotFoundException cnfe) { throw cnfe; } } public URL getResource(String name) { return super.getResource(name); } }; } }); return classLoader; } private ClassLoader getParentClassLoader() { return getHibernateService().getClassLoader(); } public String getHibernateVersion() { String result = prefs.getHibernateVersion(); // return hibernate 3.5 by default // TODO do something smarter here return result != null ? result : "3.5"; //$NON-NLS-1$ } public QueryPage executeHQLQuery(final String hql, final QueryInputModel queryParameters) { return (QueryPage)execute(new Command() { public Object execute() { ISession session = sessionFactory.openSession(); QueryPage qp = new HQLQueryPage(HibernateExtension.this, hql,queryParameters); qp.setSession(session); return qp; } }); } public QueryPage executeCriteriaQuery(final String criteriaCode, final QueryInputModel model) { return (QueryPage)execute(new Command() { public Object execute() { ISession session = sessionFactory.openSession(); QueryPage qp = new JavaPage(HibernateExtension.this,criteriaCode,model); qp.setSession(session); return qp; } }); } public void build() { configuration = buildWith(null, true); } public void buildSessionFactory() { execute(new Command() { public Object execute() { if (sessionFactory != null) { throw new HibernateException("Factory was not closed before attempt to build a new Factory"); //$NON-NLS-1$ } sessionFactory = configuration.buildSessionFactory(); return null; } }); } public boolean closeSessionFactory() { boolean res = false; if (sessionFactory != null) { sessionFactory.close(); sessionFactory = null; res = true; } return res; } public IConfiguration buildWith(final IConfiguration cfg, final boolean includeMappings) { reinitClassLoader(); //TODO handle user libraries here executionContext = new DefaultExecutionContext(prefs.getName(), classLoader); IConfiguration result = (IConfiguration)execute(new Command() { public Object execute() { ConfigurationFactory cf = new ConfigurationFactory(prefs, fakeDrivers); return cf.createConfiguration(cfg, includeMappings); } }); return result; } /** * Create class loader - so it uses the original urls list from preferences. */ protected void reinitClassLoader() { //the class loader caches user's compiled classes //need to rebuild it on every console configuration rebuild to pick up latest versions. final URL[] customClassPathURLs = PreferencesClassPathUtils.getCustomClassPathURLs(prefs); cleanUpClassLoader(); classLoader = createClassLoader(customClassPathURLs); } public String getName() { return prefs.getName(); } public Object execute(Command c) { if (executionContext != null) { return executionContext.execute(c); } final String msg = NLS.bind(ConsoleMessages.ConsoleConfiguration_null_execution_context, getName()); throw new HibernateException(msg); } public boolean reset() { boolean resetted = false; // reseting state if (configuration != null) { configuration = null; resetted = true; } resetted = resetted | closeSessionFactory() | cleanUpClassLoader(); executionContext = null; return resetted; } protected boolean cleanUpClassLoader() { boolean resetted = false; if (executionContext != null) { executionContext.execute(new Command() { public Object execute() { Iterator<FakeDelegatingDriver> it = fakeDrivers.values().iterator(); while (it.hasNext()) { try { DriverManager.deregisterDriver(it.next()); } catch (SQLException e) { // ignore } } return null; } }); } if (fakeDrivers.size() > 0) { fakeDrivers.clear(); resetted = true; } ClassLoader classLoaderTmp = classLoader; while (classLoaderTmp != null) { if (classLoaderTmp instanceof ConsoleConfigClassLoader) { ((ConsoleConfigClassLoader)classLoaderTmp).close(); resetted = true; } classLoaderTmp = classLoaderTmp.getParent(); } if (classLoader != null) { classLoader = null; resetted = true; } return resetted; } public boolean hasConfiguration() { return configuration != null; } /** * @return */ public IConfiguration getConfiguration() { return configuration; } public boolean isSessionFactoryCreated() { return sessionFactory != null; } public String generateSQL(final String query) { return QueryHelper.generateSQL(executionContext, sessionFactory, query, getHibernateService()); } public void buildMappings() { execute(new Command() { public Object execute() { getConfiguration().buildMappings(); return null; } }); } public boolean hasExecutionContext() { return executionContext != null; } public String getConsoleConfigurationName() { return prefs.getName(); } public IService getHibernateService() { return ServiceLookup.findService(getHibernateVersion()); } }