>From: "Ryan Wynn" <[EMAIL PROTECTED]>
>
> 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
> be ing ab le 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?
>
 
That seems reasonable in this case since the "description" is part of the DTD. 
We could just provide a boolean property to toggle on reading the descriptions
and add the property to all the config beans.
 
We need to create a JIRA ticket so we can track the change regardless. 
 
Gary
 

> 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]
> > >
> >
--- Begin Message ---
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]

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

Reply via email to