blob: 5f74784e95bba37212c553292739c9aa1d335ec2 [file] [log] [blame]
/*
* 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();
}
}