| /* |
| * 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.cocoon.components.hsqldb; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| import org.apache.avalon.framework.CascadingRuntimeException; |
| import org.apache.avalon.framework.activity.Startable; |
| import org.apache.avalon.framework.context.Context; |
| import org.apache.avalon.framework.context.ContextException; |
| import org.apache.avalon.framework.context.Contextualizable; |
| import org.apache.avalon.framework.logger.AbstractLogEnabled; |
| import org.apache.avalon.framework.parameters.Parameterizable; |
| import org.apache.avalon.framework.parameters.Parameters; |
| import org.apache.avalon.framework.parameters.ParameterException; |
| import org.apache.avalon.framework.service.ServiceException; |
| import org.apache.avalon.framework.service.ServiceManager; |
| import org.apache.avalon.framework.service.Serviceable; |
| import org.apache.avalon.framework.thread.ThreadSafe; |
| |
| import org.apache.cocoon.Constants; |
| import org.apache.cocoon.components.thread.RunnableManager; |
| import org.hsqldb.Database; |
| import org.hsqldb.DatabaseManager; |
| |
| /** |
| * This class runs an instance of the HSQLDB HSQL protocol network database server. |
| * |
| * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> |
| * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a> |
| * @version CVS $Id$ |
| */ |
| public class ServerImpl extends AbstractLogEnabled |
| implements Server, Parameterizable, Contextualizable, |
| ThreadSafe, Runnable, Serviceable, Startable { |
| |
| private static final boolean DEFAULT_TRACE = false; |
| private static final boolean DEFAULT_SILENT = true; |
| private static final int DEFAULT_PORT = 9002; |
| private static final String CONTEXT_PROTOCOL = "context:/"; |
| private static final String DEFAULT_DB_NAME = "cocoondb"; |
| private static final String DEFAULT_DB_PATH = "context://WEB-INF/db"; |
| |
| /** Cocoon context **/ |
| private org.apache.cocoon.environment.Context cocoonContext; |
| |
| /** The HSQLDB HSQL protocol network database server instance **/ |
| private org.hsqldb.Server hsqlServer = new org.hsqldb.Server(); |
| |
| /** The threadpool name to be used for daemon thread */ |
| private String m_daemonThreadPoolName = "daemon"; |
| |
| /** The {@link ServiceManager} instance */ |
| private ServiceManager m_serviceManager; |
| |
| /** Contextualize this class */ |
| public void contextualize(Context context) throws ContextException { |
| cocoonContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); |
| } |
| |
| /** |
| * Initialize the ServerImpl. |
| * Posible options: |
| * <ul> |
| * <li>port = port where the server is listening</li> |
| * <li>silent = false => display all queries</li> |
| * <li>trace = print JDBC trace messages</li> |
| * <li>name = name of the HSQL-DB</li> |
| * <li>path = path to the database - context-protocol is resolved</li> |
| * </ul> |
| */ |
| public void parameterize(Parameters params) throws ParameterException { |
| hsqlServer.setLogWriter(null); /* Remove console log */ |
| hsqlServer.setErrWriter(null); /* Remove console log */ |
| hsqlServer.setPort(params.getParameterAsInteger("port", DEFAULT_PORT)); |
| hsqlServer.setSilent(params.getParameterAsBoolean("silent", DEFAULT_SILENT)); |
| hsqlServer.setTrace(params.getParameterAsBoolean("trace", DEFAULT_TRACE)); |
| hsqlServer.setNoSystemExit(true); |
| if (getLogger().isDebugEnabled()) { |
| getLogger().debug("Configure HSQLDB with port: " + hsqlServer.getPort() + |
| ", silent: " + hsqlServer.isSilent() + |
| ", trace: " + hsqlServer.isTrace()); |
| } |
| |
| m_daemonThreadPoolName = params.getParameter("thread-pool-name", m_daemonThreadPoolName); |
| |
| final String dbCfgPath = params.getParameter("path", DEFAULT_DB_PATH); |
| String dbPath = dbCfgPath; |
| // Test if we are running inside a WAR file |
| if(dbPath.startsWith(ServerImpl.CONTEXT_PROTOCOL)) { |
| dbPath = this.cocoonContext.getRealPath(dbPath.substring(ServerImpl.CONTEXT_PROTOCOL.length())); |
| } |
| if (dbPath == null) { |
| throw new ParameterException("The hsqldb cannot be used inside an unexpanded WAR file. " + |
| "Real path for <" + dbCfgPath + "> is null."); |
| } |
| |
| String dbName = params.getParameter("name", DEFAULT_DB_NAME); |
| try { |
| hsqlServer.setDatabasePath(0, new File(dbPath).getCanonicalPath() + File.separator + dbName); |
| hsqlServer.setDatabaseName(0, dbName); |
| } catch (IOException e) { |
| throw new ParameterException("Could not get database directory <" + dbPath + ">", e); |
| } |
| |
| if (getLogger().isDebugEnabled()) { |
| getLogger().debug("Database path is <" + hsqlServer.getDatabasePath(0, true) + ">"); |
| } |
| } |
| |
| /** |
| * @param serviceManager The <@link ServiceManager} instance |
| * @throws ServiceException In case we cannot find a service needed |
| */ |
| public void service(ServiceManager serviceManager) throws ServiceException { |
| m_serviceManager = serviceManager; |
| } |
| |
| /** Start the server */ |
| public void start() { |
| RunnableManager runnableManager = null; |
| try { |
| runnableManager = (RunnableManager) m_serviceManager.lookup(RunnableManager.ROLE); |
| runnableManager.execute(m_daemonThreadPoolName, this); |
| } catch(final ServiceException e) { |
| throw new CascadingRuntimeException("Cannot get RunnableManager", e); |
| } finally { |
| if (null != runnableManager) { |
| m_serviceManager.release(runnableManager); |
| } |
| } |
| } |
| |
| /** Stop the server */ |
| public void stop() { |
| getLogger().debug("Shutting down HSQLDB"); |
| //AG: Temporally workaround for http://issues.apache.org/jira/browse/COCOON-1862 |
| // A newer version of hsqldb or SAP NetWeaver may not need the next line |
| DatabaseManager.closeDatabases(Database.CLOSEMODE_COMPACT); |
| hsqlServer.stop(); |
| getLogger().debug("Shutting down HSQLDB: Done"); |
| } |
| |
| /** Run the server */ |
| public void run() { |
| if (getLogger().isDebugEnabled()) { |
| getLogger().debug("Starting " + hsqlServer.getProductName() + " " + hsqlServer.getProductVersion() + " with parameters:"); |
| } |
| this.hsqlServer.start(); |
| } |
| } |