[jboss-svn-commits] JBL Code SVN: r10971 - in labs/jbossesb/trunk/product/core: listeners/src/org/jboss/soa/esb/actions/persistence and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Apr 13 13:26:28 EDT 2007


Author: derek.adams
Date: 2007-04-13 13:26:27 -0400 (Fri, 13 Apr 2007)
New Revision: 10971

Added:
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/BeanConfiguredAction.java
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionBeanConfigurator.java
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/BeanConfigActionProcessor.java
   labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/util/BeanConfigurator.java
Modified:
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java
   labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
Log:
Added support for bean-configured actions.

Added: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/BeanConfiguredAction.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/BeanConfiguredAction.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/BeanConfiguredAction.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -0,0 +1,10 @@
+package org.jboss.soa.esb.actions;
+
+/**
+ * Marker interface for actions configured automatically by invoking setters
+ * based on ConfigTree attributes.
+ * 
+ * @author Derek Adams
+ */
+public interface BeanConfiguredAction {
+}
\ No newline at end of file

Modified: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java	2007-04-13 17:25:12 UTC (rev 10970)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/actions/persistence/StoreMessage.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -5,7 +5,7 @@
 
 import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
 import org.jboss.soa.esb.actions.ActionProcessingException;
-import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.actions.BeanConfiguredAction;
 import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.services.persistence.MessageStore;
 import org.jboss.soa.esb.services.persistence.MessageStoreException;
@@ -13,34 +13,39 @@
 import org.jboss.soa.esb.services.persistence.MessageStoreType;
 
 /**
- * Action that stores the incoming message to the message store.
+ * Action that stores the incoming message to a message store. The
+ * <code>messageStoreType</code> property indicates which message store to
+ * use. If not specified, the default message store is used. If the property
+ * value is 'database' or 'jcr', the indicated message store is used.
+ * Alternatively, the URI for any other message store type can be passed as the
+ * value.
  * 
  * @author Derek Adams
  */
-public class StoreMessage extends AbstractActionPipelineProcessor {
+public class StoreMessage extends AbstractActionPipelineProcessor implements BeanConfiguredAction {
 
 	/** Property that indicates the type of message store to be queried */
 	public static final String MESSAGE_STORE_TYPE = "messageStoreType";
-	
+
 	/** Constant that indicates the database datastore should be used */
 	public static final String INDICATOR_DATABASE = "database";
-	
+
 	/** Constant that indicates the JCR datastore should be used */
 	public static final String INDICATOR_JCR = "jcr";
 
-	/** Configuration elements */
-	protected ConfigTree config;
+	/** Message store type indicator injected from bean config */
+	protected String messageStoreType;
 
 	/** URI that indicates message store type */
-	protected URI messageStoreType;
+	protected URI messageStoreTypeURI;
 
 	/**
-	 * Constructor called by pipeline.
+	 * Message store type injected from bean configuartion.
 	 * 
-	 * @param config
+	 * @param messageStoreType
 	 */
-	public StoreMessage(ConfigTree config) {
-		this.config = config;
+	public void setMessageStoreType(String messageStoreType) {
+		this.messageStoreType = messageStoreType;
 	}
 
 	/**
@@ -49,24 +54,23 @@
 	 * @return
 	 * @throws ActionProcessingException
 	 */
-	protected URI getMessageStoreType() throws ActionProcessingException {
-		if (messageStoreType == null) {
-			String strMessageStoreType = config.getAttribute(MESSAGE_STORE_TYPE);
-			if (strMessageStoreType == null) {
-				messageStoreType = MessageStoreType.DEFAULT_TYPE;
-			} else if (INDICATOR_DATABASE.equalsIgnoreCase(strMessageStoreType)) {
-				messageStoreType = MessageStoreType.DATABASE;
-			} else if (INDICATOR_JCR.equalsIgnoreCase(strMessageStoreType)) {
-				messageStoreType = MessageStoreType.JCR;
+	protected URI getMessageStoreTypeURI() throws ActionProcessingException {
+		if (messageStoreTypeURI == null) {
+			if (messageStoreType == null) {
+				messageStoreTypeURI = MessageStoreType.DEFAULT_TYPE;
+			} else if (INDICATOR_DATABASE.equalsIgnoreCase(messageStoreType)) {
+				messageStoreTypeURI = MessageStoreType.DATABASE;
+			} else if (INDICATOR_JCR.equalsIgnoreCase(messageStoreType)) {
+				messageStoreTypeURI = MessageStoreType.JCR;
 			} else {
 				try {
-					messageStoreType = new URI(strMessageStoreType);
+					messageStoreTypeURI = new URI(messageStoreType);
 				} catch (URISyntaxException e) {
 					throw new ActionProcessingException(e);
 				}
 			}
 		}
-		return messageStoreType;
+		return messageStoreTypeURI;
 	}
 
 	/*
@@ -76,7 +80,7 @@
 	 */
 	public Message process(Message message) throws ActionProcessingException {
 		MessageStore store = MessageStoreFactory.getInstance().getMessageStore(
-				getMessageStoreType());
+				getMessageStoreTypeURI());
 		try {
 			store.addMessage(message);
 			return message;

Added: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionBeanConfigurator.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionBeanConfigurator.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionBeanConfigurator.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -0,0 +1,50 @@
+/**
+ * 
+ */
+package org.jboss.soa.esb.listeners.message;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.helpers.KeyValuePair;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.util.BeanConfigurator;
+
+/**
+ * ActionBeanConfigurator was created because ActionMapper flattens the
+ * ConfigTree by promoting child "property" elements to attributes on the parent
+ * element.
+ * 
+ * @author <a href="mailto:rex.sheridan at sapience360.com">Rex Sheridan</a>
+ * 
+ */
+public class ActionBeanConfigurator extends BeanConfigurator {
+
+	/**
+	 * A list of key-value pairs to ignore because they don't actually
+	 * correspond to bean properties.
+	 */
+	private static final List<String> ignored = Arrays.asList("action",
+			ListenerTagNames.ACTION_ELEMENT_TAG,
+			ListenerTagNames.ACTION_CLASS_TAG,
+			ListenerTagNames.PROCESS_METHOD_TAG);
+
+	/**
+	 * @param config
+	 * @param bean
+	 */
+	ActionBeanConfigurator(ConfigTree config, Object bean) {
+		setBean(bean);
+		List<KeyValuePair> pairs = config.attributesAsList();
+		Map<String, String> properties = new HashMap<String, String>();
+		for (KeyValuePair kvp : pairs) {
+			if (!ignored.contains(kvp.getKey())) {
+				properties.put(kvp.getKey(), kvp.getValue());
+			}
+		}
+		setProperties(properties);
+	}
+}

Modified: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java	2007-04-13 17:25:12 UTC (rev 10970)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -30,6 +30,7 @@
 import org.jboss.soa.esb.actions.ActionLifecycle;
 import org.jboss.soa.esb.actions.ActionPipelineProcessor;
 import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.BeanConfiguredAction;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.listeners.ListenerTagNames;
 import org.jboss.soa.esb.message.Message;
@@ -101,8 +102,16 @@
             }
             
             final ActionPipelineProcessor processor ;
-            if (ActionPipelineProcessor.class.isAssignableFrom(actionClass))
+            if (BeanConfiguredAction.class.isAssignableFrom(actionClass))
             {
+                if (LOGGER.isDebugEnabled())
+                {
+                    LOGGER.debug("Using bean configured action processor for " + actionClassTag) ;
+                }
+                processor = new BeanConfigActionProcessor(actionConfig, actionClass) ;
+            } 
+            else if (ActionPipelineProcessor.class.isAssignableFrom(actionClass))
+            {
                 final ActionPipelineProcessor currentProcessor = (ActionPipelineProcessor)ActionProcessorMethodInfo.getActionClassInstance(actionConfig, actionClass) ;
                 if (ActionProcessorMethodInfo.checkOverridden(actionConfig))
                 {

Added: labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/BeanConfigActionProcessor.java
===================================================================
--- labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/BeanConfigActionProcessor.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/listeners/src/org/jboss/soa/esb/listeners/message/BeanConfigActionProcessor.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -0,0 +1,96 @@
+package org.jboss.soa.esb.listeners.message;
+
+import java.lang.reflect.Constructor;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.actions.ActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.util.BeanConfigurator;
+
+public class BeanConfigActionProcessor implements ActionPipelineProcessor {
+
+	/** Config tree for processor */
+	private final ConfigTree config;
+
+	/** No-argument constructor for action class */
+	private final Constructor constructor;
+
+	/** Method info on action class */
+	private final ActionProcessorMethodInfo methodInfo;
+
+	/**
+	 * Construct the overridden action processor.
+	 * 
+	 * @param config The action config.
+	 * @param actionClass The action class.
+	 * @throws ConfigurationException for errors during configuration.
+	 */
+	BeanConfigActionProcessor(final ConfigTree config, final Class actionClass)
+			throws ConfigurationException {
+		this.config = config;
+		try {
+			this.constructor = actionClass.getConstructor();
+		} catch (SecurityException e) {
+			throw new ConfigurationException(e);
+		} catch (NoSuchMethodException e) {
+			throw new ConfigurationException(e);
+		}
+		this.methodInfo = ActionProcessorMethodInfo.getMethodInfo(config, actionClass);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#process(org.jboss.soa.esb.message.Message)
+	 */
+	public Message process(Message message) throws ActionProcessingException {
+		if (methodInfo.hasProcessMethods()) {
+			try {
+				Object instance = constructor.newInstance();
+				BeanConfigurator configurator = new ActionBeanConfigurator(config, instance);
+				configurator.configure();
+				return methodInfo.processMethods(instance, message);
+			} catch (Exception e) {
+				throw new ActionProcessingException(e);
+			}
+		} else {
+			return message;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#processException(org.jboss.soa.esb.message.Message,
+	 * java.lang.Throwable)
+	 */
+	public void processException(Message message, Throwable th) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#processSuccess(org.jboss.soa.esb.message.Message)
+	 */
+	public void processSuccess(Message message) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionLifecycle#destroy()
+	 */
+	public void destroy() throws ActionLifecycleException {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.jboss.soa.esb.actions.ActionLifecycle#initialise()
+	 */
+	public void initialise() throws ActionLifecycleException {
+	}
+}
\ No newline at end of file

Added: labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/util/BeanConfigurator.java
===================================================================
--- labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/util/BeanConfigurator.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/core/rosetta/src/org/jboss/soa/esb/util/BeanConfigurator.java	2007-04-13 17:26:27 UTC (rev 10971)
@@ -0,0 +1,134 @@
+/**
+ * 
+ */
+package org.jboss.soa.esb.util;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.helpers.KeyValuePair;
+
+/**
+ * The BeanConfigurator knows how to map a ConfigTree to JavaBean properties.
+ * 
+ * @author <a href="mailto:rex.sheridan at sapience360.com">Rex Sheridan</a>
+ */
+public class BeanConfigurator {
+
+	private PropertyDescriptor[] descriptors;
+
+	private Object bean;
+
+	private Map<String, String> properties;
+
+	public BeanConfigurator() {
+		super();
+	}
+
+	public BeanConfigurator(ConfigTree config, Object bean) {
+		List<KeyValuePair> pairs = config.childPropertyList();
+		properties = new HashMap<String, String>();
+		for (KeyValuePair kvp : pairs) {
+			properties.put(kvp.getKey(), kvp.getValue());
+		}
+		this.bean = bean;
+	}
+
+	public BeanConfigurator(Map<String, String> properties, Object bean) {
+		this.properties = properties;
+		this.bean = bean;
+	}
+
+	public void configure() throws IntrospectionException {
+		Class<? extends Object> beanClass = bean.getClass();
+		BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
+		descriptors = beanInfo.getPropertyDescriptors();
+
+		for (Entry<String, String> entry : properties.entrySet()) {
+			String key = entry.getKey();
+			key = Introspector.decapitalize(key);
+			PropertyDescriptor descriptor = getPropertyDescriptor(key);
+			if (descriptor == null) {
+				throw new IllegalArgumentException("'" + key
+						+ "' property not found on " + beanClass.getName());
+			}
+			setProperty(descriptor, key, entry.getValue());
+		}
+	}
+
+	protected void setProperty(PropertyDescriptor descriptor, String name,
+			String value) {
+		Method setter = descriptor.getWriteMethod();
+		if (setter == null) {
+			throw new IllegalArgumentException("No setter for property ["
+					+ name + "]");
+		}
+
+		Object arg;
+		Class<?> propertyType = descriptor.getPropertyType();
+		PropertyEditor editor = PropertyEditorManager.findEditor(propertyType);
+		if (editor == null) {
+			throw new IllegalArgumentException(
+					"Unable to find suitable property editor for property="
+							+ name + " type=" + propertyType.getName());
+		}
+		editor.setAsText(value);
+		arg = editor.getValue();
+
+		try {
+			setter.invoke(bean, new Object[] { arg });
+		} catch (Exception ex) {
+			throw new RuntimeException("Unable to set property named '+" + name
+					+ "'", ex);
+		}
+	}
+
+	protected PropertyDescriptor getPropertyDescriptor(String name) {
+		for (int i = 0; i < descriptors.length; i++) {
+			if (name.equals(descriptors[i].getName())) {
+				return descriptors[i];
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @return the bean
+	 */
+	public Object getBean() {
+		return bean;
+	}
+
+	/**
+	 * @param bean
+	 *            the bean to set
+	 */
+	public void setBean(Object bean) {
+		this.bean = bean;
+	}
+
+	/**
+	 * @return the properties
+	 */
+	public Map<String, String> getProperties() {
+		return properties;
+	}
+
+	/**
+	 * @param properties
+	 *            the properties to set
+	 */
+	public void setProperties(Map<String, String> properties) {
+		this.properties = properties;
+	}
+}
\ No newline at end of file




More information about the jboss-svn-commits mailing list