/*
* $Id: AnyConfigurable.java,v 1.25 2002/09/16 08:05:03 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.system;
import java.util.Enumeration;
import java.io.IOException;
import anvil.core.Any;
import anvil.core.AnyAbstractClass;
import anvil.core.AnyString;
import anvil.core.AnyTuple;
import anvil.core.AnyList;
import anvil.core.Array;
import anvil.core.Modules;
import anvil.script.Context;
import anvil.script.Scope;
import anvil.script.ModuleEnvelope;
import anvil.java.util.BindingEnumeration;
import anvil.server.ConfigReader;
import anvil.server.Configurable;
import anvil.server.Server;
import anvil.server.Domain;
import anvil.server.Zone;
import anvil.server.Realm;
import anvil.server.NamespacePreferences;
import anvil.server.PoolPreferences;
import anvil.server.RealmPreferences;
import anvil.database.PooledConnection;
import anvil.database.CannotReturnPooledConnectionException;
import anvil.database.NoConnectionPoolException;
/// @class Configurable
/// Configurable represents entities declared in server's configuration.
/// These entities form a tree which can be investigated and modified through
/// this class.
/**
* class AnyConfigurable
*
* @author: Jani Lehtim�ki
*/
public class AnyConfigurable extends AnyAbstractClass
{
public static anvil.core.RuntimePermission CAN_READ = new anvil.core.RuntimePermission("anvil.system.Configurable", false);
public static anvil.core.RuntimePermission CAN_WRITE = new anvil.core.RuntimePermission("anvil.system.Configurable", true);
protected Configurable _conf;
public AnyConfigurable(Configurable conf)
{
_conf = conf;
}
public anvil.script.ClassType classOf()
{
return __class__;
}
public String toString()
{
return "Configurable(" + Configurable.CLASSES[_conf.getType()] + ')';
}
public Object toObject()
{
return _conf;
}
public int hashCode()
{
return _conf.hashCode();
}
public Any getAttribute(Context context, String attribute)
{
return Any.create(_conf.getPreference(attribute));
}
public Any checkAttribute(Context context, String attribute)
{
return Any.create(_conf.getPreference(attribute));
}
public Any setAttribute(Context context, String attribute, Any value)
{
_conf.setPreference(attribute, value.toString());
return value;
}
public boolean deleteAttribute(Context context, String attribute)
{
_conf.setPreference(attribute, null);
return true;
}
public Any getReference(Context context, Any index)
{
return getAttribute(context, index.toString());
}
public Any checkReference(Context context, Any index)
{
return checkAttribute(context, index.toString());
}
public Any setReference(Context context, Any index, Any value)
{
return setAttribute(context, index.toString(), value);
}
public Any setReference(Context context, Any value)
{
if (value instanceof AnyConfigurable) {
_conf.configure((Configurable)value.toObject());
}
return value;
}
public boolean deleteReference(Context context, Any index)
{
if (index.isString()) {
return deleteAttribute(context, index.toString());
} else if (index instanceof AnyConfigurable) {
_conf.deleteConfiguration((Configurable)index.toObject());
return true;
} else {
return false;
}
}
public BindingEnumeration enumeration()
{
Configurable[] childs = _conf.getConfigurations();
return new ConfigurationEnumeration(childs);
}
/********* Exposed methods ************/
/// @method getServer
/// Returns the server where this object is located.
/// @synopsis Configurable getServer()
public Any m_getServer()
{
Server server;
if (_conf instanceof Zone) {
server = ((Zone)_conf).getServer();
} else {
server = _conf.getParent().getServer();
}
return (server != null) ? new AnyConfigurable(server) : UNDEFINED;
}
/// @method getDomain
/// Returns the domain where this object is located.
/// @synopsis Configurable getDomain()
public Any m_getDomain()
{
Domain domain;
if (_conf instanceof Zone) {
domain = ((Zone)_conf).getDomain();
} else {
domain = _conf.getParent().getDomain();
}
return (domain != null) ? new AnyConfigurable(domain) : UNDEFINED;
}
/// @method getParent
/// Returns the parent of this object.
/// @synopsis Configurable getParent()
public Any m_getParent()
{
Configurable parent = _conf.getParent();
return (parent != null) ? new AnyConfigurable(parent) : UNDEFINED;
}
/// @method getType
/// Returns the type of this object.
/// Type is one of: <ul>
/// <li>access
/// <li>application
/// <li>bind
/// <li>compiler
/// <li>domain
/// <li>handlers
/// <li>listener
/// <li>localization
/// <li>logging
/// <li>modules
/// <li>namespace
/// <li>policy
/// <li>pool
/// <li>realm
/// <li>server
/// <li>session
/// <li>sessioncontainer
/// <li>zone
/// </ul>
/// @synopsis string getType()
public Any m_getType()
{
return Any.create(Configurable.CLASSES[_conf.getType()]);
}
/// @method getName
/// Returns the name of this object.
/// @synopsis string getName()
public Any m_getName()
{
Object obj = _conf.getPreference("name");
String name = (obj != null) ? obj.toString() : null;
if (obj == null || name.length() == 0) {
switch(_conf.getType()) {
case Configurable.SERVER:
name = "Server";
break;
case Configurable.DOMAIN:
name = ((Domain)_conf).getHostname();
if (name == null || name.length() == 0) {
name = "Domain";
}
break;
case Configurable.ZONE:
name = ((Zone)_conf).getPathinfo();
if (name == null || name.length() == 0) {
name = "Zone";
}
break;
default:
name = Configurable.CLASSES[_conf.getType()];
}
} else {
name = obj.toString();
}
return Any.create(name);
}
/// @method getChilds
/// Returns a list of children for this object.
/// @synopsis tuple getChilds()
public Any m_getChilds()
{
Configurable[] childs = _conf.getConfigurations();
final int n = childs.length;
Any[] list = new Any[n];
for(int i=0; i<n; i++) {
list[i] = new AnyConfigurable(childs[i]);
}
return new AnyTuple(list);
}
/// @method getNames
/// Returns a list of names of valid (fixed) attributes.
/// @synopsis tuple getNames()
public Any m_getNames()
{
String[] s = _conf.getPreferences();
if (s != null) {
int n = s.length;
Any[] list = new Any[n/2];
int j = 0;
for(int i=0; i<n; i+=2) {
list[j++] = new AnyString(s[i]);
}
return new AnyTuple(list);
} else {
return Any.EMPTY_TUPLE;
}
}
/// @method getTypes
/// Returns a list of types of valid (fixed) attributes.
/// Indices at tuple returned by this object matches
/// with with one returned by getNames().
/// @synopsis tuple getTypes()
public Any m_getTypes()
{
String[] s = _conf.getPreferences();
if (s != null) {
int n = s.length;
Any[] list = new Any[n/2];
int j = 0;
for(int i=1; i<n; i+=2) {
list[j++] = new AnyString(s[i]);
}
return new AnyTuple(list);
} else {
return Any.EMPTY_TUPLE;
}
}
/// @method getMoreNames
/// Returns the names of extran (non-fixed) attributes for this object.
/// They are always interpreted as strings.
/// @synopsis tuple getMoreNames()
public Any m_getMoreNames()
{
String[] s = _conf.getAdditionalPreferenceNames();
if (s != null) {
int n = s.length;
Any[] list = new Any[n];
for(int i=0; i<n; i++) {
list[i] = new AnyString(s[i]);
}
return new AnyTuple(list);
} else {
return Any.EMPTY_TUPLE;
}
}
/// @method getSessionContainer
/// Returns the zone's session container, of this object
/// if this object is a session container.
/// @synopsis SessionContainer getSessionContainer()
public Any m_getSessionContainer()
{
anvil.session.SessionContainer container = null;
if (_conf.getType() == Configurable.SESSION_CONTAINER) {
container = _conf.getParent().getSessionContainer();
} else if (_conf instanceof Zone) {
container = ((Zone)_conf).getSessionContainer();
}
return (container != null) ?
new anvil.core.net.AnySessionContainer(container) : UNDEFINED;
}
/// @method getRealm
/// Returns the realm with given name.
/// @synopsis Realm getRealm() ;
/// @synopsis Realm getRealm(string name)
public static final Object[] p_getRealm = { null, "*name", null };
public Any m_getRealm(Context context, String name)
{
Realm realm = null;
if (_conf.getType() == Configurable.REALM) {
RealmPreferences rp = (RealmPreferences)_conf;
realm = _conf.getParent().getRealm(rp.getName());
} else if (_conf instanceof Zone) {
if (name == null) {
throw context.NotEnoughParameters("Name of realm missing");
}
realm = ((Zone)_conf).getRealm(name);
}
return (realm != null) ?
new anvil.core.net.AnyRealm(realm) : UNDEFINED;
}
/// @method getNamespace
/// Returns the namespace with given name.
/// @synopsis Namespace getNamespace()
/// @synopsis Namespace getNamespace(string name)
/// @throws AccessDenied if security policy denies this operation
public static final Object[] p_getNamespace = { null, "*name", null };
public Any m_getNamespace(Context context, String name)
{
anvil.script.Namespace namespace = null;
if (_conf.getType() == Configurable.NAMESPACE) {
name = ((NamespacePreferences)_conf).getName();
context.checkNamespace(name, false);
namespace = _conf.getParent().getNamespace(name);
} else if (_conf instanceof Zone) {
if (name == null) {
throw context.NotEnoughParameters("Name of namespace missing");
}
context.checkNamespace(name, false);
namespace = ((Zone)_conf).getNamespace(name);
}
return (namespace != null) ?
new anvil.core.runtime.AnyNamespace(namespace) : UNDEFINED;
}
/// @method acquireConnection
/// Acquires connection from given pool.
/// @synopsis Connection acquireConnection()
/// @synopsis Connection acquireConnection(string name)
/// @throws AcquireError
public static final Object[] p_acquireConnection = { null, "*name", null };
public Any m_acquireConnection(Context context, String name)
{
PooledConnection connection = null;
try {
if (_conf.getType() == Configurable.POOL) {
connection = _conf.getParent().acquireConnection(((PoolPreferences)_conf).getName());
} else if (_conf instanceof Zone) {
if (name == null) {
throw context.NotEnoughParameters("Name of connection pool missing");
}
connection = ((Zone)_conf).acquireConnection(name);
}
} catch (NoConnectionPoolException e) {
throw context.AcquireError(e.getMessage());
} catch (CannotReturnPooledConnectionException e) {
throw context.AcquireError(e.getMessage());
}
return (connection != null) ?
new anvil.core.sql.AnyConnection(connection) : UNDEFINED;
}
/// @method getModule
/// Returns the root module of libraries.
/// @synopsis module getModule()
public static final Object[] p_getModule = { null, "name" };
public Any m_getModule(Context context)
{
anvil.script.Module module = null;
if (_conf.getType() == Configurable.MODULES) {
module = _conf.getParent().getModules();
} else if (_conf instanceof Zone) {
module = ((Zone)_conf).getModules();
}
return (module != null) ?
new anvil.core.runtime.AnyScope(module) : UNDEFINED;
}
/// @method getIdentity
/// Returns the identity for this object (memory address).
/// @synopsis int getIdentity()
public Any m_getIdentity()
{
return Any.create(System.identityHashCode(_conf));
}
private Configurable find(Configurable cfg, int id)
{
if (System.identityHashCode(cfg) == id) {
return cfg;
}
Configurable[] childs = cfg.getConfigurations();
final int n = childs.length;
for(int i=0; i<n; i++) {
cfg = find(childs[i], id);
if (cfg != null) {
return cfg;
}
}
return null;
}
/// @method find
/// Searches for an object with given identity from objects
/// starting from this object.
/// @synopsis Configurable find(int identity)
public static final Object[] p_find = { "identity" };
public Any m_find(int id)
{
Configurable cfg = find(_conf, id);
return (cfg != null) ? new AnyConfigurable(cfg) : Any.UNDEFINED;
}
/// @method create
/// Creates a new configuration object of given type under this object.
/// @synopsis Configurable create(string type)
/// @throws AccessDenied if security policy denies this operation
public static final Object[] p_create = { null, "type" };
public Any m_create(Context context, String type)
{
context.checkAccess(CAN_WRITE);
Configurable cfg = null;
if (_conf instanceof Zone) {
cfg = ConfigReader.create((Zone)_conf, type);
}
if (cfg != null) {
_conf.configure(cfg);
return new AnyConfigurable(cfg);
} else {
return NULL;
}
}
/// @method remove
/// Removes this object.
/// @synopsis boolean remove()
/// @throws AccessDenied if security policy denies this operation
public Any m_remove(Context context)
{
context.checkAccess(CAN_WRITE);
Configurable parent = _conf.getParent();
if (parent != null) {
parent.deleteConfiguration(_conf);
return TRUE;
} else {
return FALSE;
}
}
/// @method getCacheContents
/// Returns a list of script cache contents from this zone as Envelope's.
/// @synopsis list getCacheContents()
/// @throws AccessDenied if security policy denies this operation
public Any m_getCacheContents(Context context)
{
context.checkAccess(AnyEnvelope.CAN_READ);
if (_conf instanceof Zone) {
ModuleEnvelope[] env = ((Zone)_conf).getCacheContents();
int n = env.length;
Any[] array = new Any[n];
for(int i=0; i<n; i++) {
array[i] = new AnyEnvelope(env[i]);
}
return new AnyList(array);
}
return UNDEFINED;
}
/// @method purgeCache
/// Removes all compiled scripts from cache under this zone.
/// @synopsis Configurable purgeCache()
/// @throws AccessDenied if security policy denies this operation
public Any m_purgeCache(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Zone) {
((Zone)_conf).purgeCache();
}
return this;
}
/// @method save
/// Saves the server's configuration.
/// @synopsis Configurable save()
/// @throws AccessDenied if security policy denies this operation
public Any m_save(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Server) {
try {
((Server)_conf).save();
} catch (IOException e) {
throw context.exception(e);
} catch (Throwable t) {
throw context.exception(t);
}
}
return this;
}
/// @method reread
/// Rereads the server's configuration.
/// @synopsis Configurable reread()
/// @throws AccessDenied if security policy denies this operation
/// @throws IOError if an IO error occured
public Any m_reread(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Server) {
try {
((Server)_conf).reread();
} catch (IOException e) {
throw context.exception(e);
} catch (Throwable t) {
throw context.exception(t);
}
}
return this;
}
/// @method isStarted
/// Checks if this object is started.
/// @synopsis boolean isStarted()
public Any m_isStarted()
{
Configurable c = _conf;
while(c != null) {
if (c instanceof Zone) {
return ((Zone)c).isStarted() ? TRUE : FALSE;
}
c = c.getParent();
}
return FALSE;
}
/// @method restart
/// Restarts this zone.
/// @synopsis boolean restart()
/// @throws AccessDenied if security policy denies this operation
public Any m_restart(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Zone) {
Zone zone = (Zone)_conf;
zone.stop();
zone.start();
return TRUE;
} else {
return FALSE;
}
}
/// @method stop
/// Stops this zone.
/// @synopsis boolean stop()
/// @throws AccessDenied if security policy denies this operation
public Any m_stop(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Zone) {
((Zone)_conf).stop();
return TRUE;
} else {
return FALSE;
}
}
/// @method start
/// Starts this zone.
/// @synopsis boolean start()
/// @throws AccessDenied if security policy denies this operation
public Any m_start(Context context)
{
context.checkAccess(CAN_WRITE);
if (_conf instanceof Zone) {
((Zone)_conf).start();
return TRUE;
} else {
return FALSE;
}
}
public class ConfigurationEnumeration implements BindingEnumeration
{
private Configurable[] _list;
private int _index = 0;
public ConfigurationEnumeration(Configurable[] list)
{
_list = list;
}
public boolean hasMoreElements()
{
return (_index < _list.length);
}
public Object nextKey()
{
return Any.create(_index);
}
public Object nextElement()
{
if (_index < _list.length) {
return new AnyConfigurable(_list[_index++]);
} else {
return Any.NULL;
}
}
}
transient public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("Configurable", AnyConfigurable.class,
//DOC{{
""+
" @class Configurable\n" +
" Configurable represents entities declared in server's configuration.\n" +
" These entities form a tree which can be investigated and modified through\n" +
" this class.\n" +
" @method getServer\n" +
" Returns the server where this object is located.\n" +
" @synopsis Configurable getServer()\n" +
" @method getDomain\n" +
" Returns the domain where this object is located.\n" +
" @synopsis Configurable getDomain()\n" +
" @method getParent\n" +
" Returns the parent of this object.\n" +
" @synopsis Configurable getParent()\n" +
" @method getType\n" +
" Returns the type of this object.\n" +
" Type is one of: <ul>\n" +
" <li>access\n" +
" <li>application\n" +
" <li>bind\n" +
" <li>compiler\n" +
" <li>domain\n" +
" <li>handlers\n" +
" <li>listener\n" +
" <li>localization\n" +
" <li>logging\n" +
" <li>modules\n" +
" <li>namespace\n" +
" <li>policy\n" +
" <li>pool\n" +
" <li>realm\n" +
" <li>server\n" +
" <li>session\n" +
" <li>sessioncontainer\n" +
" <li>zone\n" +
" </ul>\n" +
" @synopsis string getType()\n" +
" @method getName\n" +
" Returns the name of this object.\n" +
" @synopsis string getName()\n" +
" @method getChilds\n" +
" Returns a list of children for this object.\n" +
" @synopsis tuple getChilds()\n" +
" @method getNames\n" +
" Returns a list of names of valid (fixed) attributes.\n" +
" @synopsis tuple getNames()\n" +
" @method getTypes\n" +
" Returns a list of types of valid (fixed) attributes.\n" +
" Indices at tuple returned by this object matches\n" +
" with with one returned by getNames().\n" +
" @synopsis tuple getTypes()\n" +
" @method getMoreNames\n" +
" Returns the names of extran (non-fixed) attributes for this object.\n" +
" They are always interpreted as strings.\n" +
" @synopsis tuple getMoreNames()\n" +
" @method getSessionContainer\n" +
" Returns the zone's session container, of this object\n" +
" if this object is a session container.\n" +
" @synopsis SessionContainer getSessionContainer()\n" +
" @method getRealm\n" +
" Returns the realm with given name.\n" +
" @synopsis Realm getRealm() ;\n" +
" @synopsis Realm getRealm(string name)\n" +
" @method getNamespace\n" +
" Returns the namespace with given name.\n" +
" @synopsis Namespace getNamespace()\n" +
" @synopsis Namespace getNamespace(string name)\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method acquireConnection\n" +
" Acquires connection from given pool.\n" +
" @synopsis Connection acquireConnection()\n" +
" @synopsis Connection acquireConnection(string name)\n" +
" @throws AcquireError\n" +
" @method getModule\n" +
" Returns the root module of libraries.\n" +
" @synopsis module getModule()\n" +
" @method getIdentity\n" +
" Returns the identity for this object (memory address).\n" +
" @synopsis int getIdentity()\n" +
" @method find\n" +
" Searches for an object with given identity from objects\n" +
" starting from this object.\n" +
" @synopsis Configurable find(int identity)\n" +
" @method create\n" +
" Creates a new configuration object of given type under this object.\n" +
" @synopsis Configurable create(string type)\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method remove\n" +
" Removes this object.\n" +
" @synopsis boolean remove()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method getCacheContents\n" +
" Returns a list of script cache contents from this zone as Envelope's.\n" +
" @synopsis list getCacheContents()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method purgeCache\n" +
" Removes all compiled scripts from cache under this zone.\n" +
" @synopsis Configurable purgeCache()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method save\n" +
" Saves the server's configuration.\n" +
" @synopsis Configurable save()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method reread\n" +
" Rereads the server's configuration.\n" +
" @synopsis Configurable reread()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @throws IOError if an IO error occured\n" +
" @method isStarted\n" +
" Checks if this object is started.\n" +
" @synopsis boolean isStarted()\n" +
" @method restart\n" +
" Restarts this zone.\n" +
" @synopsis boolean restart()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method stop\n" +
" Stops this zone.\n" +
" @synopsis boolean stop()\n" +
" @throws AccessDenied if security policy denies this operation\n" +
" @method start\n" +
" Starts this zone.\n" +
" @synopsis boolean start()\n" +
" @throws AccessDenied if security policy denies this operation\n"
//}}DOC
);
static {
SystemModule.class.getName();
}
}