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. -->
<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>
<!-- 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. -->
<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>
<!-- 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
words provided by Erbo. -->
<dictionary>
<file>/home/erbo/venice/WEB-INF/en-us.dict</file>
<file>/home/erbo/venice/WEB-INF/erbo.dict</file>
<file>WEB-INF/en-us.dict</file>
<file>WEB-INF/erbo.dict</file>
</dictionary>
<!-- Settings for dealing with uploads -->

View File

@ -27,7 +27,7 @@ import org.w3c.dom.*;
* @version X
* @see org.w3c.dom.Element
*/
public class DOMElementHelper
public final class DOMElementHelper
{
/*--------------------------------------------------------------------------------
* Attributes
@ -65,7 +65,7 @@ public class DOMElementHelper
* @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>
*/
private static String getTextOfElement(Element e)
private static final String getTextOfElement(Element e)
{
NodeList kids = e.getChildNodes();
if (kids==null)
@ -94,6 +94,30 @@ public class DOMElementHelper
} // 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
*--------------------------------------------------------------------------------
@ -104,7 +128,7 @@ public class DOMElementHelper
*
* @return See above.
*/
public Element getElement()
public final Element getElement()
{
return elt;
@ -118,7 +142,7 @@ public class DOMElementHelper
* If the <CODE>Element</CODE> has no child <CODE>Elements</CODE> with the given name,
* the method returns <CODE>null</CODE>.
*/
public Element getSubElement(String name)
public final Element getSubElement(String name)
{
NodeList kids = elt.getChildNodes();
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>
* has not text nodes underneath it, returns <CODE>null.</CODE>
*/
public String getElementText()
public final String getElementText()
{
return getTextOfElement(elt);
} // 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
* <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
* 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);
if (se==null)
return null;
else
return getTextOfElement(se);
return ((se==null) ? null : getTextOfElement(se));
} // 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.
*
@ -174,10 +225,9 @@ public class DOMElementHelper
* @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has a sub-element with the
* specified name, <CODE>false</CODE> if not.
*/
public boolean hasChildElement(String name)
public final boolean hasChildElement(String name)
{
Element tmp = getSubElement(name);
return (tmp==null) ? false : true;
return (getSubElement(name)!=null);
} // end hasChildElement
@ -188,7 +238,7 @@ public class DOMElementHelper
* @return <CODE>true</CODE> if the wrapped <CODE>Element</CODE> has an attribute with the
* specified name, <CODE>false</CODE> if not.
*/
public boolean hasAttribute(String name)
public final boolean hasAttribute(String 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
* 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);
if (StringUtil.isStringEmpty(tmp))
return null;
try
{ // convert to an Integer
return new Integer(tmp);
return new Integer(tmp.trim());
} // end try
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;
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.venice.except.*;
import com.silverwrist.venice.util.XMLLoader;
public class Startup
{
@ -45,126 +42,28 @@ public class Startup
} // 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)
throws ConfigException, DataException
{
XMLLoader loader = XMLLoader.get();
// load the configuration data
Document config = loadConfiguration(configname);
Document config = loader.loadConfigDocument(configname);
// 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())
logger.debug("Venice engine classname: " + cname);
try
{ // attempt to load the engine class
Class engine_class = Class.forName(cname);
// now create a new Venice engine (cast to the external interface)
VeniceEngine engine = (VeniceEngine)(engine_class.newInstance());
{ // create a new Venice engine (cast to the external interface)
VeniceEngine engine = (VeniceEngine)(Class.forName(cname).newInstance());
if (logger.isDebugEnabled())
logger.debug("VeniceEngine created successfully");
@ -176,39 +75,39 @@ public class Startup
return engine;
} // end try
catch (ClassNotFoundException e1)
catch (ClassNotFoundException cnfe)
{ // 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);
} // end catch
catch (IllegalAccessException e2)
catch (IllegalAccessException iae)
{ // 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);
} // end catch
catch (InstantiationException e3)
catch (InstantiationException ie)
{ // 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);
} // end catch
catch (ExceptionInInitializerError e4)
catch (ExceptionInInitializerError eiie)
{ // 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);
} // end catch
catch (SecurityException e5)
catch (SecurityException se)
{ // 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);
} // end catch
catch (ClassCastException e6)
catch (ClassCastException cce)
{ // 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);
} // 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 shutdown() throws ConfigException;
public abstract int getNumFeatures();
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.filters.*;
import com.silverwrist.venice.security.*;
import com.silverwrist.venice.util.XMLLoader;
public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{
@ -143,37 +144,13 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
MasterSideBox(Element section) throws ConfigException
{
try
{ // get the ID value for this sidebox
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
XMLLoader loader = XMLLoader.get();
id = loader.configGetAttributeInt(section,"id");
// get the title and classname
DOMElementHelper section_h = new DOMElementHelper(section);
title = section_h.getSubElementText("title");
anon_title = section_h.getSubElementText("anon-title");
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
title = loader.configGetSubElementText(section_h,"title");
classname = loader.configGetSubElementText(section_h,"factory-class");
try
{ // 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
// get the anonymous title and default it if it's not found
anon_title = section_h.getSubElementText("anon-title");
if (StringUtil.isStringEmpty(anon_title))
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
/*--------------------------------------------------------------------------------
* 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.
*--------------------------------------------------------------------------------
@ -390,12 +340,11 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
*--------------------------------------------------------------------------------
*/
private Document config = null; // configuration data
private EnvEngine env = null; // my environment
private Random rng; // random number generator
private Properties email_props = null; // email properties
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 VeniceFeatureDef[] features; // master feature table
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 community_security; // the community security monitor
private SecurityMonitor conference_security; // conference security monitor (will move eventually)
private ServiceControlManager scmgr; // service control manager
/*--------------------------------------------------------------------------------
* 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()
{
if (config==null)
if (env==null)
throw new InternalStateError("Venice engine not initialized!");
} // end checkInitialized
@ -643,89 +618,41 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{
int i; // loop counter
if (this.config!=null)
if (env!=null)
{ // already configured!
logger.error("Venice engine already initialized");
throw new ConfigException("Venice engine already initialized");
} // end if
this.config = config;
DataPool datapool = null;
ArrayList dictionary_tmp;
Collection dictionary_tmp;
try
{ // first, verify that this is a valid configuration
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
XMLLoader loader = XMLLoader.get();
Element root = loader.configGetRootElement(config,"venice-config");
DOMElementHelper root_h = new DOMElementHelper(root);
// Get the <engine/> section.
Element engine_sect = root_h.getSubElement("engine");
if (engine_sect==null)
{ // 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);
Element sect = loader.configGetSubSection(root_h,"engine");
DOMElementHelper sect_h = new DOMElementHelper(sect);
// Get the name of the sidebox config file.
String sidebox_config = engine_h.getSubElementText("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
String sidebox_config = loader.configGetSubElementText(sect_h,"sidebox-config");
if (!(sidebox_config.startsWith("/")))
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
NodeList sb_nodes = sb_root.getChildNodes();
ArrayList sidebox_tmp = new ArrayList();
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 name of the services config file.
String services_config = loader.configGetSubElementText(sect_h,"services-config");
if (!(services_config.startsWith("/")))
services_config = app_root + services_config;
// Get the <database/> section.
Element db_sect = root_h.getSubElement("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
sect = loader.configGetSubSection(root_h,"database");
try
{ // allocate the data pool object
datapool = new DataPool(db_sect);
datapool = new DataPool(sect);
} // end try
catch (SQLException e)
@ -735,20 +662,16 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end catch
Element security_sect = root_h.getSubElement("security");
if (security_sect==null)
{ // no "security" section...bad!
logger.fatal("config document has no <security/> section");
throw new ConfigException("no <security/> section found in config file",root);
// Get the <security/> section.
sect = loader.configGetSubSection(root_h,"security");
} // end if
NodeList sec_nodes = security_sect.getChildNodes();
for (i=0; i<sec_nodes.getLength(); i++)
// Load the security monitors.
NodeList nl = sect.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // 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")))
{ // initial security definition
{ // load one of the initial security definitions
SecurityMonitor sm = new StaticSecurityMonitor((Element)n);
if (sm.getID().equals("Global"))
global_security = sm;
@ -761,120 +684,85 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end for
Element email_sect = root_h.getSubElement("email");
if (email_sect==null)
{ // unable to find the database section
logger.fatal("config document has no <email/> section");
throw new ConfigException("no <email/> section found in config file",root);
} // end if
// Get the <email/> section.
sect = loader.configGetSubSection(root_h,"email");
sect_h = new DOMElementHelper(sect);
// initialize the email properties and get a mail session object
email_props = new Properties();
email_props.put("mail.transport.protocol","smtp");
DOMElementHelper email_sect_h = new DOMElementHelper(email_sect);
email_props.put("mail.smtp.host",email_sect_h.getSubElementText("smtp-host"));
email_props.put("mail.from",email_sect_h.getSubElementText("mail-from-addr"));
email_props.put("com.silverwrist.venice.email.mailer",email_sect_h.getSubElementText("mailer"));
email_props.put("mail.smtp.host",sect_h.getSubElementText("smtp-host"));
email_props.put("mail.from",sect_h.getSubElementText("mail-from-addr"));
email_props.put("com.silverwrist.venice.email.mailer",sect_h.getSubElementText("mailer"));
mailsession = javax.mail.Session.getInstance(email_props,null);
Element dict_sect = root_h.getSubElement("dictionary");
if (dict_sect==null)
{ // 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);
// Get the <dictionary/> section.
sect = loader.configGetSubSection(root_h,"dictionary");
} // 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.
dictionary_tmp = new ArrayList();
NodeList dict_nodes = dict_sect.getChildNodes();
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
// Get the <upload/> section.
sect = loader.configGetSubSection(root_h,"upload");
sect_h = new DOMElementHelper(sect);
// Look for a "no-compress" blacklist.
DOMElementHelper upload_sect_h = new DOMElementHelper(upload_sect);
Element no_compress_sect = upload_sect_h.getSubElement("no-compress");
if (no_compress_sect!=null)
Element subsect = sect_h.getSubElement("no-compress");
if (subsect!=null)
{ // Initialize the no-compress list.
NodeList nc_nodes = no_compress_sect.getChildNodes();
for (i=0; i<nc_nodes.getLength(); i++)
nl = subsect.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // retrieve all entries from the list
Node ncn = nc_nodes.item(i);
if (ncn.getNodeType()==Node.ELEMENT_NODE)
{ // get the element
DOMElementHelper ncel = new DOMElementHelper((Element)ncn);
if (ncel.getElement().getNodeName().equals("type"))
{ // add a new element to the list
no_compress_types.add(ncel.getElementText().trim().toLowerCase());
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // look at the element name now
loader.configVerifyNodeName(n,"type",subsect);
DOMElementHelper h = new DOMElementHelper((Element)n);
no_compress_types.add(h.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
// else skip it
// else skip this node
} // end for
} // end if
// 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.
stock_messages = new Hashtable();
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());
stock_messages = new StockMessages(sect);
} // 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
// store the real master sidebox table as an array
sideboxes = (MasterSideBox[])(sidebox_tmp.toArray(new MasterSideBox[0]));
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
catch (ConfigException ce)
{ // before we leave on a ConfigException, nuke the important data
this.config = null;
if (datapool!=null)
datapool.closeAllConnections();
throw ce;
@ -1014,6 +902,21 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // 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()
{
checkInitialized();
@ -1765,7 +1668,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
public List getMasterSideBoxList()
{
return new MasterSideBoxList(sideboxes);
return Arrays.asList(sideboxes);
} // end getMasterSideBoxList

View File

@ -26,7 +26,7 @@ import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.servlets.format.*;
import com.silverwrist.venice.servlets.format.menus.LeftMenu;
import com.silverwrist.venice.servlets.format.menus.*;
public class Variables
{
@ -206,23 +206,34 @@ public class Variables
} // 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);
boolean do_change;
if ((obj==null) || !(obj instanceof MenuCommunity))
if ((obj==null) || !(obj instanceof CommunityLeftMenu))
do_change = true;
else
{ // look at the actual community IDs underlying the MenuCommunity
MenuCommunity tmp = (MenuCommunity)obj;
CommunityLeftMenu tmp = (CommunityLeftMenu)obj;
do_change = (tmp.getID()!=comm.getCommunityID());
} // end else
if (do_change)
{ // switch to the appropriate MenuCommunity
MenuCommunity mc = new MenuCommunity(comm);
session.setAttribute(MENU_ATTRIBUTE,mc);
{ // switch to the appropriate CommunityLeftMenu
try
{ // 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

View File

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

View File

@ -21,22 +21,17 @@ import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
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.IOUtil;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.CommunityContext;
import com.silverwrist.venice.core.UserContext;
import com.silverwrist.venice.core.VeniceEngine;
import com.silverwrist.venice.except.AccessError;
import com.silverwrist.venice.except.ConfigException;
import com.silverwrist.venice.except.DataException;
import com.silverwrist.venice.except.*;
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.util.XMLLoader;
public class RenderConfig implements ColorSelectors
{
@ -57,7 +52,6 @@ public class RenderConfig implements ColorSelectors
*--------------------------------------------------------------------------------
*/
private Document config;
private String site_title;
private boolean want_comments;
private boolean allow_gzip;
@ -71,13 +65,14 @@ public class RenderConfig implements ColorSelectors
private int site_logo_width = 140;
private int site_logo_height = 80;
private String site_logo_linkURL = null;
private HashMap stock_messages;
private HashMap menus;
private StockMessages stock_messages;
private Map menus;
private String[] colors_array;
private int footer_logo_scale;
private Map sidebox_factories;
private String photo_not_avail;
private boolean photo_not_avail_fixup;
private CommunityLeftMenuFactory comm_menu_fact;
/*--------------------------------------------------------------------------------
* Constructor
@ -86,76 +81,54 @@ public class RenderConfig implements ColorSelectors
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...
Element root = config.getDocumentElement();
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.
// Make sure the document is valid.
Element root = loader.configGetRootElement(doc,"render-config");
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())
logger.debug("Site title: " + site_title);
Element render_sect = root_h.getSubElement("rendering");
if (render_sect==null)
{ // 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);
// Get the <rendering/> section.
Element sect = loader.configGetSubSection(root_h,"rendering");
} // end if
DOMElementHelper render_sect_h = new DOMElementHelper(render_sect);
want_comments = render_sect_h.hasChildElement("html-comments");
allow_gzip = render_sect_h.hasChildElement("gzip-output");
no_smart_tags = !(render_sect_h.hasChildElement("ms-copyright-violations"));
// Load the quick Boolean values indicated by the presence or absence of a tag.
DOMElementHelper sect_h = new DOMElementHelper(sect);
want_comments = sect_h.hasChildElement("html-comments");
allow_gzip = sect_h.hasChildElement("gzip-output");
no_smart_tags = !(sect_h.hasChildElement("ms-copyright-violations"));
if (logger.isDebugEnabled())
{ // log the read values
logger.debug("Use HTML comments: " + String.valueOf(want_comments));
logger.debug("Use GZIP encoding: " + String.valueOf(allow_gzip));
logger.debug("Disable IE Smart Tags: " + String.valueOf(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);
logger.debug("Use HTML comments: " + want_comments);
logger.debug("Use GZIP encoding: " + allow_gzip);
logger.debug("Disable IE Smart Tags: " + no_smart_tags);
} // end if
// Load the default font face.
font_face = loader.configGetSubElementText(sect_h,"font");
if (logger.isDebugEnabled())
logger.debug("Font face: " + font_face);
String stylesheet_loc = render_sect_h.getSubElementText("stylesheet");
if (stylesheet_loc!=null)
// Load the default stylesheet file reference.
String tmp = sect_h.getSubElementText("stylesheet");
if (tmp!=null)
{ // we're using Cascading Stylesheets - load it and test for existence
if (!(stylesheet_loc.startsWith("/")))
stylesheet_loc = root_file_path + stylesheet_loc;
if (!(tmp.startsWith("/"))) // prepend app root
tmp = root_file_path + tmp;
if (logger.isDebugEnabled())
logger.debug("Stylesheet location: " + stylesheet_loc);
logger.debug("Stylesheet location: " + tmp);
// Test to make sure the stylesheet is actually present.
stylesheet = new File(stylesheet_loc);
stylesheet = new File(tmp);
if (!(stylesheet.exists() && stylesheet.canRead()))
{ // it's not there - bail out!
logger.fatal("unable to read stylesheet file: " + stylesheet_loc);
throw new ConfigException("stylesheet " + stylesheet_loc + " cannot be read",render_sect);
logger.fatal("unable to read stylesheet file: " + tmp);
throw new ConfigException("stylesheet " + tmp + " cannot be read",sect);
} // end if
@ -163,27 +136,21 @@ public class RenderConfig implements ColorSelectors
else // no stylesheet
stylesheet = null;
Element colors_sect = render_sect_h.getSubElement("colors");
if (colors_sect==null)
{ // 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
// Get the <colors/> section and load the colors out of it..
Element sect1 = loader.configGetSubSection(sect_h,"colors");
colors_array = new String[colornames_map.size()];
int i;
NodeList colors_nlist = colors_sect.getChildNodes();
for (i=0; i<colors_nlist.getLength(); i++)
NodeList nl = sect1.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // look at all subelements and map their names to color selectors
Node foo = colors_nlist.item(i);
if (foo.getNodeType()==Node.ELEMENT_NODE)
{ // map the element name to a color selector
Integer csel = (Integer)(colornames_map.get(foo.getNodeName()));
if (csel!=null)
{ // load the specified color into the colors array
DOMElementHelper foo_h = new DOMElementHelper((Element)foo);
colors_array[csel.intValue()] = foo_h.getElementText();
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // map the name of the node to a color selector
Integer cs = (Integer)(colornames_map.get(n.getNodeName()));
if (cs!=null)
{ // get the color value and load it into the array
DOMElementHelper h = new DOMElementHelper((Element)n);
colors_array[cs.intValue()] = h.getElementText();
} // end if
@ -191,186 +158,57 @@ public class RenderConfig implements ColorSelectors
} // end for
try
{ // load in the footer logo scale
String tmp = render_sect_h.getSubElementText("footer-logo-scale");
if (tmp==null)
footer_logo_scale = 100;
else
footer_logo_scale = Integer.parseInt(tmp.trim());
// Load in the footer logo scale.
Integer itmp = sect_h.getSubElementInt("footer-logo-scale");
footer_logo_scale = ((itmp==null) ? 100 : itmp.intValue());
} // end try
catch (NumberFormatException nfe)
{ // just default on serious error
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
// Get the <paths/> section.
sect = loader.configGetSubSection(root_h,"paths");
sect_h = new DOMElementHelper(sect);
// Load the image path.
image_url = loader.configGetSubElementText(sect_h,"image");
if (logger.isDebugEnabled())
logger.debug("Image path: " + image_url);
static_url = paths_sect_h.getSubElementText("static");
if (static_url==null)
{ // 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
// Load the static path.
static_url = loader.configGetSubElementText(sect_h,"static");
if (logger.isDebugEnabled())
logger.debug("Static files path: " + static_url);
Element site_logo_elt = paths_sect_h.getSubElement("site-logo");
if (site_logo_elt==null)
{ // no <site-logo/> tag - bail out now!
logger.fatal("<paths/> section has no <site-logo/> element");
throw new ConfigException("no <site-logo/> found in <paths/> section",paths_sect);
// Get the site logo element.
sect1 = loader.configGetSubSection(sect_h,"site-logo");
DOMElementHelper sect1_h = new DOMElementHelper(sect1);
site_logo = loader.configGetText(sect1_h);
} // 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);
site_logo = site_logo_h.getElementText();
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");
// Get the link URL of the logo.
tmp = sect1.getAttribute("href");
if (!(StringUtil.isStringEmpty(tmp)))
site_logo_linkURL = tmp;
if (logger.isDebugEnabled())
logger.debug("Site logo: " + site_logo);
// Load the sidebox configuration information.
String sidebox_config = paths_sect_h.getSubElementText("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
// Get the name of the sidebox configuration file.
String sidebox_config = loader.configGetSubElementText(sect_h,"sidebox-config");
if (!(sidebox_config.startsWith("/")))
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
NodeList sb_nodes = sb_root.getChildNodes();
HashMap tmp_factories = new HashMap();
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")))
{ // 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");
// Get the name of the "photo not available" image.
sect1 = sect_h.getSubElement("photo-not-avail");
if (sect1!=null)
{ // load the element text and fixup information
sect1_h = new DOMElementHelper(sect1);
photo_not_avail = sect1_h.getElementText();
photo_not_avail_fixup = sect1_h.hasAttribute("fixup");
} // end if
else
@ -380,85 +218,98 @@ public class RenderConfig implements ColorSelectors
} // end else
Element msg_sect = root_h.getSubElement("messages");
if (msg_sect==null)
{ // no <messages/> section - bail out now!
logger.fatal("config document has no <messages/> section");
throw new ConfigException("no <messages/> section found in config file",root);
// Get the name of the services configuration file.
String services_config = loader.configGetSubElementText(sect_h,"services-config");
if (!(services_config.startsWith("/")))
services_config = root_file_path + services_config;
} // end if
// Load the <messages/> section.
sect = loader.configGetSubSection(root_h,"messages");
// Initialize the stock messages list.
stock_messages = new HashMap();
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());
stock_messages = new StockMessages(sect);
} // end if
} // 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
// Load the <menu-definitions/> section.
sect = loader.configGetSubSection(root_h,"menu-definitions");
// Initialize the menus list.
menus = new HashMap();
NodeList menu_nodes = menu_sect.getChildNodes();
for (i=0; i<menu_nodes.getLength(); i++)
HashMap tmp_menus = new HashMap();
nl = sect.getChildNodes();
for (i=0; i<nl.getLength(); i++)
{ // look for <menudef> subnodes and use them to initialize menus
Node mn = menu_nodes.item(i);
if (mn.getNodeType()==Node.ELEMENT_NODE)
{ // found an element - now check it's name
if (mn.getNodeName().equals("menudef"))
{ // root of a menu definition - get its ID, build it, and save it
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
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // verify that it's a menu definition, then get its ID and build a menu
loader.configVerifyNodeName(n,"menudef",sect);
String menuid = loader.configGetAttribute((Element)n,"id");
// create the menu and add it to the mapping
LeftMenu menu = new LeftMenu(mel,menuid);
menus.put(menuid,menu);
LeftMenu menu = new LeftMenu((Element)n,menuid);
tmp_menus.put(menuid,menu);
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
// 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
if (tmp_factories.isEmpty())
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
/*--------------------------------------------------------------------------------
@ -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
{ // 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();
XMLLoader loader = XMLLoader.get();
String cname = loader.configGetSubElementText(cfg,"factory-class");
// 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;
try
{ // load the factory class and create an instance of the factory
SideBoxFactory factory = (SideBoxFactory)(Class.forName(cname).newInstance());
factory.setConfiguration(cfg);
return factory;
} // 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());
catch (ClassNotFoundException cnfe)
{ // sidebox could not be configured
logger.fatal("<sidebox/> config <factory-class/> not valid!",cnfe);
throw new ConfigException("<factory-class/> in <sidebox/> is not a valid class!",cfg);
} // 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);
catch (IllegalAccessException iae)
{ // could not access class and/or constructor
logger.fatal("<sidebox/> <factory-class/> is not accessible!",iae);
throw new ConfigException("<factory-class/> in <sidebox/> is not accessible!",cfg);
} // 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
catch (InstantiationException ie)
{ // unable to create the class
logger.fatal("<sidebox/> <factory-class/> could not be instantiated!",ie);
throw new ConfigException("<factory-class/> in <sidebox/> could not be created!",cfg);
} // 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);
catch (ClassCastException cce)
{ // the class is not a SideBoxFactory implementor - cannot create
logger.fatal("<sidebox/> <factory-class/> is not a SideBoxFactory!",cce);
throw new ConfigException("<factory-class/> in <sidebox/> is not the correct type!",cfg);
} // end catch
} // end loadConfiguration
} // end createSideBoxFactory
/*--------------------------------------------------------------------------------
* External operations usable only by RenderData
@ -740,6 +573,12 @@ public class RenderConfig implements ColorSelectors
} // end getPhotoNotAvailFixup
public CommunityLeftMenu createCommunityMenu(CommunityContext comm)
{
return comm_menu_fact.createMenu(comm);
} // end createCommunityMenu
/*--------------------------------------------------------------------------------
* Static operations for use by VeniceServlet
*--------------------------------------------------------------------------------

View File

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

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