Attached is my modified ClayXmlParser which digests description
elements and sets them into extended ComponentBeans.

My mistake, forgot to add digester rules for attributes and symbols.
Attached is the fixed version.
package clay_plugin.parser;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shale.clay.config.ClayConfigParser;
import org.apache.shale.clay.config.ClayConfigureListener;
import org.apache.shale.clay.config.beans.ComponentBean;
import org.apache.shale.clay.config.beans.ComponentConfigBean;
import org.apache.shale.clay.config.beans.ConfigBean;
import org.apache.shale.util.Messages;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * <p>
 * This class loads the configuration files defining page fragments and caches a
 * graph of beans in application scope. The location of the default
 * configuration file is located at
 * <code>Globals.DEFAULT_CLAY_CONFIG_FILE</code>. A comma value list of names
 * can be supplied as a initialization parameter in the web deployment
 * descriptor using the parameter name <code>Globals.CLAY_CONFIG_FILES</code>.
 * </p>
 */

public class ClayXmlParserExt implements ClayConfigParser {

	/**
	 * <p>
	 * The [EMAIL PROTECTED] ComponentConfigBean} is the container holding all of the
	 * component metadata definitions read for the configuration files.
	 * </p>
	 */
	private ConfigBean config = null;

	/**
	 * <p>
	 * The <code>Digester</code> makes short work of materalizing a XML
	 * document into an object graph using simple binding rules.
	 * </p>
	 */
	private Digester digester;

	/**
	 * <p>
	 * Commons logging utility object static instance.
	 * </p>
	 */
	private static Log log;
	static {
		log = LogFactory
				.getLog(org.apache.shale.clay.config.ClayXmlParser.class);
	}

	/**
	 * @return config [EMAIL PROTECTED] ConfigBean} instance of the component metadata
	 *         container
	 */
	public ConfigBean getConfig() {
		return config;
	}

	/**
	 * @param config
	 *            [EMAIL PROTECTED] ConfigBean} instance of the component metadata
	 *            container
	 */
	public void setConfig(ConfigBean config) {
		this.config = config;
	}

	/**
	 * <p>
	 * Message resources for this class.
	 * </p>
	 */
	private static Messages messages = new Messages(
			"org.apache.shale.clay.Bundle", ClayConfigureListener.class
					.getClassLoader());

	/**
	 * <p>
	 * A static array of local DTD's to validate the digested documents against
	 * when not connected to the internet.
	 * </p>
	 */
	protected Object[] registrations = { new String[] {
			"-//Apache Software Foundation//DTD Shale Clay View Configuration 1.0//EN",
			"/org/apache/shale/clay/config/clay-config_1_0.dtd" } };

	/**
	 * <p>
	 * This is a custom digester Rule that handles adding value pairs to the
	 * symbols table on the [EMAIL PROTECTED] ComponentBean} nodes.
	 * </p>
	 */
	private class SymbolRule extends Rule {

		/**
		 * <p>
		 * Takes a peek at the last object on the digester stack. It assume that
		 * it will be a [EMAIL PROTECTED] ComponentBean}. The attributes "name" and
		 * "value" are pulled from the <code>Attributes</code> sax collection
		 * and pushed into the [EMAIL PROTECTED] ComponentBean}'s <code>symbols</code>
		 * Map collection. The character '@' is prepended to the symbol name if
		 * not existing.
		 * </p>
		 */
		public void begin(String qname, String name, Attributes attributes)
				throws Exception {
			ComponentBean b = (ComponentBean) super.digester.peek();
			if (b != null && attributes != null) {
				String key = attributes.getValue("name");
				String value = attributes.getValue("value");
				if (name != null) {
					StringBuffer tmp = new StringBuffer(key);
					if (tmp.charAt(0) != '@')
						tmp.insert(0, '@');

					b.addSymbol(tmp.toString(), value);
				}
			}
		}

	}

	/**
	 * <p>
	 * Loads a configuration file from a <code>url</code>. The input stream
	 * is identifed by the <code>watchDogName</code>.
	 * </p>
	 */
	public void loadConfigFile(URL configURL, String watchDogName)
			throws IOException, SAXException {

		if (digester == null) {
			digester = new Digester();
			digester.setLogger(log);
			digester.setValidating(true);
			digester.setUseContextClassLoader(true);

			// Register our local copy of the DTDs that we can find
			for (int i = 0; i < registrations.length; i++) {
				URL url = this.getClass().getResource(
						((String[]) registrations[i])[1]);
				if (url != null) {
					digester.register(((String[]) registrations[i])[0], url
							.toString());
				}
			}

			configureRules();
			digester.push(config);
		} else {
			digester.clear();
			digester.push(config);
		}

		InputStream in = null;
		InputSource inputSource = null;
		try {
			in = configURL.openStream();
			inputSource = new InputSource(configURL.toExternalForm());
			inputSource.setByteStream(in);
			digester.parse(inputSource);
		} finally {
			if (in != null) {
				in.close();
			}
		}
		inputSource = null;

	}

	/**
	 * <p>
	 * This method is called once to register the object binding rules with the
	 * <code>Digester</code> instance.
	 * </p>
	 */
	protected void configureRules() {

		if (log.isInfoEnabled())
			log.info(messages.getMessage("parser.load.rules"));

		digester.addObjectCreate("*/attributes/set",
				clay_plugin.ext.AttributeBeanExt.class);
		digester.addSetProperties("*/attributes/set");
		configureDescriptionRule("*/attributes/set");
		digester.addSetNext("*/attributes/set", "addAttribute",
				"clay_plugin.ext.AttributeBeanExt");

		digester.addRule("*/symbols/set", new SymbolRule());
		configureDescriptionRule("*/symbols/set");

		digester.addObjectCreate("*/valueChangeListener",
				clay_plugin.ext.ValueChangeListenerBeanExt.class);
		digester.addSetProperties("*/valueChangeListener");
		configureDescriptionRule("*/valueChangeListener");
		digester.addSetNext("*/valueChangeListener", "addValueChangeListener",
				"clay_plugin.ext.ValueChangeListenerBeanExt");

		digester.addObjectCreate("*/actionListener",
				clay_plugin.ext.ActionListenerBeanExt.class);
		digester.addSetProperties("*/actionListener");
		configureDescriptionRule("*/actionListener");
		digester.addSetNext("*/actionListener", "addActionListener",
				"clay_plugin.ext.ActionListenerBeanExt");

		digester.addObjectCreate("*/validator",
				clay_plugin.ext.ValidatorBeanExt.class);
		digester.addSetProperties("*/validator");
		configureDescriptionRule("*/validator");
		digester.addSetNext("*/validator", "addValidator",
				"clay_plugin.ext.ValidatorBeanExt");

		digester.addObjectCreate("*/converter",
				clay_plugin.ext.ConverterBeanExt.class);
		digester.addSetProperties("*/converter");
		configureDescriptionRule("*/converter");
		digester.addSetNext("*/converter", "addConverter",
				"clay_plugin.ext.ConverterBeanExt");

		digester.addObjectCreate("*/element",
				clay_plugin.ext.ElementBeanExt.class);
		digester.addSetProperties("*/element");
		configureDescriptionRule("*/element");
		digester.addSetNext("*/element", "addChild",
				"clay_plugin.ext.ElementBeanExt");

		digester.addObjectCreate("view/component",
				clay_plugin.ext.ComponentBeanExt.class);
		digester.addSetProperties("view/component");
		configureDescriptionRule("view/component");
		digester.addSetNext("view/component", "addChild",
				"clay_plugin.ext.ComponentBeanExt");

	}

	protected void configureDescriptionRule(String prefix) {

		digester.addBeanPropertySetter(prefix + "/description", "description");

	}

}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to