/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.hibernate.console; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.osgi.util.NLS; import org.hibernate.console.execution.DefaultExecutionContext; import org.hibernate.console.execution.ExecutionContext; import org.hibernate.console.execution.ExecutionContext.Command; import org.hibernate.console.execution.ExecutionContextHolder; import org.hibernate.console.preferences.ConsoleConfigurationPreferences; import org.hibernate.console.preferences.PreferencesClassPathUtils; import org.hibernate.eclipse.console.common.HibernateExtension; import org.jboss.tools.hibernate.runtime.spi.IConfiguration; import org.jboss.tools.hibernate.runtime.spi.IEnvironment; import org.jboss.tools.hibernate.runtime.spi.ISessionFactory; public class ConsoleConfiguration implements ExecutionContextHolder { private ExecutionContext executionContext; private ConsoleConfigClassLoader classLoader = null; private Map<String, FakeDelegatingDriver> fakeDrivers = new HashMap<String, FakeDelegatingDriver>(); /* TODO: move this out to the actual users of the configuraiton/sf ? */ private IConfiguration configuration; private ISessionFactory sessionFactory; //****************************** EXTENSION ********************** private String hibernateVersion = "==<None>=="; //set to some unused value //$NON-NLS-1$ private HibernateExtension extension; private void loadHibernateExtension(){ extension = new HibernateExtension(prefs); // String version = hibernateVersion == null ? "3.5" : hibernateVersion;//3.5 is a default version //$NON-NLS-1$ // HibernateExtensionDefinition def = HibernateExtensionManager.findHibernateExtensionDefinition(version); // if (def != null){ // HibernateExtension hibernateExtension = def.createHibernateExtensionInstance(); // hibernateExtension.setConsoleConfigurationPreferences(prefs); // extension = hibernateExtension; // } else { // throw new IllegalArgumentException("Can't find definition for hibernate version " + version); //$NON-NLS-1$ // } } private void updateHibernateVersion(String hibernateVersion){ if (!equals(this.hibernateVersion, hibernateVersion)){ this.hibernateVersion = hibernateVersion; loadHibernateExtension(); } } private boolean equals(String str1, String str2) { return (str1 == null ? str2 == null : str1.equals(str2) ); } public HibernateExtension getHibernateExtension(){ updateHibernateVersion(prefs.getHibernateVersion());//reinit if necessary return this.extension; } //****************************** EXTENSION ********************** public ConsoleConfiguration(ConsoleConfigurationPreferences config) { prefs = config; } /** Unique name for this configuration */ public String getName() { return prefs.getName(); } public synchronized Object execute(Command c) { if (executionContext != null) { return executionContext.execute(c); } final String msg = NLS.bind(ConsoleMessages.ConsoleConfiguration_null_execution_context, getName()); throw new HibernateConsoleRuntimeException(msg); } public ConsoleConfigurationPreferences prefs = null; /** * Reset configuration, session factory, class loader and execution context. * */ public synchronized boolean reset() { boolean resetted = false; // resetting state if (getHibernateExtension() != null ) { getHibernateExtension().reset(); getHibernateExtension().closeSessionFactory(); } if (configuration != null) { configuration = null; resetted = true; } resetted = resetted | closeSessionFactory() | cleanUpClassLoader(); if (resetted) { fireConfigurationReset(); } 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; } /** * 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 void build() { reset(); getHibernateExtension().build(); // configuration = getHibernateExtension().getConfiguration(); // reinitClassLoader(); // executionContext = new DefaultExecutionContext(getName(), classLoader); configuration = buildWith(null, true); fireConfigurationBuilt(); } 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; } } 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; } /** * @return * */ public IConfiguration buildWith(final IConfiguration cfg, final boolean includeMappings) { reinitClassLoader(); executionContext = new DefaultExecutionContext(getName(), classLoader); IConfiguration result = (IConfiguration)execute(new Command() { public Object execute() { ConfigurationFactory csf = new ConfigurationFactory(prefs, fakeDrivers); return csf.createConfiguration(cfg, includeMappings); } }); return result; } protected ClassLoader getParentClassLoader() { HibernateExtension extension = getHibernateExtension(); if (extension != null) { return extension.getHibernateService().getClassLoader(); } else { return Thread.currentThread().getContextClassLoader(); } } public IConfiguration getConfiguration() { return configuration; } /** * @return */ public boolean hasConfiguration() { return configuration != null; } public void buildMappings(){ execute(new Command() { public Object execute() { getConfiguration().buildMappings(); return null; } }); getHibernateExtension().buildMappings(); } public void buildSessionFactory() { execute(new Command() { public Object execute() { if (sessionFactory != null) { throw new HibernateConsoleRuntimeException(ConsoleMessages.ConsoleConfiguration_factory_not_closed_before_build_new_factory); } sessionFactory = getConfiguration().buildSessionFactory(); fireFactoryBuilt(); return null; } }); getHibernateExtension().buildSessionFactory(); } public ISessionFactory getSessionFactory() { return sessionFactory; } int execcount; ArrayList<ConsoleConfigurationListener> consoleCfgListeners = new ArrayList<ConsoleConfigurationListener>(); public QueryPage executeHQLQuery(final String hql) { return executeHQLQuery(hql, new QueryInputModel(extension.getHibernateService())); } public QueryPage executeHQLQuery(final String hql, final QueryInputModel queryParameters) { QueryPage qp = getHibernateExtension().executeHQLQuery(hql, queryParameters); qp.setId(++execcount); fireQueryPageCreated(qp); return qp; } public QueryPage executeBSHQuery(final String queryString, final QueryInputModel model) { QueryPage qp = getHibernateExtension().executeCriteriaQuery(queryString, model); qp.setId(++execcount); fireQueryPageCreated(qp); return qp; } @SuppressWarnings("unchecked") // clone listeners to thread safe iterate over array private ArrayList<ConsoleConfigurationListener> cloneConsoleCfgListeners() { return (ArrayList<ConsoleConfigurationListener>)consoleCfgListeners.clone(); } private void fireConfigurationBuilt() { for (ConsoleConfigurationListener view : cloneConsoleCfgListeners()) { view.configurationBuilt(this); } } private void fireConfigurationReset() { for (ConsoleConfigurationListener view : cloneConsoleCfgListeners()) { view.configurationReset(this); } } private void fireQueryPageCreated(QueryPage qp) { for (ConsoleConfigurationListener view : cloneConsoleCfgListeners()) { view.queryPageCreated(qp); } } private void fireFactoryBuilt() { for (ConsoleConfigurationListener view : cloneConsoleCfgListeners()) { view.sessionFactoryBuilt(this, sessionFactory); } } private void fireFactoryClosing(ISessionFactory sessionFactory2) { for (ConsoleConfigurationListener view : cloneConsoleCfgListeners()) { view.sessionFactoryClosing(this, sessionFactory2); } } public void addConsoleConfigurationListener(ConsoleConfigurationListener v) { consoleCfgListeners.add(v); } public void removeConsoleConfigurationListener(ConsoleConfigurationListener sfListener) { consoleCfgListeners.remove(sfListener); } public ConsoleConfigurationListener[] getConsoleConfigurationListeners() { return consoleCfgListeners.toArray(new ConsoleConfigurationListener[consoleCfgListeners.size()]); } public boolean isSessionFactoryCreated() { return sessionFactory != null; } public ConsoleConfigurationPreferences getPreferences() { return prefs; } public File getConfigXMLFile() { IEnvironment environment = getHibernateExtension().getHibernateService().getEnvironment(); File configXMLFile = null; if (prefs != null) { configXMLFile = prefs.getConfigXMLFile(); } if (configXMLFile == null) { URL url = null; //reinitClassLoader(); if (classLoader != null) { url = classLoader.findResource("hibernate.cfg.xml"); //$NON-NLS-1$ } if (url != null) { URI uri = null; try { uri = url.toURI(); configXMLFile = new File(uri); } catch (URISyntaxException e) { // ignore } } } if (configXMLFile == null) { URL url = environment.getWrappedClass().getClassLoader().getResource("hibernate.cfg.xml"); //$NON-NLS-1$ if (url != null) { URI uri = null; try { uri = url.toURI(); configXMLFile = new File(uri); } catch (URISyntaxException e) { // ignore } } } return configXMLFile; } public String toString() { return getClass().getName() + ":" + getName(); //$NON-NLS-1$ } public ExecutionContext getExecutionContext() { return executionContext; } public boolean closeSessionFactory() { boolean resetted = false; if (sessionFactory != null) { fireFactoryClosing(sessionFactory); sessionFactory.close(); sessionFactory = null; resetted = true; } if (getHibernateExtension() != null){ getHibernateExtension().closeSessionFactory(); } return resetted; } }