On 6/6/06, Gary VanMatre <[EMAIL PROTECTED]> wrote:
>From: "Ryan Wynn" <[EMAIL PROTECTED]>
> I have had to work around the use of private instance variables in a
> couple other scenarios in trying to build this plugin. I was just
> wondering if anyone was opposed to changing some of these instance
> variables to protected or adding protected accessors.
>

That seems very reasonable.  It might be easier if you just created a JIRA svn 
patch but if you can't do that for whatever reason, I can make the changes.


Just wanted to get your feedback before I created a JIRA ticket.  I
just got it working but had to resort to copy and paste of the clay
code + some of my changes.  Basically I found out that instead of just
being able to extend configureRules I needed to weave in digester
rules throughout the existing code.  I also needed to extend all the
ComponentBeans to provide a description attribute.

What I am trying to do would be easier if the base ComponentBean class
had a description attribute.  Would it be bad to create this attribute
and not 'digest' it under normal runtime circumstances but make it
available to tooling?

This could be accompanied by a flag on the ClayXmlParser indicated
that the descriptions should be digested.  It could default to false,
but tooling could override to true.

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


> Thanks,
> Ryan
>

Gary

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

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",
				org.apache.shale.clay.config.beans.AttributeBean.class);
		digester.addSetProperties("*/attributes/set");
		digester.addSetNext("*/attributes/set", "addAttribute",
				"org.apache.shale.clay.config.beans.AttributeBean");

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

		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