/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/common/Domain.java,v 1.29 2001/08/29 13:03:16 juergen Exp $
* $Revision: 1.29 $
* $Date: 2001/08/29 13:03:16 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.common;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Properties;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.io.IOException;
import org.apache.slide.structure.*;
import org.apache.slide.content.*;
import org.apache.slide.lock.*;
import org.apache.slide.authenticate.SecurityToken;
import org.apache.slide.util.conf.*;
import org.apache.slide.util.logger.Logger;
import org.apache.slide.util.logger.SimpleLogger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
/**
* Domain class.
* <p/>
* For now, does not implement access control on Namespaces.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author Dirk Verbeeck
* @version $Revision: 1.29 $
*/
public final class Domain {
private final static String LOG_CHANNEL = Domain.class.getName();
// ----------------------------------------------------- Instance Variables
/**
* Namespaces hashtable.
*/
private static Hashtable namespaces;
/**
* Active namespaces hashtable.
*/
private static Hashtable activeNamespaces;
/**
* Slide logger.
*/
private static Logger logger;
/**
* Default namespace.
*/
private static String defaultNamespace;
// --------------------------------------------------------- Public Methods
/**
* Tests if the domain has been initialized before.
*
* @return boolean True if the domain has already been initialized
*/
public static boolean isInitialized() {
return (namespaces != null);
}
/**
* Set the domain as having been initialized before.
*/
public static void setInitialized(boolean initialized) {
if (!initialized)
return;
if (isInitialized())
return;
if (logger == null) {
logger = new org.apache.slide.util.logger.SimpleLogger();
logger.setLoggerLevel(Logger.INFO);
}
namespaces = new Hashtable();
activeNamespaces = new Hashtable();
}
/**
* Return the default namespace of this domain.
*
* @return the name of the default namespace
*/
public static String getDefaultNamespace() {
if (!isInitialized())
selfInit();
return defaultNamespace;
}
/**
* Access a Namespace.
*
* @param token Entity which wants access
* @param namespaceName Name of the namespace on which access is requested
* @return NamespaceAccessToken Access token to the namespace
*/
public static NamespaceAccessToken accessNamespace(SecurityToken token,
String namespaceName) {
if (!isInitialized())
selfInit();
Namespace namespace = (Namespace) namespaces.get(namespaceName);
if (namespace == null)
return null;
else
return new NamespaceAccessTokenImpl(namespace);
}
/**
* Enumerate namespace names.
*/
public static Enumeration enumerateNamespaces() {
if (!isInitialized())
return (new Vector()).elements();
return (namespaces.keys());
}
/**
* Close a namespace.
*
* @param token Namespace access token
*/
public static void closeNamespace(NamespaceAccessToken token) {
token.disconnect();
activeNamespaces.remove(token.getName());
}
/**
* Clsose a namespace.
*
* @param token Entity which wants to close the namespace
* @param namespaceName Name of the namespace
*/
public static void closeNamespace(SecurityToken token,
String namespaceName) {
try {
Namespace namespace = (Namespace) namespaces.get(namespaceName);
namespace.disconnectServices();
activeNamespaces.remove(namespaceName);
} catch(Exception e) {
}
}
/**
* Access a Domain.
*
* @param token Service who wants access
* @return DomainAccessToken Access token to the domain
*/
public static DomainAccessToken accessDomain(SecurityToken token) {
// Not implemented
return null;
}
/**
* holds the expanded file name of domain.xml
**/
private static String domainFileName = "Domain.xml";
/**
* Access the file name of domain.xml.
*
* @return String the expanded file name as a string.
*/
public static String getDomainFileName() {
return domainFileName;
}
/**
* Domain initialization routine using Avalon configuration parser.
*
* @param configurationURL The file name to read the configuration
*/
public static void init(java.net.URL configurationURL) throws Exception {
if (isInitialized())
return;
domainFileName = configurationURL.getFile();
init(configurationURL.openStream());
}
/**
* Domain initialization routine using Avalon configuration parser.
*
* @param configurationInputStream The file name to read the configuration
*/
public static void init(String configurationFileName) throws Exception {
if (isInitialized())
return;
domainFileName = configurationFileName;
init(new FileInputStream(configurationFileName));
}
/**
* Domain initialization routine using Avalon configuration parser.
*
* @param configurationInputStream The file name to read the configuration
*/
public static void init(InputStream configurationInputStream)
throws Exception {
if (isInitialized())
return;
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
Populate pop = new Populate();
Configuration slideConfiguration =
new ConfigurationElement(pop.load(new InputSource
(configurationInputStream), parser.getXMLReader()));
Domain.init(slideConfiguration);
}
/**
* Domain initialization routine using Avalon configuration parser.
*
* @param configuration Avalon configuration object
*/
public static void init(Configuration configuration) {
if (isInitialized())
return;
defaultNamespace = configuration.getAttribute("default", "slide");
String loggerClass = configuration.getAttribute
("logger", "org.apache.slide.util.logger.SimpleLogger");
if (logger == null) {
try {
logger = (Logger) (Class.forName(loggerClass).newInstance());
logger.setLoggerLevel(configuration.getAttributeAsInt
("logger-level", Logger.INFO));
} catch (Exception e) {
error(e);
throw new DomainInitializationFailedError
("Logger Problem: " + e.toString());
}
}
info("Initializing Domain");
namespaces = new Hashtable();
activeNamespaces = new Hashtable();
// Now initializing the domain
// Loading configuration
Properties properties =
org.apache.slide.util.Configuration.getDefault();
info("Domain configuration : " + properties.toString());
Enumeration namespaceDefinitions =
configuration.getConfigurations("namespace");
while (namespaceDefinitions.hasMoreElements()) {
initNamespace((Configuration) namespaceDefinitions.nextElement());
}
if (namespaces.isEmpty()) {
throw new DomainInitializationFailedError();
}
}
// --------------------------------------------------------- Logger Methods
/**
* Log.
*
* @param data The object to log.
* @param channel The channel name used for logging.
* @param level The level used for logging.
*/
public static void log(Object data, String channel, int level) {
logger.log(data, channel, level);
}
/**
* Log.
*
* @param data The object to log.
* @param level The level used for logging.
*/
public static void log(Object data, int level) {
logger.log(data,LOG_CHANNEL, level);
}
/**
* Log.
*
* @param data The object to log.
*/
public static void log(Object data) {
logger.log(data,LOG_CHANNEL,Logger.DEBUG);
}
/**
* Debug.
*
* @param data The object to log
*/
public static void debug(Object data) {
log(data,LOG_CHANNEL, Logger.DEBUG);
}
/**
* Error.
*
* @param data The object to log
*/
public static void error(Object data) {
log(data,LOG_CHANNEL, Logger.ERROR);
}
/**
* Error.
*
* @param data The object to log
* @param t Throwable object
*/
public static void error(Object data, Throwable t) {
log(data + " - " + t.getMessage(),LOG_CHANNEL, Logger.ERROR);
log(t,LOG_CHANNEL, Logger.ERROR);
}
/**
* Info.
*
* @param data The object to log
*/
public static void info(Object data) {
log(data,LOG_CHANNEL, Logger.INFO);
}
/**
* Warning.
*
* @param data The object to log
*/
public static void warn(Object data) {
log(data,LOG_CHANNEL, Logger.WARNING);
}
/**
* Check if the channel with the specified level is enabled for logging.
* This implementation ignores the channel specification
*
* @param channel The channel specification
* @param level The level specification
*/
public static boolean isEnabled(String channel, int level) {
return logger.isEnabled(channel, level);
}
/**
* Check if the default channel with the specified level is enabled for
* logging.
*
* @param level The level specification
*/
public static boolean isEnabled(int level) {
return logger.isEnabled(LOG_CHANNEL,level);
}
/**
* Check if the default channel with the DEBUG level is enabled for
* logging.
*/
public static boolean isDebugEnabled() {
return isEnabled(LOG_CHANNEL,logger.DEBUG);
}
/**
* Check if the default channel with the WARNING level is enabled for
* logging.
*/
public static boolean isWarningEnabled() {
return isEnabled(LOG_CHANNEL,logger.WARNING);
}
/**
* Check if the default channel with the INFO level is enabled for logging.
*/
public static boolean isInfoEnabled() {
return isEnabled(LOG_CHANNEL,logger.INFO);
}
/**
* Check if the default channel with the ERROR level is enabled for
* logging.
*/
public static boolean isErrorEnabled() {
return isEnabled(LOG_CHANNEL,logger.ERROR);
}
// -------------------------------------------------------- Package Methods
/**
* Start domain (doesn't do anything yet).
*/
static void start()
throws Exception {
}
/**
* Stop domain.
*/
static void stop()
throws Exception {
Enumeration active = activeNamespaces.elements();
while (active.hasMoreElements()) {
((Namespace) active.nextElement()).disconnectServices();
}
}
/**
* Add a namespace to the domain.
*
* @param namespace Namespace to be added
*/
static void addNamespace(Namespace namespace) {
namespaces.put(namespace.getName(), namespace);
activeNamespaces.put(namespace.getName(), namespace);
}
/**
* Get a namespace.
*
* @param namespaceName Name of the namespace
* @return Namespace
*/
static Namespace getNamespace(String namespaceName) {
return (Namespace) namespaces.get(namespaceName);
}
/**
* Set the logger to be used by Slide.
*
* @param logger Logger the domain will use
*/
static void setLogger(Logger logger) {
Domain.logger = logger;
}
/**
* Get the Domain logger.
*
* @return The domain logger
*/
static Logger getLogger() {
return Domain.logger;
}
/**
* Default initialization of the domain.
*/
static void selfInit() {
String loggerClass = "org.apache.slide.util.logger.SimpleLogger";
if (logger == null) {
try {
logger = (Logger)(Class.forName(loggerClass).newInstance());
logger.setLoggerLevel(Logger.INFO);
}
catch (Exception e) {
error(e);
throw new DomainInitializationFailedError
("Logger Problem: " + e.toString());
}
}
info("Auto-Initializing Domain");
// Now initializing the domain
// Loading configuration
Properties configuration =
org.apache.slide.util.Configuration.getDefault();
info("Domain configuration : " + configuration.toString());
// First, retrieve the domain XML definition file from
// the configuration
String fileName =
org.apache.slide.util.Configuration.getDefault().getProperty
(org.apache.slide.util.Configuration.Property.DomainInitFilename,
"Domain.xml");
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
FileInputStream is = new FileInputStream(fileName);
//init(reader);
Populate pop = new Populate();
Configuration slideConfiguration =
new ConfigurationElement(pop.load(new InputSource(is),
parser.getXMLReader()));
init(slideConfiguration);
} catch (javax.xml.parsers.FactoryConfigurationError e) {
throw new DomainInitializationFailedError(e.getMessage());
} catch (Exception e) {
throw new DomainInitializationFailedError(e.getMessage());
}
info("Domain initialization complete");
}
// -------------------------------------------------------- Private Methods
/**
* Initializes a new namespace based on the given configuration data.
*
* @param configuration Configuration object
*/
private static void initNamespace(Configuration configuration) {
try {
try {
info("Initializing namespace : "
+ configuration.getAttribute("name"));
} catch (ConfigurationException e) {
error(e);
}
String loggerClass = configuration.getAttribute
("logger", null);
Logger namespaceLogger = null;
if (loggerClass==null) {
// if there is no logger defined on the namespace
// use the domain logger
namespaceLogger=logger;
}
else {
try {
namespaceLogger =
(Logger) (Class.forName(loggerClass).newInstance());
namespaceLogger.setLoggerLevel(configuration.getAttributeAsInt
("logger-level", Logger.INFO));
} catch (Exception e) {
error(e);
}
}
Configuration namespaceDefinition =
configuration.getConfiguration("definition");
Namespace namespace = new Namespace();
namespace.setName(configuration.getAttribute("name"));
namespace.setLogger(namespaceLogger);
namespace.loadDefinition(namespaceDefinition);
addNamespace(namespace);
Configuration namespaceConfigurationDefinition =
configuration.getConfiguration("configuration");
namespace.loadParameters(namespaceConfigurationDefinition);
try {
Configuration namespaceBaseDataDefinition =
configuration.getConfiguration("data");
namespace.loadBaseData(namespaceBaseDataDefinition);
} catch (ConfigurationException e) {
info("No basedata found for the namespace");
}
namespace.loadConfiguration(namespaceConfigurationDefinition);
// preparation to add services, please ignore now
try {
Configuration services = configuration.getConfiguration("services");
Enumeration s = services.getConfigurations("service");
while (s.hasMoreElements()) {
Configuration service = (Configuration)s.nextElement();
System.out.println("&&&&&&Name = " + service.getName());
System.out.println("&&&&&&className = " + service.getAttribute("classname"));
System.out.println("&&&&&&serviceName = " + service.getAttribute("name"));
Enumeration s_pars = service.getConfigurations("parameter");
while (s_pars.hasMoreElements()) {
Configuration s_par = (Configuration)s_pars.nextElement();
System.out.println("&&&&&&PAR Name = " + s_par.getName());
System.out.println("&&&&&&PAR Name = " + s_par.getAttribute("name"));
System.out.println("&&&&&&Par Val = " + s_par.getValue());
}
}
}
catch (ConfigurationException e){
// silently ignore it ==> no services
}
catch (Exception e){
error(e);
}
// preparation to add services, please ignore now
info("Namespace configuration complete");
} catch (Throwable t) {
error(t);
}
}
}