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(" seen with no \"id\" attribute");
- throw new ConfigException(" seen with no \"id\" attribute",mel);
+ 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");
- } // end if
-
- // create the menu and add it to the mapping
- LeftMenu menu = new LeftMenu(mel,menuid);
- 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 ");
- throw new ConfigException("unknown node name <" + mn.getNodeName() + "/> in ",
- menu_sect);
-
- } // end else
+ // create the menu and add it to the mapping
+ LeftMenu menu = new LeftMenu((Element)n,menuid);
+ tmp_menus.put(menuid,menu);
+ if (logger.isDebugEnabled())
+ logger.debug("menu \"" + menuid + "\" defined");
} // 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 ID not numeric!");
+ throw new ConfigException("non-numeric ID specified in ",(Element)n);
+
+ } // end catch
+
+ SideBoxFactory factory = createSideBoxFactory((Element)n);
+ tmp_factories.put(itmp,factory);
+
+ } // end if
+ // else ignore this node
} // end for
- if (logger.isDebugEnabled())
- logger.debug(menus.size() + " menu definitions loaded from config");
+ 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(" config not valid!",cnfe);
+ throw new ConfigException(" in 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(" is not accessible!",iae);
+ throw new ConfigException(" in 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(" could not be instantiated!",ie);
+ throw new ConfigException(" in 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(" is not a SideBoxFactory!",cce);
+ throw new ConfigException(" in 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
*--------------------------------------------------------------------------------
diff --git a/src/com/silverwrist/venice/servlets/format/MenuCommunity.java b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenu.java
similarity index 83%
rename from src/com/silverwrist/venice/servlets/format/MenuCommunity.java
rename to src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenu.java
index 9698c77..d05a934 100644
--- a/src/com/silverwrist/venice/servlets/format/MenuCommunity.java
+++ b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenu.java
@@ -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("" + StringUtil.encodeHTML(title) + "");
+ out.write("" + StringUtil.encodeHTML(title) + "
");
// 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("
\n" + hilite
- + StringUtil.encodeHTML(ftr.getName()) + "\n");
+ ComponentRender cr = (ComponentRender)(it.next());
+ cr.renderHere(out,rdat);
} // end while
if (show_unjoin)
- out.write("\n"
- + hilite + "Unjoin\n");
+ out.write("
\n" + hilite
+ + "Unjoin\n");
out.write("\n"); // all done...
@@ -126,4 +124,4 @@ public class MenuCommunity implements ComponentRender, ColorSelectors
} // end getID
-} // end class MenuCommunity
+} // end class CommunityLeftMenu
diff --git a/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuEntry.java b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuEntry.java
new file mode 100644
index 0000000..1c14c35
--- /dev/null
+++ b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuEntry.java
@@ -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 .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 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
diff --git a/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuFactory.java b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuFactory.java
new file mode 100644
index 0000000..d16009a
--- /dev/null
+++ b/src/com/silverwrist/venice/servlets/format/menus/CommunityLeftMenuFactory.java
@@ -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 .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 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; i1)
+ 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
diff --git a/src/com/silverwrist/venice/servlets/format/menus/LinkItem.java b/src/com/silverwrist/venice/servlets/format/menus/LinkItem.java
index fdc7fde..fa0e7e0 100644
--- a/src/com/silverwrist/venice/servlets/format/menus/LinkItem.java
+++ b/src/com/silverwrist/venice/servlets/format/menus/LinkItem.java
@@ -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
*--------------------------------------------------------------------------------
diff --git a/src/com/silverwrist/venice/svc/CommService.java b/src/com/silverwrist/venice/svc/CommService.java
new file mode 100644
index 0000000..ba7f085
--- /dev/null
+++ b/src/com/silverwrist/venice/svc/CommService.java
@@ -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 .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 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
diff --git a/src/com/silverwrist/venice/svc/CommServiceSite.java b/src/com/silverwrist/venice/svc/CommServiceSite.java
new file mode 100644
index 0000000..a940058
--- /dev/null
+++ b/src/com/silverwrist/venice/svc/CommServiceSite.java
@@ -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 .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.venice.svc;
+
+public interface CommServiceSite
+{
+} // end interface CommServiceSite
diff --git a/src/com/silverwrist/venice/util/XMLLoader.java b/src/com/silverwrist/venice/util/XMLLoader.java
new file mode 100644
index 0000000..b6483f6
--- /dev/null
+++ b/src/com/silverwrist/venice/util/XMLLoader.java
@@ -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 .
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
+ * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
+ * language governing rights and limitations under the License.
+ *
+ * The Original Code is the Venice Web Communities System.
+ *
+ * The Initial Developer of the Original Code is Eric J. Bowersox ,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 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