the first real phase of service integration - mostly it's the configuration

file, the bare beginnings of the Service Control Manager on the server side,
and the new "community left menu" on the client side (still controlled by the
existing feature mechanism, for now).  The engine still needs to incorporate
the SCM in place of the old feature definitions.  Also added some utility
classes (StockMessage, XMLLoader) to aid with loading XML data from the
config files (big help in the RenderConfig constructor and
VeniceEngineImpl.initialize!)
This commit is contained in:
Eric J. Bowersox 2001-11-21 09:47:27 +00:00
parent 41299f6d85
commit 3752e73c2d
20 changed files with 1416 additions and 732 deletions

View File

@ -97,6 +97,9 @@
Image should be 100x100 pixels. --> Image should be 100x100 pixels. -->
<photo-not-avail fixup="true">photo_not_avail.gif</photo-not-avail> <photo-not-avail fixup="true">photo_not_avail.gif</photo-not-avail>
<!-- The location of the services configuration file, relative to the application root. -->
<services-config>WEB-INF/services-config.xml</services-config>
</paths> </paths>
<!-- Contains standard messages displayed by front end --> <!-- Contains standard messages displayed by front end -->

62
etc/services-config.xml Normal file
View File

@ -0,0 +1,62 @@
<?xml version="1.0"?>
<!--
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 <http://www.mozilla.org/MPL/>.
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 <erbo@silcom.com>,
for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
Contributor(s):
-->
<!-- Configuration for the various services that attach to Venice. -->
<services-config>
<!-- Defines services that attach to a particular community. -->
<community>
<!-- Profile service -->
<service id="Profile" index="0">
<setup default="true" locked="true"/>
<access/>
<link sequence="4900" href="sigprofile?sig=${cid}" type="servlet">Profile</link>
</service>
<!-- Community administration service -->
<service id="Admin" index="1">
<setup default="true" locked="true"/>
<access permission="Community.Read" role="Community.AnyAdmin"/>
<link sequence="5000" href="sigadmin?sig=${cid}" type="servlet">Administration</link>
</service>
<!-- System administration service -->
<service id="SysAdmin" index="2">
<setup locked="true"/>
<access permission="Global.SysAdminAccess"/>
<link sequence="10000" href="sysadmin" type="servlet">System Administration</link>
</service>
<!-- Conferences service -->
<service id="Conference" index="3">
<setup default="true"/>
<access permission="Community.Read"/>
<link sequence="500" href="confops?sig=${cid}" type="servlet">Conferences</link>
</service>
<!-- Members service -->
<service id="Members" index="4">
<setup default="true" locked="true"/>
<access permission="Community.Read"/>
<link sequence="4800" href="members?sig=${cid}" type="servlet">Members</link>
</service>
</community>
</services-config>

View File

@ -26,6 +26,9 @@
<!-- The pathname of the sidebox config file, relative to the Web application root directory. --> <!-- The pathname of the sidebox config file, relative to the Web application root directory. -->
<sidebox-config>WEB-INF/sidebox-config.xml</sidebox-config> <sidebox-config>WEB-INF/sidebox-config.xml</sidebox-config>
<!-- The pathname of the services config file, relative to the Web application root directory. -->
<services-config>WEB-INF/services-config.xml</services-config>
</engine> </engine>
<!-- This section is used to configure the database pool system. --> <!-- This section is used to configure the database pool system. -->
@ -303,8 +306,8 @@
main dictionary. The default lexicon is a standard US English one, with a supplemental list of main dictionary. The default lexicon is a standard US English one, with a supplemental list of
words provided by Erbo. --> words provided by Erbo. -->
<dictionary> <dictionary>
<file>/home/erbo/venice/WEB-INF/en-us.dict</file> <file>WEB-INF/en-us.dict</file>
<file>/home/erbo/venice/WEB-INF/erbo.dict</file> <file>WEB-INF/erbo.dict</file>
</dictionary> </dictionary>
<!-- Settings for dealing with uploads --> <!-- Settings for dealing with uploads -->

View File

@ -27,7 +27,7 @@ import org.w3c.dom.*;
* @version X * @version X
* @see org.w3c.dom.Element * @see org.w3c.dom.Element
*/ */
public class DOMElementHelper public final class DOMElementHelper
{ {
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Attributes * Attributes
@ -65,7 +65,7 @@ public class DOMElementHelper
* @return The text content under this <CODE>Element</CODE> node. If the specified <CODE>Element</CODE> * @return The text content under this <CODE>Element</CODE> node. If the specified <CODE>Element</CODE>
* has no text nodes underneath it, returns <CODE>null.</CODE> * has no text nodes underneath it, returns <CODE>null.</CODE>
*/ */
private static String getTextOfElement(Element e) private static final String getTextOfElement(Element e)
{ {
NodeList kids = e.getChildNodes(); NodeList kids = e.getChildNodes();
if (kids==null) if (kids==null)
@ -94,6 +94,30 @@ public class DOMElementHelper
} // end getTextOfElement } // end getTextOfElement
/**
* Returns the value of the text of the specified <CODE>Element</CODE>, expressed as an integer.
*
* @param e The <CODE>Element</CODE> to extract text from.
* @return An <CODE>Integer</CODE> object containing the value of the specified element. If
* the <CODE>Element</CODE> has no text, or if the text cannot be expressed as an integer,
* returns <CODE>null</CODE>.
*/
private static final Integer getIntegerFromElement(Element e)
{
try
{ // extract the text and create an Integer around it
String s = getTextOfElement(e);
return ((s==null) ? null : new Integer(s.trim()));
} // end try
catch (NumberFormatException nfe)
{ // value cannot be parsed as an integer
return null;
} // end catch
} // end getIntegerFromElement
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External operations * External operations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -104,7 +128,7 @@ public class DOMElementHelper
* *
* @return See above. * @return See above.
*/ */
public Element getElement() public final Element getElement()
{ {
return elt; return elt;
@ -118,7 +142,7 @@ public class DOMElementHelper
* If the <CODE>Element</CODE> has no child <CODE>Elements</CODE> with the given name, * If the <CODE>Element</CODE> has no child <CODE>Elements</CODE> with the given name,
* the method returns <CODE>null</CODE>. * the method returns <CODE>null</CODE>.
*/ */
public Element getSubElement(String name) public final Element getSubElement(String name)
{ {
NodeList kids = elt.getChildNodes(); NodeList kids = elt.getChildNodes();
if (kids==null) if (kids==null)
@ -142,12 +166,25 @@ public class DOMElementHelper
* @return The text content under the wrapped <CODE>Element</CODE> node. If the wrapped <CODE>Element</CODE> * @return The text content under the wrapped <CODE>Element</CODE> node. If the wrapped <CODE>Element</CODE>
* has not text nodes underneath it, returns <CODE>null.</CODE> * has not text nodes underneath it, returns <CODE>null.</CODE>
*/ */
public String getElementText() public final String getElementText()
{ {
return getTextOfElement(elt); return getTextOfElement(elt);
} // end getElementText } // end getElementText
/**
* Returns the value of the text of the wrapped <CODE>Element</CODE>, expressed as an integer.
*
* @return An <CODE>Integer</CODE> object containing the value of the wrapped element. If
* the <CODE>Element</CODE> has no text, or if the text cannot be expressed as an integer,
* returns <CODE>null</CODE>.
*/
public final Integer getElementInt()
{
return getIntegerFromElement(elt);
} // end getElementInt
/** /**
* Returns the content of all text nodes underneath the first sub-element of the wrapped * Returns the content of all text nodes underneath the first sub-element of the wrapped
* <CODE>Element</CODE>, with the given name, concatenated together into a single string. * <CODE>Element</CODE>, with the given name, concatenated together into a single string.
@ -157,16 +194,30 @@ public class DOMElementHelper
* If the wrapped <CODE>Element</CODE> does not have a sub-element with the given name, or * If the wrapped <CODE>Element</CODE> does not have a sub-element with the given name, or
* that sub-element has no text nodes underneath it, returns <CODE>null.</CODE> * that sub-element has no text nodes underneath it, returns <CODE>null.</CODE>
*/ */
public String getSubElementText(String name) public final String getSubElementText(String name)
{ {
Element se = getSubElement(name); Element se = getSubElement(name);
if (se==null) return ((se==null) ? null : getTextOfElement(se));
return null;
else
return getTextOfElement(se);
} // end getSubElementText } // end getSubElementText
/**
* Returns the value of the text underneath the first sub-element of the wrapped
* <CODE>Element</CODE>, with the given name, expressed as an integer.
*
* @param name The name of the sub-element to search for.
* @return An <CODE>Integer</CODE> object containing the value of the specified element. If
* the wrapped <CODE>Element</CODE> does not have a sub-element with the given name, or that
* sub-element has no text, or if the text cannot be expressed as an integer, returns
* <CODE>null</CODE>.
*/
public final Integer getSubElementInt(String name)
{
Element se = getSubElement(name);
return ((se==null) ? null : getIntegerFromElement(se));
} // end getSubElementInt
/** /**
* Determines whether the wrapped <CODE>Element</CODE> has a sub-element with the given name. * Determines whether the wrapped <CODE>Element</CODE> has a sub-element with the given name.
* *
@ -174,10 +225,9 @@ public class DOMElementHelper
* @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has a sub-element with the * @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has a sub-element with the
* specified name, <CODE>false</CODE> if not. * specified name, <CODE>false</CODE> if not.
*/ */
public boolean hasChildElement(String name) public final boolean hasChildElement(String name)
{ {
Element tmp = getSubElement(name); return (getSubElement(name)!=null);
return (tmp==null) ? false : true;
} // end hasChildElement } // end hasChildElement
@ -188,7 +238,7 @@ public class DOMElementHelper
* @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has an attribute with the * @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has an attribute with the
* specified name, <CODE>false</CODE> if not. * specified name, <CODE>false</CODE> if not.
*/ */
public boolean hasAttribute(String name) public final boolean hasAttribute(String name)
{ {
return !(StringUtil.isStringEmpty(elt.getAttribute(name))); return !(StringUtil.isStringEmpty(elt.getAttribute(name)));
@ -203,14 +253,14 @@ public class DOMElementHelper
* the wrapped <CODE>Element</CODE> has no such attribute, or if the attribute's value * the wrapped <CODE>Element</CODE> has no such attribute, or if the attribute's value
* cannot be expressed as an integer, returns <CODE>null</CODE>. * cannot be expressed as an integer, returns <CODE>null</CODE>.
*/ */
public Integer getAttributeInt(String name) public final Integer getAttributeInt(String name)
{ {
String tmp = elt.getAttribute(name); String tmp = elt.getAttribute(name);
if (StringUtil.isStringEmpty(tmp)) if (StringUtil.isStringEmpty(tmp))
return null; return null;
try try
{ // convert to an Integer { // convert to an Integer
return new Integer(tmp); return new Integer(tmp.trim());
} // end try } // end try
catch (NumberFormatException nfe) catch (NumberFormatException nfe)

View File

@ -0,0 +1,85 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util;
import java.util.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
public final class StockMessages
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(StockMessages.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Map msgmap;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public StockMessages(Element elt)
{
HashMap tmp_msgmap = new HashMap();
NodeList msgs = elt.getChildNodes();
for (int i=0; i<msgs.getLength(); i++)
{ // check each sub-element, get its message, and load it
Node n = msgs.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // add this node to the hashmap by its tag name
DOMElementHelper h = new DOMElementHelper((Element)n);
String txt = h.getElementText();
if (txt!=null)
tmp_msgmap.put(n.getNodeName(),txt.trim());
} // end if
} // end for
if (tmp_msgmap.size()>0)
msgmap = Collections.unmodifiableMap(tmp_msgmap);
else
msgmap = Collections.EMPTY_MAP;
if (logger.isDebugEnabled())
logger.debug(msgmap.size() + " stock message(s) loaded from <" + elt.getTagName() + "/> section");
} // end constructor
public final String get(String name)
{
return (String)(msgmap.get(name));
} // end get
public final String getReplace(String name, Map vars)
{
return StringUtil.replaceAllVariables((String)(msgmap.get(name)),vars);
} // end getReplace
} // end class StockMessages

View File

@ -17,14 +17,11 @@
*/ */
package com.silverwrist.venice.core; package com.silverwrist.venice.core;
import java.io.*;
import javax.xml.parsers.*;
import org.apache.log4j.*; import org.apache.log4j.*;
import org.w3c.dom.*; import org.w3c.dom.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.silverwrist.util.DOMElementHelper; import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.util.XMLLoader;
public class Startup public class Startup
{ {
@ -45,126 +42,28 @@ public class Startup
} // end constructor } // end constructor
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Internal functions * External static operations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private static String getEngineClassName(Document config) throws ConfigException
{
// Make sure the configuration is valid...
Element root = config.getDocumentElement();
if (!(root.getTagName().equals("venice-config")))
{ // not the correct root tag name
logger.fatal("config document is not a <venice-config/> document (root tag: <"
+ root.getTagName() + "/>)");
throw new ConfigException("document is not a <venice-config/> document",root);
} // end if
// Get the <engine/> section.
DOMElementHelper root_h = new DOMElementHelper(root);
Element engine_sect = root_h.getSubElement("engine");
if (engine_sect==null)
{ // no <engine/> section - bail out now!
logger.fatal("config document has no <engine/> section");
throw new ConfigException("no <engine/> section found in config file",root);
} // end if
// Get the classname out of that section.
DOMElementHelper engine_sect_h = new DOMElementHelper(engine_sect);
String rc = engine_sect_h.getSubElementText("classname");
if (rc==null)
{ // no <classname/> specified - bail out now!
logger.fatal("config document <engine/> section has no <classname/>");
throw new ConfigException("no <classname/> found in <engine/> section",engine_sect);
} // end if
return rc;
} // end getEngineClassName
/*--------------------------------------------------------------------------------
* External static methods (global functions)
*--------------------------------------------------------------------------------
*/
public static Document loadConfiguration(String configname) throws ConfigException
{
try
{ // create a simple DOM parser by using the Java XML parsing API
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(false);
fac.setValidating(false);
DocumentBuilder parser = fac.newDocumentBuilder();
// access the config file and parse it into our config data tree
File configfile = new File(configname);
Document rc = parser.parse(configfile);
if (logger.isDebugEnabled())
logger.debug("configuration loaded successfully");
return rc;
} // end try
catch (FactoryConfigurationError e1)
{ // if the document builder factory could not be created
logger.fatal("Parser factory configuration error: " + e1.getMessage(),e1);
throw new ConfigException("XML parser factory could not be created - " + e1.getMessage());
} // end catch
catch (ParserConfigurationException e2)
{ // if the XML parser itself could not be created
logger.fatal("Parser configuration error: " + e2.getMessage(),e2);
throw new ConfigException("XML parser could not be created - " + e2.getMessage(),e2);
} // end catch
catch (SAXException e3)
{ // if the XML parser choked on our document
if (e3 instanceof SAXParseException)
{ // we have a detailed message - make a proper exception
SAXParseException e3a = (SAXParseException)e3;
logger.fatal("Config file error [" + configname + ":" + e3a.getLineNumber() + ","
+ e3a.getColumnNumber() + "]: " + e3a.getMessage(),e3a);
throw new ConfigException("Configuration file error: " + e3a.getMessage() + " at line "
+ e3a.getLineNumber() + ", column " + e3a.getColumnNumber(),e3a);
} // end if
else
{ // generic exception - just send up a simple error message
logger.fatal("Config file error [" + configname + "]: " + e3.getMessage(),e3);
throw new ConfigException("Configuration file error - " + e3.getMessage(),e3);
} // end else
} // end catch
catch (IOException e4)
{ // error reading the config file itself off the disk
logger.fatal("IO error reading config: " + e4.getMessage(),e4);
throw new ConfigException("unable to read config file \"" + configname + "\" - " + e4.getMessage(),e4);
} // end catch
} // end loadConfiguration
public static VeniceEngine createEngine(String configname, String app_root) public static VeniceEngine createEngine(String configname, String app_root)
throws ConfigException, DataException throws ConfigException, DataException
{ {
XMLLoader loader = XMLLoader.get();
// load the configuration data // load the configuration data
Document config = loadConfiguration(configname); Document config = loader.loadConfigDocument(configname);
// find the classname of the engine // find the classname of the engine
String cname = getEngineClassName(config); Element root = loader.configGetRootElement(config,"venice-config");
Element sect = loader.configGetSubSection(root,"engine");
String cname = loader.configGetSubElementText(sect,"classname");
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Venice engine classname: " + cname); logger.debug("Venice engine classname: " + cname);
try try
{ // attempt to load the engine class { // create a new Venice engine (cast to the external interface)
Class engine_class = Class.forName(cname); VeniceEngine engine = (VeniceEngine)(Class.forName(cname).newInstance());
// now create a new Venice engine (cast to the external interface)
VeniceEngine engine = (VeniceEngine)(engine_class.newInstance());
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("VeniceEngine created successfully"); logger.debug("VeniceEngine created successfully");
@ -176,39 +75,39 @@ public class Startup
return engine; return engine;
} // end try } // end try
catch (ClassNotFoundException e1) catch (ClassNotFoundException cnfe)
{ // the class was not found { // the class was not found
logger.fatal("Venice engine class \"" + cname + "\" not found",e1); logger.fatal("Venice engine class \"" + cname + "\" not found",cnfe);
throw new ConfigException("Invalid engine classname: " + cname); throw new ConfigException("Invalid engine classname: " + cname);
} // end catch } // end catch
catch (IllegalAccessException e2) catch (IllegalAccessException iae)
{ // could not access constructor or something { // could not access constructor or something
logger.fatal("Can't access \"" + cname + "\" constructor: " + e2.getMessage(),e2); logger.fatal("Can't access \"" + cname + "\" constructor: " + iae.getMessage(),iae);
throw new ConfigException("Unable to create classname: " + cname); throw new ConfigException("Unable to create classname: " + cname);
} // end catch } // end catch
catch (InstantiationException e3) catch (InstantiationException ie)
{ // could not create the instance { // could not create the instance
logger.fatal("Can't create instance of \"" + cname + "\": " + e3.getMessage(),e3); logger.fatal("Can't create instance of \"" + cname + "\": " + ie.getMessage(),ie);
throw new ConfigException("Unable to create classname: " + cname); throw new ConfigException("Unable to create classname: " + cname);
} // end catch } // end catch
catch (ExceptionInInitializerError e4) catch (ExceptionInInitializerError eiie)
{ // some exception while initializing class { // some exception while initializing class
logger.fatal("Exception while initializing \"" + cname + "\": " + e4.getMessage(),e4); logger.fatal("Exception while initializing \"" + cname + "\": " + eiie.getMessage(),eiie);
throw new ConfigException("Unable to create classname: " + cname); throw new ConfigException("Unable to create classname: " + cname);
} // end catch } // end catch
catch (SecurityException e5) catch (SecurityException se)
{ // security violation somewhere { // security violation somewhere
logger.fatal("Security violation on \"" + cname + "\": " + e5.getMessage(),e5); logger.fatal("Security violation on \"" + cname + "\": " + se.getMessage(),se);
throw new ConfigException("Unable to create classname: " + cname); throw new ConfigException("Unable to create classname: " + cname);
} // end catch } // end catch
catch (ClassCastException e6) catch (ClassCastException cce)
{ // engine could not be cast to VeniceEngine interface type { // engine could not be cast to VeniceEngine interface type
logger.fatal("\"" + cname + "\" is not of type VeniceEngine",e6); logger.fatal("\"" + cname + "\" is not of type VeniceEngine",cce);
throw new ConfigException("Invalid engine classname: " + cname); throw new ConfigException("Invalid engine classname: " + cname);
} // end catch } // end catch

View File

@ -31,6 +31,8 @@ public interface VeniceEngine extends SearchMode
{ {
public abstract void initialize(Document config, String app_root) throws ConfigException, DataException; public abstract void initialize(Document config, String app_root) throws ConfigException, DataException;
public abstract void shutdown() throws ConfigException;
public abstract int getNumFeatures(); public abstract int getNumFeatures();
public abstract BitSet getAllFeaturesMask(); public abstract BitSet getAllFeaturesMask();

View File

@ -0,0 +1,144 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.util.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.security.*;
import com.silverwrist.venice.svc.*;
import com.silverwrist.venice.util.XMLLoader;
class ServiceControlManager
{
/*--------------------------------------------------------------------------------
* Internal "Community Service Site" class
*--------------------------------------------------------------------------------
*/
class MyCommServiceSite implements CommServiceSite
{
MyCommServiceSite()
{ // do nothing
} // end constructor
} // end class MyCommServiceSite
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(ServiceControlManager.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Map comm_symbol_to_service;
private Map comm_index_to_service;
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
ServiceControlManager(Document cfg, SecurityMonitor sm_global, SecurityMonitor sm_comm)
throws ConfigException
{
XMLLoader loader = XMLLoader.get();
Element root = loader.configGetRootElement(cfg,"services-config");
DOMElementHelper root_h = new DOMElementHelper(root);
NodeList nl;
int i;
// Get the "community" section
Element sect = root_h.getSubElement("community");
if (sect!=null)
{ // load the services for the section
HashMap tmp_symbol_to_service = new HashMap();
HashMap tmp_index_to_service = new HashMap();
nl = sect.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // get each element node...
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("service")))
{ // create the appropriate service settings
CommService svc = initCommunityService((Element)n,sm_comm);
tmp_symbol_to_service.put(svc.getSymbol(),svc);
tmp_index_to_service.put(new Integer(svc.getIndex()),svc);
} // end if
} // end for
if (tmp_symbol_to_service.size()>0)
comm_symbol_to_service = Collections.unmodifiableMap(tmp_symbol_to_service);
else
comm_symbol_to_service = Collections.EMPTY_MAP;
if (tmp_index_to_service.size()>0)
comm_index_to_service = Collections.unmodifiableMap(tmp_index_to_service);
else
comm_index_to_service = Collections.EMPTY_MAP;
} // end if
else
{ // no community services - undo this
comm_symbol_to_service = Collections.EMPTY_MAP;
comm_index_to_service = Collections.EMPTY_MAP;
} // end else
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private CommService initCommunityService(Element root, SecurityMonitor sm) throws ConfigException
{
CommService svc;
// FUTURE: do a create of a specific class
svc = new StaticCommService();
svc.initialize(root,sm,new MyCommServiceSite());
return svc;
} // end initCommunityService
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final void shutdown()
{
Iterator it = comm_symbol_to_service.values().iterator();
while (it.hasNext())
{ // shut down each service in turn
CommService svc = (CommService)(it.next());
svc.shutdown();
} // end while
} // end shutdown
} // end class ServiceControlManager

View File

@ -0,0 +1,135 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.security.*;
import com.silverwrist.venice.svc.*;
import com.silverwrist.venice.util.XMLLoader;
class StaticCommService implements CommService
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String symbol;
private int index;
private boolean is_default;
private boolean is_locked;
private SecurityMonitor secmon;
private String permission;
private Role role;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public StaticCommService()
{
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface CommunityService
*--------------------------------------------------------------------------------
*/
public void initialize(Element root, SecurityMonitor sm, CommServiceSite site) throws ConfigException
{
XMLLoader loader = XMLLoader.get();
// Load the symbol and index from the root element.
symbol = loader.configGetAttribute(root,"id");
index = loader.configGetAttributeInt(root,"index");
// Get the setup from the subelement.
DOMElementHelper h = new DOMElementHelper(root);
Element sub = h.getSubElement("setup");
if (sub!=null)
{ // read the values of the "default" and "locked" flags
DOMElementHelper h2 = new DOMElementHelper(sub);
is_default = h2.hasAttribute("default");
is_locked = h2.hasAttribute("locked");
} // end if
else
{ // default those two flags
is_default = false;
is_locked = false;
} // end else
// Get the access control element from the subelement.
sub = h.getSubElement("access");
if (sub!=null)
{ // get the attributes...
DOMElementHelper h3 = new DOMElementHelper(sub);
if (h3.hasAttribute("permission"))
{ // get the permission and verify that it exists
permission = sub.getAttribute("permission");
if (!(sm.permissionDefined(permission,false)))
throw new ConfigException("permission \"" + permission + "\" is not defined",sub);
} // end if
else // just null out the permission
permission = null;
if (h3.hasAttribute("role"))
{ // get the role and verify that it exists
role = sm.getRole(sub.getAttribute("role"));
if (role==null)
throw new ConfigException("role \"" + sub.getAttribute("role") + "\" is not defined",sub);
} // end if
else // default the role
role = sm.getRole("NotInList");
} // end if
else
{ // default the values
permission = null;
role = sm.getRole("NotInList");
} // end else
// Save the security monitor reference.
secmon = sm;
} // end initialize
public void shutdown()
{ // do nothing
} // end shutdown
public String getSymbol()
{
return symbol;
} // end getSymbol
public int getIndex()
{
return index;
} // end getIndex
} // end class StaticCommService

View File

@ -32,6 +32,7 @@ import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.htmlcheck.dict.*; import com.silverwrist.venice.htmlcheck.dict.*;
import com.silverwrist.venice.htmlcheck.filters.*; import com.silverwrist.venice.htmlcheck.filters.*;
import com.silverwrist.venice.security.*; import com.silverwrist.venice.security.*;
import com.silverwrist.venice.util.XMLLoader;
public class VeniceEngineImpl implements VeniceEngine, EngineBackend public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{ {
@ -143,37 +144,13 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
MasterSideBox(Element section) throws ConfigException MasterSideBox(Element section) throws ConfigException
{ {
try XMLLoader loader = XMLLoader.get();
{ // get the ID value for this sidebox id = loader.configGetAttributeInt(section,"id");
String tmp = section.getAttribute("id");
if (StringUtil.isStringEmpty(tmp))
{ // there's no
logger.fatal("<sidebox/> specified with no ID!");
throw new ConfigException("no ID specified in <sidebox/>",section);
} // end if
id = Integer.parseInt(tmp);
} // end try
catch (NumberFormatException e)
{ // sidebox ID not numeric
logger.fatal("<sidebox/> ID not numeric!");
throw new ConfigException("non-numeric ID specified in <sidebox/>",section);
} // end catch
// get the title and classname
DOMElementHelper section_h = new DOMElementHelper(section); DOMElementHelper section_h = new DOMElementHelper(section);
title = section_h.getSubElementText("title"); title = loader.configGetSubElementText(section_h,"title");
anon_title = section_h.getSubElementText("anon-title"); classname = loader.configGetSubElementText(section_h,"factory-class");
classname = section_h.getSubElementText("factory-class");
if (StringUtil.isStringEmpty(title) || StringUtil.isStringEmpty(classname))
{ // the configuration is not complete
logger.fatal("<sidebox/> config incomplete (missing <title/> or <factory-class/>)!");
throw new ConfigException("configuration of <sidebox/> is not complete!",section);
} // end if
try try
{ // try to resolve the classname here so we can be sure it's cool { // try to resolve the classname here so we can be sure it's cool
@ -187,6 +164,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end catch } // end catch
// get the anonymous title and default it if it's not found
anon_title = section_h.getSubElementText("anon-title");
if (StringUtil.isStringEmpty(anon_title)) if (StringUtil.isStringEmpty(anon_title))
anon_title = title; // just set as the same in the event of difficulty anon_title = title; // just set as the same in the event of difficulty
@ -218,35 +197,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end class MasterSideBox } // end class MasterSideBox
/*--------------------------------------------------------------------------------
* Internal class for returning side box information.
*--------------------------------------------------------------------------------
*/
static class MasterSideBoxList extends AbstractList
{
private MasterSideBox[] array;
MasterSideBoxList(MasterSideBox[] array)
{
this.array = array;
} // end constructor
public Object get(int index)
{
return array[index];
} // end get
public int size()
{
return array.length;
} // end size
} // end class MasterSideBoxList
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Internal class for creating new CommunityCoreData objects. * Internal class for creating new CommunityCoreData objects.
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -390,12 +340,11 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private Document config = null; // configuration data
private EnvEngine env = null; // my environment private EnvEngine env = null; // my environment
private Random rng; // random number generator private Random rng; // random number generator
private Properties email_props = null; // email properties private Properties email_props = null; // email properties
private javax.mail.Session mailsession = null; // email session object private javax.mail.Session mailsession = null; // email session object
private Hashtable stock_messages = null; // stock messages holder private StockMessages stock_messages = null; // stock messages holder
private ObjectCache comm_objcache = new ObjectCache(new CommunityCoreDataCreator()); private ObjectCache comm_objcache = new ObjectCache(new CommunityCoreDataCreator());
private VeniceFeatureDef[] features; // master feature table private VeniceFeatureDef[] features; // master feature table
private Hashtable feature_syms = new Hashtable(); // hashtable mapping symbols to features private Hashtable feature_syms = new Hashtable(); // hashtable mapping symbols to features
@ -412,6 +361,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private SecurityMonitor global_security; // the global security monitor private SecurityMonitor global_security; // the global security monitor
private SecurityMonitor community_security; // the community security monitor private SecurityMonitor community_security; // the community security monitor
private SecurityMonitor conference_security; // conference security monitor (will move eventually) private SecurityMonitor conference_security; // conference security monitor (will move eventually)
private ServiceControlManager scmgr; // service control manager
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
@ -431,9 +381,34 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private static Collection getDictionaryNames(Element sect, String app_root)
{
ArrayList rc = new ArrayList();
NodeList nl = sect.getChildNodes();
for (int i=0; i<nl.getLength(); i++)
{ // scan the element looking for <file/> elements
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("file")))
{ // extract the name of the file, possibly prefixing the application root directory
DOMElementHelper h = new DOMElementHelper((Element)n);
String fname = h.getElementText();
if (fname==null)
continue; // no file name???
if (!(fname.startsWith("/")))
fname = app_root + fname;
rc.add(fname);
} // end if
} // end for
return rc;
} // end getDictionaryNames
private void checkInitialized() private void checkInitialized()
{ {
if (config==null) if (env==null)
throw new InternalStateError("Venice engine not initialized!"); throw new InternalStateError("Venice engine not initialized!");
} // end checkInitialized } // end checkInitialized
@ -643,89 +618,41 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{ {
int i; // loop counter int i; // loop counter
if (this.config!=null) if (env!=null)
{ // already configured! { // already configured!
logger.error("Venice engine already initialized"); logger.error("Venice engine already initialized");
throw new ConfigException("Venice engine already initialized"); throw new ConfigException("Venice engine already initialized");
} // end if } // end if
this.config = config;
DataPool datapool = null; DataPool datapool = null;
ArrayList dictionary_tmp; Collection dictionary_tmp;
try try
{ // first, verify that this is a valid configuration { // first, verify that this is a valid configuration
Element root = config.getDocumentElement(); XMLLoader loader = XMLLoader.get();
if (!(root.getTagName().equals("venice-config"))) Element root = loader.configGetRootElement(config,"venice-config");
{ // not the correct root tag name
logger.fatal("config document is not a <venice-config/> document (root tag: <"
+ root.getTagName() + "/>)");
throw new ConfigException("document is not a <venice-config/> document",root);
} // end if
DOMElementHelper root_h = new DOMElementHelper(root); DOMElementHelper root_h = new DOMElementHelper(root);
// Get the <engine/> section. // Get the <engine/> section.
Element engine_sect = root_h.getSubElement("engine"); Element sect = loader.configGetSubSection(root_h,"engine");
if (engine_sect==null) DOMElementHelper sect_h = new DOMElementHelper(sect);
{ // unable to find the engine section
logger.fatal("config document has no <engine/> section");
throw new ConfigException("no <engine/> section found in config file",root);
} // end if
DOMElementHelper engine_h = new DOMElementHelper(engine_sect);
// Get the name of the sidebox config file. // Get the name of the sidebox config file.
String sidebox_config = engine_h.getSubElementText("sidebox-config"); String sidebox_config = loader.configGetSubElementText(sect_h,"sidebox-config");
if (sidebox_config==null)
{ // unable to find the sidebox config file
logger.fatal("<engine/> section has no <sidebox-config/> element");
throw new ConfigException("no <sidebox-config/> element found in <engine/> section",engine_sect);
} // end if
if (!(sidebox_config.startsWith("/"))) if (!(sidebox_config.startsWith("/")))
sidebox_config = app_root + sidebox_config; sidebox_config = app_root + sidebox_config;
Document sidebox_cfg_file = Startup.loadConfiguration(sidebox_config);
Element sb_root = sidebox_cfg_file.getDocumentElement();
if (!(sb_root.getTagName().equals("sidebox-config")))
{ // the sidebox configuration file isn't the right type
logger.fatal("config document is not a <sidebox-config/> document (root tag: <"
+ sb_root.getTagName() + "/>)");
throw new ConfigException("document is not a <sidebox-config/> document",sb_root);
} // end if // Get the name of the services config file.
String services_config = loader.configGetSubElementText(sect_h,"services-config");
NodeList sb_nodes = sb_root.getChildNodes(); if (!(services_config.startsWith("/")))
ArrayList sidebox_tmp = new ArrayList(); services_config = app_root + services_config;
for (i=0; i<sb_nodes.getLength(); i++)
{ // extract each sidebox section from the list and build a new master sidebox object
Node s = sb_nodes.item(i);
if ((s.getNodeType()==Node.ELEMENT_NODE) && (s.getNodeName().equals("sidebox")))
sidebox_tmp.add(new MasterSideBox((Element)s));
} // end for
// store the real master sidebox table as an array
sideboxes = (MasterSideBox[])(sidebox_tmp.toArray(new MasterSideBox[0]));
if (logger.isDebugEnabled())
logger.debug(sideboxes.length + " sidebox definitions loaded from XML");
// Get the <database/> section. // Get the <database/> section.
Element db_sect = root_h.getSubElement("database"); sect = loader.configGetSubSection(root_h,"database");
if (db_sect==null)
{ // unable to find the database section
logger.fatal("config document has no <database/> section");
throw new ConfigException("no <database/> section found in config file",root);
} // end if
try try
{ // allocate the data pool object { // allocate the data pool object
datapool = new DataPool(db_sect); datapool = new DataPool(sect);
} // end try } // end try
catch (SQLException e) catch (SQLException e)
@ -735,20 +662,16 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end catch } // end catch
Element security_sect = root_h.getSubElement("security"); // Get the <security/> section.
if (security_sect==null) sect = loader.configGetSubSection(root_h,"security");
{ // no "security" section...bad!
logger.fatal("config document has no <security/> section");
throw new ConfigException("no <security/> section found in config file",root);
} // end if // Load the security monitors.
NodeList nl = sect.getChildNodes();
NodeList sec_nodes = security_sect.getChildNodes(); for (i=0; i<nl.getLength(); i++)
for (i=0; i<sec_nodes.getLength(); i++)
{ // scan through and find security monitors to initialize { // scan through and find security monitors to initialize
Node n = sec_nodes.item(i); Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("security-definition"))) if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("security-definition")))
{ // initial security definition { // load one of the initial security definitions
SecurityMonitor sm = new StaticSecurityMonitor((Element)n); SecurityMonitor sm = new StaticSecurityMonitor((Element)n);
if (sm.getID().equals("Global")) if (sm.getID().equals("Global"))
global_security = sm; global_security = sm;
@ -761,120 +684,85 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end for } // end for
Element email_sect = root_h.getSubElement("email"); // Get the <email/> section.
if (email_sect==null) sect = loader.configGetSubSection(root_h,"email");
{ // unable to find the database section sect_h = new DOMElementHelper(sect);
logger.fatal("config document has no <email/> section");
throw new ConfigException("no <email/> section found in config file",root);
} // end if
// initialize the email properties and get a mail session object // initialize the email properties and get a mail session object
email_props = new Properties(); email_props = new Properties();
email_props.put("mail.transport.protocol","smtp"); email_props.put("mail.transport.protocol","smtp");
DOMElementHelper email_sect_h = new DOMElementHelper(email_sect); email_props.put("mail.smtp.host",sect_h.getSubElementText("smtp-host"));
email_props.put("mail.smtp.host",email_sect_h.getSubElementText("smtp-host")); email_props.put("mail.from",sect_h.getSubElementText("mail-from-addr"));
email_props.put("mail.from",email_sect_h.getSubElementText("mail-from-addr")); email_props.put("com.silverwrist.venice.email.mailer",sect_h.getSubElementText("mailer"));
email_props.put("com.silverwrist.venice.email.mailer",email_sect_h.getSubElementText("mailer"));
mailsession = javax.mail.Session.getInstance(email_props,null); mailsession = javax.mail.Session.getInstance(email_props,null);
Element dict_sect = root_h.getSubElement("dictionary"); // Get the <dictionary/> section.
if (dict_sect==null) sect = loader.configGetSubSection(root_h,"dictionary");
{ // unable to find the database section
logger.fatal("config document has no <dictionary/> section");
throw new ConfigException("no <dictionary/> section found in config file",root);
} // end if // Retrieve the list of dictionary files.
dictionary_tmp = getDictionaryNames(sect,app_root);
// Retrieve the list of dictionary files to load into the spellchecker. // Get the <upload/> section.
dictionary_tmp = new ArrayList(); sect = loader.configGetSubSection(root_h,"upload");
NodeList dict_nodes = dict_sect.getChildNodes(); sect_h = new DOMElementHelper(sect);
for (i=0; i<dict_nodes.getLength(); i++)
{ // scan the <dictionary> element looking for <file> elements
Node dn = dict_nodes.item(i);
if ((dn.getNodeType()==Node.ELEMENT_NODE) && (dn.getNodeName().equals("file")))
{ // store the file name as a vector element
Element del = (Element)dn;
DOMElementHelper h = new DOMElementHelper(del);
dictionary_tmp.add(h.getElementText());
} // end if
} // end for
Element upload_sect = root_h.getSubElement("upload");
if (upload_sect==null)
{ // unable to find the "upload" section
logger.fatal("config document has no <upload/> section");
throw new ConfigException("no <upload/> section found in config file",root);
} // end if
// Look for a "no-compress" blacklist. // Look for a "no-compress" blacklist.
DOMElementHelper upload_sect_h = new DOMElementHelper(upload_sect); Element subsect = sect_h.getSubElement("no-compress");
Element no_compress_sect = upload_sect_h.getSubElement("no-compress"); if (subsect!=null)
if (no_compress_sect!=null)
{ // Initialize the no-compress list. { // Initialize the no-compress list.
NodeList nc_nodes = no_compress_sect.getChildNodes(); nl = subsect.getChildNodes();
for (i=0; i<nc_nodes.getLength(); i++) for (i=0; i<nl.getLength(); i++)
{ // retrieve all entries from the list { // retrieve all entries from the list
Node ncn = nc_nodes.item(i); Node n = nl.item(i);
if (ncn.getNodeType()==Node.ELEMENT_NODE) if (n.getNodeType()==Node.ELEMENT_NODE)
{ // get the element { // look at the element name now
DOMElementHelper ncel = new DOMElementHelper((Element)ncn); loader.configVerifyNodeName(n,"type",subsect);
if (ncel.getElement().getNodeName().equals("type")) DOMElementHelper h = new DOMElementHelper((Element)n);
{ // add a new element to the list no_compress_types.add(h.getElementText().trim().toLowerCase());
no_compress_types.add(ncel.getElementText().trim().toLowerCase());
} // end if
else
{ // this is bad - bail out!
logger.fatal("spurious element in <no-compress/> section");
throw new ConfigException("<no-compress/> section contains spurious element",no_compress_sect);
} // end else
} // end if } // end if
// else skip it // else skip this node
} // end for } // end for
} // end if } // end if
// else no list, just proceed // else no list, just proceed
Element msg_sect = root_h.getSubElement("messages");
if (msg_sect==null)
{ // unable to find the database section
logger.fatal("config document has no <messages/> section");
throw new ConfigException("no <messages/> section found in config file",root);
} // end if // Get the <messages/> section.
sect = loader.configGetSubSection(root_h,"messages");
// Initialize the stock messages list. // Initialize the stock messages list.
stock_messages = new Hashtable(); stock_messages = new StockMessages(sect);
NodeList msg_nodes = msg_sect.getChildNodes();
for (i=0; i<msg_nodes.getLength(); i++)
{ // examine all subnodes to add them to the message text
Node msgn = msg_nodes.item(i);
if (msgn.getNodeType()==Node.ELEMENT_NODE)
{ // add it to the hash table by its tag name
Element msgel = (Element)msgn;
DOMElementHelper h = new DOMElementHelper(msgel);
String txt = h.getElementText();
if (txt!=null)
stock_messages.put(msgel.getTagName(),txt.trim());
} // end if // Now done with the master config...
// Load the sidebox configuration file.
Document subdoc = loader.loadConfigDocument(sidebox_config);
root = loader.configGetRootElement(subdoc,"sidebox-config");
// Load the individual sideboxes.
ArrayList sidebox_tmp = new ArrayList();
nl = root.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // extract each sidebox section from the list and build a new master sidebox object
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("sidebox")))
sidebox_tmp.add(new MasterSideBox((Element)n));
} // end for } // end for
// store the real master sidebox table as an array
sideboxes = (MasterSideBox[])(sidebox_tmp.toArray(new MasterSideBox[0]));
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug(stock_messages.size() + " stock messages loaded from config"); logger.debug(sideboxes.length + " sidebox definitions loaded from XML");
// Now done with the sidebox config...
// Load the services config file.
subdoc = loader.loadConfigDocument(services_config);
scmgr = new ServiceControlManager(subdoc,global_security,community_security);
} // end try } // end try
catch (ConfigException ce) catch (ConfigException ce)
{ // before we leave on a ConfigException, nuke the important data { // before we leave on a ConfigException, nuke the important data
this.config = null;
if (datapool!=null) if (datapool!=null)
datapool.closeAllConnections(); datapool.closeAllConnections();
throw ce; throw ce;
@ -1014,6 +902,21 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end initialize } // end initialize
public void shutdown() throws ConfigException
{
if (env==null)
{ // already configured!
logger.error("Venice engine not initialized");
throw new ConfigException("Venice engine not initialized");
} // end if
scmgr.shutdown();
env.getDataPool().closeAllConnections();
env = null;
} // end shutdown
public int getNumFeatures() public int getNumFeatures()
{ {
checkInitialized(); checkInitialized();
@ -1765,7 +1668,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
public List getMasterSideBoxList() public List getMasterSideBoxList()
{ {
return new MasterSideBoxList(sideboxes); return Arrays.asList(sideboxes);
} // end getMasterSideBoxList } // end getMasterSideBoxList

View File

@ -26,7 +26,7 @@ import org.apache.log4j.*;
import com.silverwrist.venice.core.*; import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.servlets.format.*; import com.silverwrist.venice.servlets.format.*;
import com.silverwrist.venice.servlets.format.menus.LeftMenu; import com.silverwrist.venice.servlets.format.menus.*;
public class Variables public class Variables
{ {
@ -206,23 +206,34 @@ public class Variables
} // end setMenuTop } // end setMenuTop
public static void setMenuCommunity(HttpSession session, CommunityContext comm) public static void setMenuCommunity(ServletContext ctxt, HttpSession session, CommunityContext comm)
{ {
Object obj = session.getAttribute(MENU_ATTRIBUTE); Object obj = session.getAttribute(MENU_ATTRIBUTE);
boolean do_change; boolean do_change;
if ((obj==null) || !(obj instanceof MenuCommunity)) if ((obj==null) || !(obj instanceof CommunityLeftMenu))
do_change = true; do_change = true;
else else
{ // look at the actual community IDs underlying the MenuCommunity { // look at the actual community IDs underlying the MenuCommunity
MenuCommunity tmp = (MenuCommunity)obj; CommunityLeftMenu tmp = (CommunityLeftMenu)obj;
do_change = (tmp.getID()!=comm.getCommunityID()); do_change = (tmp.getID()!=comm.getCommunityID());
} // end else } // end else
if (do_change) if (do_change)
{ // switch to the appropriate MenuCommunity { // switch to the appropriate CommunityLeftMenu
MenuCommunity mc = new MenuCommunity(comm); try
session.setAttribute(MENU_ATTRIBUTE,mc); { // but note that getting the rendering configuration can throw a ServletException
RenderConfig cfg = RenderConfig.getRenderConfig(ctxt);
CommunityLeftMenu menu = cfg.createCommunityMenu(comm);
session.setAttribute(MENU_ATTRIBUTE,menu);
} // end try
catch (ServletException e)
{ // if we fail, just clear it out
logger.warn("caught ServletException in setMenuCommunity",e);
session.removeAttribute(MENU_ATTRIBUTE);
} // end catch
} // end if } // end if

View File

@ -321,7 +321,7 @@ public abstract class VeniceServlet extends HttpServlet
protected final void changeMenuCommunity(HttpServletRequest request, CommunityContext comm) protected final void changeMenuCommunity(HttpServletRequest request, CommunityContext comm)
{ {
Variables.setMenuCommunity(request.getSession(true),comm); Variables.setMenuCommunity(getServletContext(),request.getSession(true),comm);
} // end changeMenuCommunity } // end changeMenuCommunity

View File

@ -21,22 +21,17 @@ import java.io.*;
import java.util.*; import java.util.*;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import javax.xml.parsers.*;
import org.apache.log4j.*; import org.apache.log4j.*;
import org.w3c.dom.*; import org.w3c.dom.*;
import org.xml.sax.SAXException; import com.silverwrist.util.*;
import org.xml.sax.SAXParseException; import com.silverwrist.venice.core.CommunityContext;
import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.util.IOUtil;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.UserContext; import com.silverwrist.venice.core.UserContext;
import com.silverwrist.venice.core.VeniceEngine; import com.silverwrist.venice.core.VeniceEngine;
import com.silverwrist.venice.except.AccessError; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.except.ConfigException;
import com.silverwrist.venice.except.DataException;
import com.silverwrist.venice.servlets.Variables; import com.silverwrist.venice.servlets.Variables;
import com.silverwrist.venice.servlets.format.menus.LeftMenu; import com.silverwrist.venice.servlets.format.menus.*;
import com.silverwrist.venice.servlets.format.sideboxes.SideBoxFactory; import com.silverwrist.venice.servlets.format.sideboxes.SideBoxFactory;
import com.silverwrist.venice.util.XMLLoader;
public class RenderConfig implements ColorSelectors public class RenderConfig implements ColorSelectors
{ {
@ -57,7 +52,6 @@ public class RenderConfig implements ColorSelectors
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private Document config;
private String site_title; private String site_title;
private boolean want_comments; private boolean want_comments;
private boolean allow_gzip; private boolean allow_gzip;
@ -71,13 +65,14 @@ public class RenderConfig implements ColorSelectors
private int site_logo_width = 140; private int site_logo_width = 140;
private int site_logo_height = 80; private int site_logo_height = 80;
private String site_logo_linkURL = null; private String site_logo_linkURL = null;
private HashMap stock_messages; private StockMessages stock_messages;
private HashMap menus; private Map menus;
private String[] colors_array; private String[] colors_array;
private int footer_logo_scale; private int footer_logo_scale;
private Map sidebox_factories; private Map sidebox_factories;
private String photo_not_avail; private String photo_not_avail;
private boolean photo_not_avail_fixup; private boolean photo_not_avail_fixup;
private CommunityLeftMenuFactory comm_menu_fact;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
@ -86,104 +81,76 @@ public class RenderConfig implements ColorSelectors
protected RenderConfig(String config_file, String root_file_path) throws ConfigException protected RenderConfig(String config_file, String root_file_path) throws ConfigException
{ {
config = loadConfiguration(config_file); XMLLoader loader = XMLLoader.get();
Document doc = loader.loadConfigDocument(config_file);
// Make sure the configuration is valid... // Make sure the document is valid.
Element root = config.getDocumentElement(); Element root = loader.configGetRootElement(doc,"render-config");
if (!(root.getTagName().equals("render-config")))
{ // not the correct root tag name
logger.fatal("config document is not a <render-config/> document (root tag: <"
+ root.getTagName() + "/>)");
throw new ConfigException("document is not a <render-config/> document",root);
} // end if
// Get the site name.
DOMElementHelper root_h = new DOMElementHelper(root); DOMElementHelper root_h = new DOMElementHelper(root);
site_title = root_h.getSubElementText("site-name");
if (site_title==null)
{ // no <site-name/> section - bail out now!
logger.fatal("config document has no <site-title/> element");
throw new ConfigException("no <site-title/> section found in config file",root);
} // end if
// Get the site title.
site_title = loader.configGetSubElementText(root_h,"site-name");
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Site title: " + site_title); logger.debug("Site title: " + site_title);
Element render_sect = root_h.getSubElement("rendering"); // Get the <rendering/> section.
if (render_sect==null) Element sect = loader.configGetSubSection(root_h,"rendering");
{ // no <rendering/> section - bail out now!
logger.fatal("config document has no <rendering/> section");
throw new ConfigException("no <rendering/> section found in config file",root);
} // end if // Load the quick Boolean values indicated by the presence or absence of a tag.
DOMElementHelper sect_h = new DOMElementHelper(sect);
DOMElementHelper render_sect_h = new DOMElementHelper(render_sect); want_comments = sect_h.hasChildElement("html-comments");
want_comments = render_sect_h.hasChildElement("html-comments"); allow_gzip = sect_h.hasChildElement("gzip-output");
allow_gzip = render_sect_h.hasChildElement("gzip-output"); no_smart_tags = !(sect_h.hasChildElement("ms-copyright-violations"));
no_smart_tags = !(render_sect_h.hasChildElement("ms-copyright-violations"));
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ // log the read values { // log the read values
logger.debug("Use HTML comments: " + String.valueOf(want_comments)); logger.debug("Use HTML comments: " + want_comments);
logger.debug("Use GZIP encoding: " + String.valueOf(allow_gzip)); logger.debug("Use GZIP encoding: " + allow_gzip);
logger.debug("Disable IE Smart Tags: " + String.valueOf(no_smart_tags)); logger.debug("Disable IE Smart Tags: " + no_smart_tags);
} // end if
font_face = render_sect_h.getSubElementText("font");
if (font_face==null)
{ // no <font/> tag - bail out now!
logger.fatal("<rendering/> section has no <font/> element");
throw new ConfigException("no <font/> found in <rendering/> section",render_sect);
} // end if } // end if
// Load the default font face.
font_face = loader.configGetSubElementText(sect_h,"font");
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Font face: " + font_face); logger.debug("Font face: " + font_face);
String stylesheet_loc = render_sect_h.getSubElementText("stylesheet"); // Load the default stylesheet file reference.
if (stylesheet_loc!=null) String tmp = sect_h.getSubElementText("stylesheet");
if (tmp!=null)
{ // we're using Cascading Stylesheets - load it and test for existence { // we're using Cascading Stylesheets - load it and test for existence
if (!(stylesheet_loc.startsWith("/"))) if (!(tmp.startsWith("/"))) // prepend app root
stylesheet_loc = root_file_path + stylesheet_loc; tmp = root_file_path + tmp;
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Stylesheet location: " + stylesheet_loc); logger.debug("Stylesheet location: " + tmp);
// Test to make sure the stylesheet is actually present. // Test to make sure the stylesheet is actually present.
stylesheet = new File(stylesheet_loc); stylesheet = new File(tmp);
if (!(stylesheet.exists() && stylesheet.canRead())) if (!(stylesheet.exists() && stylesheet.canRead()))
{ // it's not there - bail out! { // it's not there - bail out!
logger.fatal("unable to read stylesheet file: " + stylesheet_loc); logger.fatal("unable to read stylesheet file: " + tmp);
throw new ConfigException("stylesheet " + stylesheet_loc + " cannot be read",render_sect); throw new ConfigException("stylesheet " + tmp + " cannot be read",sect);
} // end if } // end if
} // end if } // end if
else // no stylesheet else // no stylesheet
stylesheet = null; stylesheet = null;
Element colors_sect = render_sect_h.getSubElement("colors"); // Get the <colors/> section and load the colors out of it..
if (colors_sect==null) Element sect1 = loader.configGetSubSection(sect_h,"colors");
{ // no <colors/> tag - bail out now!
logger.fatal("<rendering/> section has no <colors/> element");
throw new ConfigException("no <colors/> found in <rendering/> section",render_sect);
} // end if
colors_array = new String[colornames_map.size()]; colors_array = new String[colornames_map.size()];
int i; int i;
NodeList colors_nlist = colors_sect.getChildNodes(); NodeList nl = sect1.getChildNodes();
for (i=0; i<colors_nlist.getLength(); i++) for (i=0; i<nl.getLength(); i++)
{ // look at all subelements and map their names to color selectors { // look at all subelements and map their names to color selectors
Node foo = colors_nlist.item(i); Node n = nl.item(i);
if (foo.getNodeType()==Node.ELEMENT_NODE) if (n.getNodeType()==Node.ELEMENT_NODE)
{ // map the element name to a color selector { // map the name of the node to a color selector
Integer csel = (Integer)(colornames_map.get(foo.getNodeName())); Integer cs = (Integer)(colornames_map.get(n.getNodeName()));
if (csel!=null) if (cs!=null)
{ // load the specified color into the colors array { // get the color value and load it into the array
DOMElementHelper foo_h = new DOMElementHelper((Element)foo); DOMElementHelper h = new DOMElementHelper((Element)n);
colors_array[csel.intValue()] = foo_h.getElementText(); colors_array[cs.intValue()] = h.getElementText();
} // end if } // end if
@ -191,186 +158,57 @@ public class RenderConfig implements ColorSelectors
} // end for } // end for
try // Load in the footer logo scale.
{ // load in the footer logo scale Integer itmp = sect_h.getSubElementInt("footer-logo-scale");
String tmp = render_sect_h.getSubElementText("footer-logo-scale"); footer_logo_scale = ((itmp==null) ? 100 : itmp.intValue());
if (tmp==null)
footer_logo_scale = 100;
else
footer_logo_scale = Integer.parseInt(tmp.trim());
} // end try // Get the <paths/> section.
catch (NumberFormatException nfe) sect = loader.configGetSubSection(root_h,"paths");
{ // just default on serious error sect_h = new DOMElementHelper(sect);
footer_logo_scale = 100;
} // end catch
Element paths_sect = root_h.getSubElement("paths");
if (paths_sect==null)
{ // no <paths/> section - bail out now!
logger.fatal("config document has no <paths/> section");
throw new ConfigException("no <paths/> section found in config file",root);
} // end if
DOMElementHelper paths_sect_h = new DOMElementHelper(paths_sect);
image_url = paths_sect_h.getSubElementText("image");
if (image_url==null)
{ // no <image/> tag - bail out now!
logger.fatal("<paths/> section has no <image/> element");
throw new ConfigException("no <image/> found in <paths/> section",paths_sect);
} // end if
// Load the image path.
image_url = loader.configGetSubElementText(sect_h,"image");
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Image path: " + image_url); logger.debug("Image path: " + image_url);
static_url = paths_sect_h.getSubElementText("static"); // Load the static path.
if (static_url==null) static_url = loader.configGetSubElementText(sect_h,"static");
{ // no <static/> tag - bail out now!
logger.fatal("<paths/> section has no <static/> element");
throw new ConfigException("no <static/> found in <paths/> section",paths_sect);
} // end if
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Static files path: " + static_url); logger.debug("Static files path: " + static_url);
Element site_logo_elt = paths_sect_h.getSubElement("site-logo"); // Get the site logo element.
if (site_logo_elt==null) sect1 = loader.configGetSubSection(sect_h,"site-logo");
{ // no <site-logo/> tag - bail out now! DOMElementHelper sect1_h = new DOMElementHelper(sect1);
logger.fatal("<paths/> section has no <site-logo/> element"); site_logo = loader.configGetText(sect1_h);
throw new ConfigException("no <site-logo/> found in <paths/> section",paths_sect);
} // end if // Get the width and height of the logo.
itmp = sect1_h.getAttributeInt("width");
if (itmp!=null)
site_logo_width = itmp.intValue();
itmp = sect1_h.getAttributeInt("height");
if (itmp!=null)
site_logo_height = itmp.intValue();
DOMElementHelper site_logo_h = new DOMElementHelper(site_logo_elt); // Get the link URL of the logo.
site_logo = site_logo_h.getElementText(); tmp = sect1.getAttribute("href");
if (site_logo==null)
{ // no site logo specified - bail out now!
logger.fatal("<paths/> section has no site logo element");
throw new ConfigException("no site logo found in <paths/> section",paths_sect);
} // end if
// get logo width and height
Integer fooint = site_logo_h.getAttributeInt("width");
if (fooint!=null)
site_logo_width = fooint.intValue();
fooint = site_logo_h.getAttributeInt("height");
if (fooint!=null)
site_logo_height = fooint.intValue();
// get logo link URL
String tmp = site_logo_elt.getAttribute("href");
if (!(StringUtil.isStringEmpty(tmp))) if (!(StringUtil.isStringEmpty(tmp)))
site_logo_linkURL = tmp; site_logo_linkURL = tmp;
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Site logo: " + site_logo); logger.debug("Site logo: " + site_logo);
// Load the sidebox configuration information. // Get the name of the sidebox configuration file.
String sidebox_config = paths_sect_h.getSubElementText("sidebox-config"); String sidebox_config = loader.configGetSubElementText(sect_h,"sidebox-config");
if (sidebox_config==null)
{ // the sidebox config was not present
logger.fatal("<paths/> section has no <sidebox-config/> element");
throw new ConfigException("no <sidebox-config/> found in <paths/> section",paths_sect);
} // end if
if (!(sidebox_config.startsWith("/"))) if (!(sidebox_config.startsWith("/")))
sidebox_config = root_file_path + sidebox_config; sidebox_config = root_file_path + sidebox_config;
Document sb_doc = loadConfiguration(sidebox_config);
Element sb_root = sb_doc.getDocumentElement();
if (!(sb_root.getTagName().equals("sidebox-config")))
{ // the sidebox configuration file isn't the right type
logger.fatal("config document is not a <sidebox-config/> document (root tag: <"
+ sb_root.getTagName() + "/>)");
throw new ConfigException("document is not a <sidebox-config/> document",sb_root);
} // end if // Get the name of the "photo not available" image.
sect1 = sect_h.getSubElement("photo-not-avail");
NodeList sb_nodes = sb_root.getChildNodes(); if (sect1!=null)
HashMap tmp_factories = new HashMap(); { // load the element text and fixup information
for (i=0; i<sb_nodes.getLength(); i++) sect1_h = new DOMElementHelper(sect1);
{ // extract each sidebox section from the list and build a new master sidebox object photo_not_avail = sect1_h.getElementText();
Node s = sb_nodes.item(i); photo_not_avail_fixup = sect1_h.hasAttribute("fixup");
if ((s.getNodeType()==Node.ELEMENT_NODE) && (s.getNodeName().equals("sidebox")))
{ // get the various attributes of the sidebox
Element sb = (Element)s;
try
{ // get the ID of the sidebox first
tmp = sb.getAttribute("id");
if (StringUtil.isStringEmpty(tmp))
{ // there was no ID specified for the sidebox
logger.fatal("<sidebox/> specified with no ID!");
throw new ConfigException("no ID specified in <sidebox/>",sb);
} // end if
// convert to an integer which we'll be using later in the HashMap
Integer id = new Integer(tmp);
// get the name of the factory class
DOMElementHelper sb_h = new DOMElementHelper(sb);
tmp = sb_h.getSubElementText("factory-class");
if (StringUtil.isStringEmpty(tmp))
{ // the factory class was not specified!
logger.fatal("<sidebox/> config incomplete (missing <factory-class/>)!");
throw new ConfigException("configuration of <sidebox/> is not complete!",sb);
} // end if
Class factory_class = Class.forName(tmp);
SideBoxFactory factory = (SideBoxFactory)(factory_class.newInstance());
factory.setConfiguration(sb);
tmp_factories.put(id,factory);
} // end if
catch (NumberFormatException e1)
{ // ID value was not an integer
logger.fatal("<sidebox/> ID not numeric!");
throw new ConfigException("non-numeric ID specified in <sidebox/>",sb);
} // end catch
catch (ClassNotFoundException e2)
{ // sidebox could not be configured
logger.fatal("<sidebox/> config <factory-class/> not valid!",e2);
throw new ConfigException("<factory-class/> in <sidebox/> is not a valid class!",sb);
} // end catch
catch (IllegalAccessException e3)
{ // could not access class and/or constructor
logger.fatal("<sidebox/> <factory-class/> is not accessible!",e3);
throw new ConfigException("<factory-class/> in <sidebox/> is not accessible!",sb);
} // end catch
catch (InstantiationException e4)
{ // unable to create the class
logger.fatal("<sidebox/> <factory-class/> could not be instantiated!",e4);
throw new ConfigException("<factory-class/> in <sidebox/> could not be created!",sb);
} // end catch
catch (ClassCastException e5)
{ // the class is not a SideBoxFactory implementor - cannot create
logger.fatal("<sidebox/> <factory-class/> is not a SideBoxFactory!",e5);
throw new ConfigException("<factory-class/> in <sidebox/> is not the correct type!",sb);
} // end catch
} // end if
} // end for
sidebox_factories = Collections.unmodifiableMap(tmp_factories);
Element pna = paths_sect_h.getSubElement("photo-not-avail");
if (pna!=null)
{ // copy element text and fixup information
DOMElementHelper pna_h = new DOMElementHelper(pna);
photo_not_avail = pna_h.getElementText();
photo_not_avail_fixup = pna_h.hasAttribute("fixup");
} // end if } // end if
else else
@ -380,84 +218,97 @@ public class RenderConfig implements ColorSelectors
} // end else } // end else
Element msg_sect = root_h.getSubElement("messages"); // Get the name of the services configuration file.
if (msg_sect==null) String services_config = loader.configGetSubElementText(sect_h,"services-config");
{ // no <messages/> section - bail out now! if (!(services_config.startsWith("/")))
logger.fatal("config document has no <messages/> section"); services_config = root_file_path + services_config;
throw new ConfigException("no <messages/> section found in config file",root);
} // end if // Load the <messages/> section.
sect = loader.configGetSubSection(root_h,"messages");
// Initialize the stock messages list. // Initialize the stock messages list.
stock_messages = new HashMap(); stock_messages = new StockMessages(sect);
NodeList msg_nodes = msg_sect.getChildNodes();
for (i=0; i<msg_nodes.getLength(); i++)
{ // examine all subnodes to add them to the message text
Node msgn = msg_nodes.item(i);
if (msgn.getNodeType()==Node.ELEMENT_NODE)
{ // add it to the hash table by its tag name
Element msgel = (Element)msgn;
DOMElementHelper h = new DOMElementHelper(msgel);
String txt = h.getElementText();
if (txt!=null)
stock_messages.put(msgel.getTagName(),txt.trim());
} // end if // Load the <menu-definitions/> section.
sect = loader.configGetSubSection(root_h,"menu-definitions");
} // end for
if (logger.isDebugEnabled())
logger.debug(stock_messages.size() + " stock messages loaded from config");
Element menu_sect = root_h.getSubElement("menu-definitions");
if (menu_sect==null)
{ // no <menu-definitions/> section - bail out now!
logger.fatal("config document has no <menu-definitions/> section");
throw new ConfigException("no <menu-definitions/> section found in config file",root);
} // end if
// Initialize the menus list. // Initialize the menus list.
menus = new HashMap(); HashMap tmp_menus = new HashMap();
NodeList menu_nodes = menu_sect.getChildNodes(); nl = sect.getChildNodes();
for (i=0; i<menu_nodes.getLength(); i++) for (i=0; i<nl.getLength(); i++)
{ // look for <menudef> subnodes and use them to initialize menus { // look for <menudef> subnodes and use them to initialize menus
Node mn = menu_nodes.item(i); Node n = nl.item(i);
if (mn.getNodeType()==Node.ELEMENT_NODE) if (n.getNodeType()==Node.ELEMENT_NODE)
{ // found an element - now check it's name { // verify that it's a menu definition, then get its ID and build a menu
if (mn.getNodeName().equals("menudef")) loader.configVerifyNodeName(n,"menudef",sect);
{ // root of a menu definition - get its ID, build it, and save it String menuid = loader.configGetAttribute((Element)n,"id");
Element mel = (Element)mn;
String menuid = mel.getAttribute("id");
if (menuid==null)
{ // no menu ID attribute
logger.fatal("<menudef/> seen with no \"id\" attribute");
throw new ConfigException("<menudef/> seen with no \"id\" attribute",mel);
} // end if // create the menu and add it to the mapping
LeftMenu menu = new LeftMenu((Element)n,menuid);
// create the menu and add it to the mapping tmp_menus.put(menuid,menu);
LeftMenu menu = new LeftMenu(mel,menuid); if (logger.isDebugEnabled())
menus.put(menuid,menu); logger.debug("menu \"" + menuid + "\" defined");
if (logger.isDebugEnabled())
logger.debug("menu \"" + menuid + "\" defined");
} // end if (found the root of a menu definition)
else
{ // unknown element - bail out!
logger.fatal("config document has unknown node <" + mn.getNodeName() +
"/> inside <menu-definitions/>");
throw new ConfigException("unknown node name <" + mn.getNodeName() + "/> in <menu-definitions/>",
menu_sect);
} // end else
} // end if } // end if
// else just ignore it
} // end for
// save off the menus as an unmodifiable map
if (tmp_menus.isEmpty())
menus = Collections.EMPTY_MAP;
else
menus = Collections.unmodifiableMap(tmp_menus);
if (logger.isDebugEnabled())
logger.debug(menus.size() + " menu definitions loaded from config");
// done with the render-config.xml file
// Load up the sidebox-config.xml file.
doc = loader.loadConfigDocument(sidebox_config);
root = loader.configGetRootElement(doc,"sidebox-config");
// Examine the child nodes for sidebox configuration data.
nl = root.getChildNodes();
HashMap tmp_factories = new HashMap();
for (i=0; i<nl.getLength(); i++)
{ // extract each sidebox section from the list and build a new master sidebox object
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("sidebox")))
{ // get the ID for this sidebox
try
{ // get the ID and convert it to integer
tmp = loader.configGetAttribute((Element)n,"id");
itmp = new Integer(tmp);
} // end try
catch (NumberFormatException nfe)
{ // sidebox ID was not an integer!
logger.fatal("<sidebox/> ID not numeric!");
throw new ConfigException("non-numeric ID specified in <sidebox/>",(Element)n);
} // end catch
SideBoxFactory factory = createSideBoxFactory((Element)n);
tmp_factories.put(itmp,factory);
} // end if
// else ignore this node
} // end for } // end for
if (logger.isDebugEnabled()) if (tmp_factories.isEmpty())
logger.debug(menus.size() + " menu definitions loaded from config"); sidebox_factories = Collections.EMPTY_MAP;
else
sidebox_factories = Collections.unmodifiableMap(tmp_factories);
// done with the sidebox-config.xml file
// Load up the services-config.xml file.
doc = loader.loadConfigDocument(services_config);
root = loader.configGetRootElement(doc,"services-config");
root_h = new DOMElementHelper(root);
// Get the community section and pass it to the CommunityLeftMenuFactory.
comm_menu_fact = new CommunityLeftMenuFactory(root_h.getSubElement("community"));
} // end constructor } // end constructor
@ -466,62 +317,44 @@ public class RenderConfig implements ColorSelectors
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private static Document loadConfiguration(String configname) throws ConfigException private static SideBoxFactory createSideBoxFactory(Element cfg) throws ConfigException
{ {
try XMLLoader loader = XMLLoader.get();
{ // create a simple DOM parser by using the Java XML parsing API String cname = loader.configGetSubElementText(cfg,"factory-class");
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(false);
fac.setValidating(false);
DocumentBuilder parser = fac.newDocumentBuilder();
// access the config file and parse it into our config data tree try
File configfile = new File(configname); { // load the factory class and create an instance of the factory
Document rc = parser.parse(configfile); SideBoxFactory factory = (SideBoxFactory)(Class.forName(cname).newInstance());
if (logger.isDebugEnabled()) factory.setConfiguration(cfg);
logger.debug("configuration loaded successfully"); return factory;
return rc;
} // end try } // end try
catch (FactoryConfigurationError e1) catch (ClassNotFoundException cnfe)
{ // if the document builder factory could not be created { // sidebox could not be configured
logger.fatal("Parser factory configuration error: " + e1.getMessage(),e1); logger.fatal("<sidebox/> config <factory-class/> not valid!",cnfe);
throw new ConfigException("XML parser factory could not be created - " + e1.getMessage()); throw new ConfigException("<factory-class/> in <sidebox/> is not a valid class!",cfg);
} // end catch } // end catch
catch (ParserConfigurationException e2) catch (IllegalAccessException iae)
{ // if the XML parser itself could not be created { // could not access class and/or constructor
logger.fatal("Parser configuration error: " + e2.getMessage(),e2); logger.fatal("<sidebox/> <factory-class/> is not accessible!",iae);
throw new ConfigException("XML parser could not be created - " + e2.getMessage(),e2); throw new ConfigException("<factory-class/> in <sidebox/> is not accessible!",cfg);
} // end catch } // end catch
catch (SAXException e3) catch (InstantiationException ie)
{ // if the XML parser choked on our document { // unable to create the class
if (e3 instanceof SAXParseException) logger.fatal("<sidebox/> <factory-class/> could not be instantiated!",ie);
{ // we have a detailed message - make a proper exception throw new ConfigException("<factory-class/> in <sidebox/> could not be created!",cfg);
SAXParseException e3a = (SAXParseException)e3;
logger.fatal("Config file error [" + configname + ":" + e3a.getLineNumber() + ","
+ e3a.getColumnNumber() + "]: " + e3a.getMessage(),e3a);
throw new ConfigException("Configuration file error: " + e3a.getMessage() + " at line "
+ e3a.getLineNumber() + ", column " + e3a.getColumnNumber(),e3a);
} // end if
else
{ // generic exception - just send up a simple error message
logger.fatal("Config file error [" + configname + "]: " + e3.getMessage(),e3);
throw new ConfigException("Configuration file error - " + e3.getMessage(),e3);
} // end else
} // end catch } // end catch
catch (IOException e4) catch (ClassCastException cce)
{ // error reading the config file itself off the disk { // the class is not a SideBoxFactory implementor - cannot create
logger.fatal("IO error reading config: " + e4.getMessage(),e4); logger.fatal("<sidebox/> <factory-class/> is not a SideBoxFactory!",cce);
throw new ConfigException("unable to read config file \"" + configname + "\" - " + e4.getMessage(),e4); throw new ConfigException("<factory-class/> in <sidebox/> is not the correct type!",cfg);
} // end catch } // end catch
} // end loadConfiguration } // end createSideBoxFactory
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External operations usable only by RenderData * External operations usable only by RenderData
@ -740,6 +573,12 @@ public class RenderConfig implements ColorSelectors
} // end getPhotoNotAvailFixup } // end getPhotoNotAvailFixup
public CommunityLeftMenu createCommunityMenu(CommunityContext comm)
{
return comm_menu_fact.createMenu(comm);
} // end createCommunityMenu
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Static operations for use by VeniceServlet * Static operations for use by VeniceServlet
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -15,16 +15,17 @@
* *
* Contributor(s): * Contributor(s):
*/ */
package com.silverwrist.venice.servlets.format; package com.silverwrist.venice.servlets.format.menus;
import java.io.Writer; import java.io.Writer;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import com.silverwrist.util.StringUtil; import com.silverwrist.util.*;
import com.silverwrist.venice.core.*; import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.servlets.format.*;
public class MenuCommunity implements ComponentRender, ColorSelectors public class CommunityLeftMenu implements ComponentRender, ColorSelectors
{ {
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Attributes * Attributes
@ -43,7 +44,7 @@ public class MenuCommunity implements ComponentRender, ColorSelectors
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public MenuCommunity(CommunityContext ctxt) CommunityLeftMenu(CommunityContext ctxt, List items)
{ {
try try
{ // retrieve the contact info for this puppy { // retrieve the contact info for this puppy
@ -64,7 +65,7 @@ public class MenuCommunity implements ComponentRender, ColorSelectors
} // end catch } // end catch
title = ctxt.getName(); title = ctxt.getName();
items_list = ctxt.getCommunityFeaturesList(); items_list = items;
cid = ctxt.getCommunityID(); cid = ctxt.getCommunityID();
show_unjoin = ctxt.canUnjoin(); show_unjoin = ctxt.canUnjoin();
@ -92,24 +93,21 @@ public class MenuCommunity implements ComponentRender, ColorSelectors
} // end if } // end if
// display the title // display the title
out.write("<B>" + StringUtil.encodeHTML(title) + "</B>"); out.write("<B>" + StringUtil.encodeHTML(title) + "</B><BR>");
// display the menu items // display the menu items
Iterator it = items_list.iterator(); Iterator it = items_list.iterator();
String cparm = "sig=" + cid;
while (it.hasNext()) while (it.hasNext())
{ // display each menu item in turn { // display each menu item in turn
CommunityFeature ftr = (CommunityFeature)(it.next()); ComponentRender cr = (ComponentRender)(it.next());
out.write("<BR>\n<A CLASS=\"lbar\" HREF=\"" cr.renderHere(out,rdat);
+ rdat.getEncodedServletPath(ftr.getApplet() + "?" + cparm) + "\">" + hilite
+ StringUtil.encodeHTML(ftr.getName()) + "</FONT></A>\n");
} // end while } // end while
if (show_unjoin) if (show_unjoin)
out.write("<P>\n<A CLASS=\"lbar\" HREF=\"" out.write("<BR>\n<A CLASS=\"lbar\" HREF=\""
+ rdat.getEncodedServletPath("sigops?cmd=U&" + cparm) + "\">" + rdat.getEncodedServletPath("sigops?cmd=U&sig=" + cid) + "\">" + hilite
+ hilite + "Unjoin</FONT></A>\n"); + "Unjoin</FONT></A>\n");
out.write("\n"); // all done... out.write("\n"); // all done...
@ -126,4 +124,4 @@ public class MenuCommunity implements ComponentRender, ColorSelectors
} // end getID } // end getID
} // end class MenuCommunity } // end class CommunityLeftMenu

View File

@ -0,0 +1,117 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format.menus;
import java.util.Map;
import org.w3c.dom.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.util.XMLLoader;
class CommunityLeftMenuEntry implements Comparable
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String symbol;
private int index;
private int sequence;
private LinkItem item;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
CommunityLeftMenuEntry(Element svc) throws ConfigException
{
XMLLoader loader = XMLLoader.get();
symbol = loader.configGetAttribute(svc,"id");
index = loader.configGetAttributeInt(svc,"index");
Element link_elt = loader.configGetSubSection(svc,"link");
sequence = loader.configGetAttributeInt(link_elt,"sequence");
item = new LinkItem(link_elt);
} // end constructor
/*--------------------------------------------------------------------------------
* Overrides from class Object
*--------------------------------------------------------------------------------
*/
public boolean equals(Object o)
{
if ((o==null) || !(o instanceof CommunityLeftMenuEntry))
return false;
CommunityLeftMenuEntry other = (CommunityLeftMenuEntry)o;
return (sequence==other.sequence);
} // end equals
public int hashCode()
{
return sequence;
} // end hashCode
/*--------------------------------------------------------------------------------
* Implementations from interface Comparable
*--------------------------------------------------------------------------------
*/
public int compareTo(Object o)
{
if (o==null)
throw new NullPointerException("compareTo null object!");
CommunityLeftMenuEntry other = (CommunityLeftMenuEntry)o; // may throw ClassCastException
return sequence - other.sequence;
} // end compareTo
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
final String getSymbol()
{
return symbol;
} // end getSymbol
final int getIndex()
{
return index;
} // end getIndex
final int getSequence()
{
return sequence;
} // end getSequence
final LinkItem resolveItem(Map vars)
{
return new LinkItem(item,vars);
} // end resolveItem
} // end class CommunityLeftMenuEntry

View File

@ -0,0 +1,130 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format.menus;
import java.util.*;
import org.w3c.dom.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
public class CommunityLeftMenuFactory
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private List entries;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public CommunityLeftMenuFactory(Element comm_sect) throws ConfigException
{
if (comm_sect!=null)
{ // look for community services
NodeList nl = comm_sect.getChildNodes();
ArrayList tmp_entries = new ArrayList(nl.getLength());
for (int i=0; i<nl.getLength(); i++)
{ // get each node and see if it's a service node
Node n = nl.item(i);
if ((n.getNodeType()==Node.ELEMENT_NODE) && (n.getNodeName().equals("service")))
{ // create a template LeftMenuEntry and add it
CommunityLeftMenuEntry ent = new CommunityLeftMenuEntry((Element)n);
tmp_entries.add(ent);
} // end if
} // end for
if (tmp_entries.isEmpty())
entries = Collections.EMPTY_LIST;
else
{ // sort the list by sequence before we save it
if (tmp_entries.size()>1)
Collections.sort(tmp_entries);
tmp_entries.trimToSize();
entries = Collections.unmodifiableList(tmp_entries);
} // end else
} // end if
else // no communty services - initialize to null
entries = Collections.EMPTY_LIST;
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public CommunityLeftMenu createMenu(CommunityContext comm)
{
// N.B. This implementation will change once the engine uses the SCM to return the defined
// community services.
List items;
if (entries.size()>0)
{ // Get the community features list and stash the indexes in a set.
HashSet defined = new HashSet();
List ftr_list = comm.getCommunityFeaturesList();
Iterator it = ftr_list.iterator();
while (it.hasNext())
{ // add each index to the set
CommunityFeature ftr = (CommunityFeature)(it.next());
defined.add(new Integer(ftr.getFeatureCode()));
} // end while
// Create the map used to replace the variables in the menu items.
HashMap vars = new HashMap();
vars.put("cid",String.valueOf(comm.getCommunityID()));
// Run through the list of entries (sorted by sequence) and add them.
ArrayList tmp_items = new ArrayList(defined.size());
it = entries.iterator();
while (it.hasNext())
{ // get this entry and see if there's a match in the set
CommunityLeftMenuEntry ntry = (CommunityLeftMenuEntry)(it.next());
if (defined.contains(new Integer(ntry.getIndex())))
tmp_items.add(ntry.resolveItem(vars));
} // end while
if (tmp_items.isEmpty()) // dummy out the list
items = Collections.EMPTY_LIST;
else
{ // make the list unmodifiable
tmp_items.trimToSize();
items = Collections.unmodifiableList(tmp_items);
} // end else
} // end if
else // no defined services - short-circuit the whole business
items = Collections.EMPTY_LIST;
// the constructor will handle the rest of the initialization
return new CommunityLeftMenu(comm,items);
} // end createMenu
} // end class CommunityLeftMenuFactory

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.servlets.format.menus;
import java.io.Writer; import java.io.Writer;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import org.apache.log4j.*; import org.apache.log4j.*;
import org.w3c.dom.*; import org.w3c.dom.*;
import com.silverwrist.util.*; import com.silverwrist.util.*;
@ -53,7 +54,7 @@ class LinkItem implements ComponentRender, ColorSelectors
private ComponentRender contents; private ComponentRender contents;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructors
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
@ -103,6 +104,16 @@ class LinkItem implements ComponentRender, ColorSelectors
} // end constructor } // end constructor
LinkItem(LinkItem other, Map vars)
{
this.href = StringUtil.replaceAllVariables(other.href,vars);
this.type = other.type;
this.enabled = other.enabled;
this.target = other.target;
this.contents = other.contents;
} // end constructor
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface ComponentRender * Implementations from interface ComponentRender
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -0,0 +1,35 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.svc;
import org.w3c.dom.Element;
import com.silverwrist.venice.except.ConfigException;
import com.silverwrist.venice.security.SecurityMonitor;
public interface CommService
{
public abstract void initialize(Element root, SecurityMonitor sm, CommServiceSite site)
throws ConfigException;
public abstract void shutdown();
public abstract String getSymbol();
public abstract int getIndex();
} // end interface CommService

View File

@ -0,0 +1,22 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.svc;
public interface CommServiceSite
{
} // end interface CommServiceSite

View File

@ -0,0 +1,235 @@
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.util;
import java.io.*;
import javax.xml.parsers.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.except.*;
public class XMLLoader
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(XMLLoader.class);
private static XMLLoader self = null;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
private XMLLoader()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final Document loadConfigDocument(String filename) throws ConfigException
{
if (logger.isDebugEnabled())
logger.debug("loadConfigDocument(\"" + filename + "\")...");
try
{ // create a simple DOM parser by using the Java XML parsing API
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(false);
fac.setValidating(false);
DocumentBuilder parser = fac.newDocumentBuilder();
// access the config file and parse it into our config data tree
Document rc = parser.parse(new File(filename));
if (logger.isDebugEnabled())
logger.debug("config file \"" + filename + "\" loaded successfully");
return rc;
} // end try
catch (FactoryConfigurationError fce)
{ // if the document builder factory could not be created
logger.fatal("Parser factory configuration error: " + fce.getMessage(),fce);
throw new ConfigException("XML parser factory could not be created - " + fce.getMessage());
} // end catch
catch (ParserConfigurationException pce)
{ // if the XML parser itself could not be created
logger.fatal("Parser configuration error: " + pce.getMessage(),pce);
throw new ConfigException("XML parser could not be created - " + pce.getMessage(),pce);
} // end catch
catch (SAXException se)
{ // if the XML parser choked on our document
if (se instanceof SAXParseException)
{ // we have a detailed message - make a proper exception
SAXParseException spe = (SAXParseException)se;
logger.fatal("Config file error [" + filename + ":" + spe.getLineNumber() + ","
+ spe.getColumnNumber() + "]: " + spe.getMessage(),spe);
throw new ConfigException("Configuration file error: " + spe.getMessage() + " at line "
+ spe.getLineNumber() + ", column " + spe.getColumnNumber(),spe);
} // end if
else
{ // generic exception - just send up a simple error message
logger.fatal("Config file error [" + filename + "]: " + se.getMessage(),se);
throw new ConfigException("Configuration file error - " + se.getMessage(),se);
} // end else
} // end catch
catch (IOException ioe)
{ // error reading the config file itself off the disk
logger.fatal("IO error reading config: " + ioe.getMessage(),ioe);
throw new ConfigException("unable to read config file \"" + filename + "\" - " + ioe.getMessage(),ioe);
} // end catch
} // end loadConfigDocument
public final Element configGetRootElement(Document doc, String expected_name) throws ConfigException
{
Element rc = doc.getDocumentElement();
if (rc.getTagName().equals(expected_name))
return rc; // we're OK
logger.fatal("config document is not a <" + expected_name + "/> document (actual root tag: <"
+ rc.getTagName() + "/>)");
throw new ConfigException("document is not a <" + expected_name + "/> document",rc);
} // end configGetRootElement
public final String configGetText(DOMElementHelper h) throws ConfigException
{
String rc = h.getElementText();
if (rc!=null)
return rc; // we're OK
logger.fatal("<" + h.getElement().getTagName() + "/> has no value");
throw new ConfigException("no data value found in <" + h.getElement().getTagName() + "/>",h.getElement());
} // end configGetSubElementText
public final String configGetText(Element elt) throws ConfigException
{
return configGetText(new DOMElementHelper(elt));
} // end configGetText
public final String configGetSubElementText(DOMElementHelper h, String elt_name) throws ConfigException
{
String rc = h.getSubElementText(elt_name);
if (rc!=null)
return rc; // we're OK
logger.fatal("<" + h.getElement().getTagName() + "/> has no <" + elt_name + "/> element");
throw new ConfigException("no <" + elt_name + "/> element found in <" + h.getElement().getTagName() + "/>",
h.getElement());
} // end configGetSubElementText
public final String configGetSubElementText(Element elt, String subelt_name) throws ConfigException
{
return configGetSubElementText(new DOMElementHelper(elt),subelt_name);
} // end configGetSubElementText
public final Element configGetSubSection(DOMElementHelper h, String sect_name) throws ConfigException
{
Element rc = h.getSubElement(sect_name);
if (rc!=null)
return rc; // we're OK
logger.fatal("<" + h.getElement().getTagName() + "/> has no <" + sect_name + "/> section");
throw new ConfigException("no <" + sect_name + "/> section found in <" + h.getElement().getTagName()
+ "/>",h.getElement());
} // end configGetSubElementText
public final Element configGetSubSection(Element sect, String subsect_name) throws ConfigException
{
return configGetSubSection(new DOMElementHelper(sect),subsect_name);
} // end configGetSubSection
public final void configVerifyNodeName(Node n, String name, Element enclosing_sect) throws ConfigException
{
if (n.getNodeName().equals(name))
return;
logger.fatal("unknown node <" + n.getNodeName() + "/> seen inside <" + enclosing_sect.getTagName() + "/>");
throw new ConfigException("unknown node name <" + n.getNodeName() + "/> in <"
+ enclosing_sect.getTagName() + "/>",enclosing_sect);
} // end configVerifyNodeName
public final String configGetAttribute(Element elt, String attr_name) throws ConfigException
{
String rc = elt.getAttribute(attr_name);
if (!(StringUtil.isStringEmpty(rc)))
return rc;
logger.fatal("no " + attr_name + "= attribute found in <" + elt.getTagName() + "/> element");
throw new ConfigException("no " + attr_name + "= attribute found in <" + elt.getTagName()
+ "/> element",elt);
} // end configGetAttribute
public final int configGetAttributeInt(Element elt, String attr_name) throws ConfigException
{
String tmp = elt.getAttribute(attr_name);
if (StringUtil.isStringEmpty(tmp))
{ // the attribute is not present
logger.fatal("no " + attr_name + "= attribute found in <" + elt.getTagName() + "/> element");
throw new ConfigException("no " + attr_name + "= attribute found in <" + elt.getTagName()
+ "/> element",elt);
} // end if
try
{ // parse out the integer value
return Integer.parseInt(tmp.trim());
} // end try
catch (NumberFormatException nfe)
{ // but it's not a valid integer - throw something else!
logger.fatal(attr_name + "= attribute in <" + elt.getTagName() + "/> element is not a valid integer");
throw new ConfigException(attr_name + "= attribute in <" + elt.getTagName()
+ "/> element is not a valid integer",elt);
} // end catch
} // end configGetAttributeInt
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static final synchronized XMLLoader get()
{
if (self==null)
self = new XMLLoader();
return self;
} // end get
} // end class XMLLoader