From 23a113089125f0676ce7d490498e464430248818 Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Sat, 19 Jul 2003 22:06:54 +0000 Subject: [PATCH] more implementation - got the conference list to the script. Also fixed up the low-level services a bit... --- .../scripts/conferences.js | 9 ++ .../velocity/conferences.vm | 7 +- .../venice/conf/impl/ConferenceManager.java | 14 +- .../venice/conf/module/ModuleMain.java | 8 ++ .../venice/conf/obj/LibraryConference.java | 46 ++++++ .../dynamo/module/ModuleManager.java | 9 +- .../dynamo/script/ScriptController.java | 131 ++++++++++++++---- .../dynamo/script/ScriptEngine.java | 35 +++++ .../script/ScriptEngineMessages.properties | 3 +- 9 files changed, 223 insertions(+), 39 deletions(-) create mode 100644 src/conferencing-module/com/silverwrist/venice/conf/obj/LibraryConference.java diff --git a/resources/conferencing-module/scripts/conferences.js b/resources/conferencing-module/scripts/conferences.js index b3d6033..11e305a 100644 --- a/resources/conferencing-module/scripts/conferences.js +++ b/resources/conferencing-module/scripts/conferences.js @@ -27,10 +27,19 @@ rhelp = bsf.lookupBean("request_help"); // get request helper user = vlib.getUser(req); // get user comm = vlib.getCommunity(req); // get community +// Get the conference access object. +commsvc = vcast.queryCommunityService(rhelp.getRequestObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,"communities")); +conf_ns = "http://www.silverwrist.com/NS/venice/2003/06/19/conferencing"; +conf_tmp = commsvc.getServiceForName(conf_ns,"conferencing.service").getAccessObject(); +conf_access = lib_conf.castConferenceAccessObject(conf_tmp); + // Create the view. rc = new VelocityView("Conference List: " + comm.name,"conf/conferences.vm"); rc.setParameter("community",comm); +// Get the conference list. +rc.setParameter("conferences",conf_access.getConferences(user,comm)); + // Can we manage the conference list? perm_namespace = "http://www.silverwrist.com/NS/venice/2003/06/25/conferencing.permissions"; srm = cast.querySecurityReferenceMonitor(req_help.getRequestObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,"srm")); diff --git a/resources/conferencing-module/velocity/conferences.vm b/resources/conferencing-module/velocity/conferences.vm index 677fabb..bf6b64c 100644 --- a/resources/conferencing-module/velocity/conferences.vm +++ b/resources/conferencing-module/velocity/conferences.vm @@ -17,9 +17,10 @@ *# #* Parameters: - community = The community we're getting the conferences of. - can_manage = Set if we can manage the ordering of conferences. - can_create = Set if we can create new conferences. + community = The community we're getting the conferences of. + conferences = The list of conferences for this community. + can_manage = Set if we can manage the ordering of conferences. + can_create = Set if we can create new conferences. *# #header2( "Conference List:" $community.Name ) ## TEMPORARY diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java index 923f2f6..fd1b6fe 100644 --- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java +++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java @@ -37,13 +37,13 @@ public class ConferenceManager implements ConferenceAccessObject *-------------------------------------------------------------------------------- */ - private DynamicImplConferenceAccess m_dobj; - private UseCount m_uc; - private ConferenceManagerOps m_ops; - private NamespaceCache m_nscache; - private SecurityReferenceMonitor m_srm; - private UserManagement m_users; // user management object - private ReferenceMap m_confs; + private DynamicImplConferenceAccess m_dobj; // DynamicObject implementation + private UseCount m_uc; // use count interface + private ConferenceManagerOps m_ops; // operations object + private NamespaceCache m_nscache; // namespace cache + private SecurityReferenceMonitor m_srm; // security reference monitor + private UserManagement m_users; // user management object + private ReferenceMap m_confs; // cache for conference objects /*-------------------------------------------------------------------------------- * Constructor diff --git a/src/conferencing-module/com/silverwrist/venice/conf/module/ModuleMain.java b/src/conferencing-module/com/silverwrist/venice/conf/module/ModuleMain.java index fbc7f2d..11f0368 100644 --- a/src/conferencing-module/com/silverwrist/venice/conf/module/ModuleMain.java +++ b/src/conferencing-module/com/silverwrist/venice/conf/module/ModuleMain.java @@ -36,6 +36,7 @@ import com.silverwrist.venice.util.*; import com.silverwrist.venice.conf.ConfNamespaces; import com.silverwrist.venice.conf.iface.UseCount; import com.silverwrist.venice.conf.impl.ConferenceManager; +import com.silverwrist.venice.conf.obj.LibraryConference; public class ModuleMain implements ModuleFunctions, UseCount { @@ -72,6 +73,7 @@ public class ModuleMain implements ModuleFunctions, UseCount private ConferenceManager m_mgr; private ComponentShutdown m_res1; private ComponentShutdown m_res2; + private ComponentShutdown m_script; /*-------------------------------------------------------------------------------- * Constructor @@ -178,6 +180,10 @@ public class ModuleMain implements ModuleFunctions, UseCount m_res1 = resmgr.mountResourceProvider("/scripts/conf",new PrefixResourceProvider(module_res,"/scripts")); m_res2 = resmgr.mountResourceProvider("/velocity/conf",new PrefixResourceProvider(module_res,"/velocity")); + // Register the script library. + ScriptEngineConfig seconf = (ScriptEngineConfig)(services.queryService(ScriptEngineConfig.class)); + m_script = seconf.addDeclaredObject("lib_conf",new LibraryConference(),LibraryConference.class); + } // end try catch (ConfigException e) { // translate the ConfigException into a ModuleException @@ -189,6 +195,8 @@ public class ModuleMain implements ModuleFunctions, UseCount public void shutdown() { + m_script.shutdown(); + m_script = null; m_res1.shutdown(); m_res1 = null; m_res2.shutdown(); diff --git a/src/conferencing-module/com/silverwrist/venice/conf/obj/LibraryConference.java b/src/conferencing-module/com/silverwrist/venice/conf/obj/LibraryConference.java new file mode 100644 index 0000000..8148cbb --- /dev/null +++ b/src/conferencing-module/com/silverwrist/venice/conf/obj/LibraryConference.java @@ -0,0 +1,46 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.venice.conf.obj; + +import com.silverwrist.venice.conf.iface.*; + +public class LibraryConference +{ + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public LibraryConference() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + public ConferenceAccessObject castConferenceAccessObject(Object o) throws ClassCastException + { + if (o instanceof ConferenceAccessObject) + return (ConferenceAccessObject)o; + throw new ClassCastException("LibraryConference.castConferenceAccessObject: invalid cast"); + + } // end castConferenceAccessObject + +} // end class LibraryConference diff --git a/src/dynamo-framework/com/silverwrist/dynamo/module/ModuleManager.java b/src/dynamo-framework/com/silverwrist/dynamo/module/ModuleManager.java index 4a25a84..2691899 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/module/ModuleManager.java +++ b/src/dynamo-framework/com/silverwrist/dynamo/module/ModuleManager.java @@ -217,10 +217,15 @@ public class ModuleManager implements NamedObject, ComponentInitialize, Componen m_instservice.addService(DatabaseInstaller.class,new InstallerImpl(pool)); m_install_services = m_instservice.getServiceProvider(m_appcon.getInitServices()); + // Hook the initialization service provider. + SimpleServiceProvider simplesp = new SimpleServiceProvider("ModuleManager Init"); + simplesp.addService(ModuleOperations.class,this); + simplesp.addService(ModuleConfigurationData.class,(ModuleConfigurationData)cfg_data); + HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class)); + m_shut1 = hooker.hookInitServiceProvider(simplesp); + // Hook this into the service providers. SingletonServiceProvider ssp = new SingletonServiceProvider("ModuleManager",ModuleOperations.class,this); - HookServiceProviders hooker = (HookServiceProviders)(services.queryService(HookServiceProviders.class)); - m_shut1 = hooker.hookInitServiceProvider(ssp); m_shut2 = hooker.hookRuntimeServiceProvider(ssp); m_shut3 = hooker.hookOutputServiceProvider(ssp); diff --git a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptController.java b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptController.java index a7726e5..51994d5 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptController.java +++ b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptController.java @@ -20,6 +20,7 @@ package com.silverwrist.dynamo.script; import java.io.*; import java.lang.ref.*; import java.util.*; +import org.apache.log4j.Logger; import org.w3c.dom.*; import com.silverwrist.util.*; import com.silverwrist.dynamo.Namespaces; @@ -105,8 +106,35 @@ public class ScriptController { synchronized (ScriptController.this) { + // remove this object from the list of declared objects m_declared_objects.remove(m_name); + // "un-declare" the object in all active engines + if ((m_active_engines.size()>0) && logger.isDebugEnabled()) + logger.debug("need to remove object \"" + m_name + "\" from " + m_active_engines.size() + + " active engine(s)"); + Iterator it = m_active_engines.iterator(); + while (it.hasNext()) + { // get each engine and undeclare it + ScriptEngine engine = (ScriptEngine)(it.next()); + engine.undeclareOld(m_name); + + } // end while + + // "un-declare" the object in all inactive engines + sweep(); + if ((m_engines.size()>0) && logger.isDebugEnabled()) + logger.debug("need to remove object \"" + m_name + "\" from " + m_engines.size() + " inactive engine(s)"); + it = m_engines.iterator(); + while (it.hasNext()) + { // get each engine and undeclare it + Reference r = (Reference)(it.next()); + ScriptEngine engine = (ScriptEngine)(r.get()); + if (engine!=null) + engine.undeclareOld(m_name); + + } // end while + } // end synchronized block } // end shutdown @@ -160,6 +188,8 @@ public class ScriptController *-------------------------------------------------------------------------------- */ + private static Logger logger = Logger.getLogger(ScriptController.class); + private static final long SWEEP_TIME = 600000L; // 10 minutes /*-------------------------------------------------------------------------------- @@ -167,13 +197,14 @@ public class ScriptController *-------------------------------------------------------------------------------- */ - private ScriptExecuteHelper m_helper; - private String m_temp_path; - private LinkedList m_engines = new LinkedList(); - private ReferenceQueue m_ref_queue = new ReferenceQueue(); - private ComponentShutdown m_sweep_task; - private HashMap m_declared_objects = new HashMap(); - private ArrayList m_start_hooks = new ArrayList(); + private ScriptExecuteHelper m_helper; // helper objects + private String m_temp_path; // temporary path for files + private LinkedList m_engines = new LinkedList(); // currently inactive engines (SoftReferences) + private HashSet m_active_engines = new HashSet(); // currently active engines + private ReferenceQueue m_ref_queue = new ReferenceQueue(); // reference queue of inactive engines + private ComponentShutdown m_sweep_task; // shutdown for reference queue sweeper + private HashMap m_declared_objects = new HashMap(); // declared objects + private ArrayList m_start_hooks = new ArrayList(); // start hooks list /*-------------------------------------------------------------------------------- * Constructor @@ -197,14 +228,19 @@ public class ScriptController private final synchronized void sweep() { Reference r = m_ref_queue.poll(); + int count = 0; while (r!=null) { // remove the stale references m_engines.remove(r); r.clear(); + count++; r = m_ref_queue.poll(); } // end while + if ((count>0) && logger.isDebugEnabled()) + logger.debug("sweep(): discarded " + count + " stale engine reference(s)"); + } // end sweep /** @@ -215,24 +251,29 @@ public class ScriptController * @exception com.silverwrist.dynamo.except.ScriptingException If there was an error in creating a new * ScriptEngine. */ - private final ScriptEngine getEngine() throws ScriptingException + private final synchronized ScriptEngine getEngine() throws ScriptingException { ScriptEngine rc = null; - synchronized (this) - { // fiddling with m_engines here... - sweep(); - while ((rc==null) && !(m_engines.isEmpty())) - { // look for a reference that contains a valid ScriptEngine - SoftReference r = (SoftReference)(m_engines.removeFirst()); - rc = (ScriptEngine)(r.get()); - r.clear(); + sweep(); + while ((rc==null) && !(m_engines.isEmpty())) + { // look for a reference that contains a valid ScriptEngine + SoftReference r = (SoftReference)(m_engines.removeFirst()); + rc = (ScriptEngine)(r.get()); + if ((rc!=null) && logger.isDebugEnabled()) + logger.debug("getEngine() reused existing engine"); + r.clear(); - } // end while - - } // end synchronized block + } // end while if (rc==null) + { // need to create a new engine rc = new ScriptEngine(this); + if (logger.isDebugEnabled()) + logger.debug("getEngine() created new engine"); + + } // end if + + m_active_engines.add(rc); return rc; } // end getEngine @@ -245,6 +286,7 @@ public class ScriptController private final synchronized void releaseEngine(ScriptEngine engine) { sweep(); + m_active_engines.remove(engine); m_engines.addFirst(new SoftReference(engine,m_ref_queue)); } // end releaseEngine @@ -284,6 +326,7 @@ public class ScriptController */ public void initialize(Element config_root, ServiceProvider services) throws ConfigException { + logger.info("Initializing ScriptController"); try { // Start by querying the temp directory. ObjectProvider op = (ObjectProvider)(services.queryService(ObjectProvider.class)); @@ -291,13 +334,16 @@ public class ScriptController File tester = new File(m_temp_path); if (!(tester.isDirectory())) { // temporary directory is bogus! - ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages", - "scriptCtrl.badTmpDir"); + logger.fatal("ScriptController.initialize: bad temporary directory " + m_temp_path); + ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages","scriptCtrl.badTmpDir"); ce.setParameter(0,m_temp_path); throw ce; } // end if + if (logger.isDebugEnabled()) + logger.debug("Script engine temporary files path = " + m_temp_path); + } // end try catch (NoSuchObjectException e) { // translate to ConfigException @@ -322,10 +368,14 @@ public class ScriptController */ public void shutdown() { + logger.info("Shutting down ScriptController"); + // Shut down the background task. m_sweep_task.shutdown(); m_sweep_task = null; + m_active_engines.clear(); // release all active engine references + // Do one more sweep to clear dead references. sweep(); @@ -360,10 +410,11 @@ public class ScriptController */ public ComponentShutdown addDeclaredObject(String name, Object obj, Class klass) throws ConfigException { + logger.info("ScriptController.addDeclaredObject(\"" + name + "\",object,class " + klass.getName() + ")"); if (ScriptEngine.isReservedDeclaration(name)) { // this name is reserved...throw it - ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages", - "declObj.reserved"); + logger.error("the name \"" + name + "\" is reserved"); + ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages","declObj.reserved"); ce.setParameter(0,name); throw ce; @@ -373,15 +424,43 @@ public class ScriptController { // test and add declared object to map if (m_declared_objects.containsKey(name)) { // name has already been used - ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages", - "declObj.already"); + logger.error("the name \"" + name + "\" is already in use"); + ConfigException ce = new ConfigException(ScriptController.class,"ScriptEngineMessages","declObj.already"); ce.setParameter(0,name); throw ce; } // end if + // declare object in any active script engines that currently exist + if ((m_active_engines.size()>0) && logger.isDebugEnabled()) + logger.debug("need to register object \"" + name + "\" in " + m_active_engines.size() + " active engine(s)"); + Iterator it = m_active_engines.iterator(); + while (it.hasNext()) + { // get each engine and declare it + ScriptEngine engine = (ScriptEngine)(it.next()); + engine.declareNew(name,obj,klass); + + } // end while + + // declare object in any inactive script engines that currently exist + sweep(); + if ((m_engines.size()>0) && logger.isDebugEnabled()) + logger.debug("need to register object \"" + name + "\" in " + m_engines.size() + " inactive engine(s)"); + it = m_engines.iterator(); + while (it.hasNext()) + { // get each engine and declare it + Reference r = (Reference)(it.next()); + ScriptEngine engine = (ScriptEngine)(r.get()); + if (engine!=null) + engine.declareNew(name,obj,klass); + + } // end while + + // add declared object to map DeclaredObject dobj = new DeclaredObject(name,obj,klass); m_declared_objects.put(dobj.getName(),dobj); + + // return the shutdown return new DeclareShutdown(dobj.getName()); } // end synchronized block @@ -391,7 +470,7 @@ public class ScriptController /** * Adds a new "hook" to the script engine startup process in the form of an event listener. The * {@link com.silverwrist.dynamo.event.ScriptEngineStartListener#scriptEngineStarting(com.silverwrist.dynamo.event.ScriptEngineStartEvent) scriptEngineStarting()} - * method of the given object will be called when an instance of a script enine starts up. + * method of the given object will be called when an instance of a script engine starts up. * * @param listener The event listener to register for handling startup events. * @return An instance of {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} which will diff --git a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngine.java b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngine.java index 3b0d9aa..451b676 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngine.java +++ b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngine.java @@ -386,6 +386,8 @@ class ScriptEngine implements ScriptExecute void start(Request request, List start_hooks) throws ScriptingException { + if (logger.isDebugEnabled()) + logger.debug("ScriptEngine.start(): " + start_hooks.size() + " start hook(s) to call"); m_register_maps.addFirst(new HashMap()); // push new context Iterator it = start_hooks.iterator(); ScriptEngineStartEvent evt = null; @@ -506,6 +508,39 @@ class ScriptEngine implements ScriptExecute } // end getCurrentLogger + void declareNew(String name, Object obj, Class klass) throws ConfigException + { + try + { // call through to BSF to declare the object + m_bsf.declareBean(name,obj,klass); + + } // end try + catch (BSFException e) + { // unable to declare the new object - throw an exception + ConfigException ce = new ConfigException(ScriptEngine.class,"ScriptEngineMessages","engine.declNewFail",e); + ce.setParameter(0,name); + ce.setParameter(1,e.getMessage()); + throw ce; + + } // end catch + + } // end declareNew + + void undeclareOld(String name) + { + try + { // undeclare a bean + m_bsf.undeclareBean(name); + + } // end try + catch (BSFException e) + { // just log the exception and continue + logger.error("Undeclaring bean \"" + name + "\" in script engine threw exception",e); + + } // end catch + + } // end undeclareOld + /*-------------------------------------------------------------------------------- * Static initializer *-------------------------------------------------------------------------------- diff --git a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngineMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngineMessages.properties index 2492b00..cf8731b 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngineMessages.properties +++ b/src/dynamo-framework/com/silverwrist/dynamo/script/ScriptEngineMessages.properties @@ -10,7 +10,7 @@ # # The Initial Developer of the Original Code is Eric J. Bowersox , # for Silverwrist Design Studios. Portions created by Eric J. Bowersox are -# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. # # Contributor(s): # --------------------------------------------------------------------------------- @@ -27,3 +27,4 @@ script.abortStart=Scripting engine startup aborted. rhino.runtimeError=JavaScript runtime error: {0} null.message={0} exception.unexpected=Unexpected exception: {0} +engine.declNewFail=Unable to declare the new object "{0}" in the script engine: {1}