[jboss-svn-commits] JBL Code SVN: r32847 - in labs/jbossesb/workspace/tfennelly/annotated_components/product: rosetta/src/org/jboss/soa/esb and 11 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed May 12 16:13:02 EDT 2010
Author: tfennelly
Date: 2010-05-12 16:13:01 -0400 (Wed, 12 May 2010)
New Revision: 32847
Added:
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnExceptionMethod.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnSuccessMethod.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/ProcessMethod.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/AnnotationUtil.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/ConfigProperty.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/Configurator.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Destroy.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Initialize.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/BeanContainerAction.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/AlphaChar.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycle.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycleAndSuperLifecycle.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithNoLifecycle.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ConfiguratorUnitTest.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/BeanContainerActionUnitTest.java
Modified:
labs/jbossesb/workspace/tfennelly/annotated_components/product/.classpath
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/http/HttpRequest.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java
labs/jbossesb/workspace/tfennelly/annotated_components/product/samples/quickstarts/http_gateway/src/org/jboss/soa/esb/samples/quickstart/httpgateway/MyAction.java
Log:
initial spike of component annotations
Modified: labs/jbossesb/workspace/tfennelly/annotated_components/product/.classpath
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/.classpath 2010-05-12 19:31:20 UTC (rev 32846)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/.classpath 2010-05-12 20:13:01 UTC (rev 32847)
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**/.svn/" kind="src" path="rosetta/src"/>
+ <classpathentry kind="src" path="samples/quickstarts/http_gateway/src"/>
<classpathentry excluding="**/.svn/" kind="src" path="rosetta/tests/src"/>
<classpathentry excluding="**/.svn/" kind="src" path="rosetta/tests/resources"/>
<classpathentry excluding="**/.svn/" kind="src" path="services/jbossesb/src/main/java"/>
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnExceptionMethod.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnExceptionMethod.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnExceptionMethod.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.actions.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * On Exception action process method.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface OnExceptionMethod {
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnExceptionMethod.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnSuccessMethod.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnSuccessMethod.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnSuccessMethod.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.actions.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * On success action process method.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface OnSuccessMethod {
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/OnSuccessMethod.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/ProcessMethod.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/ProcessMethod.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/ProcessMethod.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.actions.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Action process method.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface ProcessMethod {
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/actions/annotation/ProcessMethod.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/AnnotationUtil.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/AnnotationUtil.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/AnnotationUtil.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,74 @@
+/*
+ Milyn - Copyright (C) 2006 - 2010
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License (version 2.1) as published by the Free Software
+ Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Lesser General Public License for more details:
+ http://www.gnu.org/licenses/lgpl.txt
+*/
+package org.jboss.soa.esb.configure;
+
+import org.jboss.soa.esb.actions.annotation.AttachmentParam;
+import org.jboss.soa.esb.actions.annotation.BodyParam;
+import org.jboss.soa.esb.actions.annotation.PropertyParam;
+
+/**
+ * Annotation constants.
+ *
+ * @author <a href="mailto:tom.fennelly at gmail.com">tom.fennelly at gmail.com</a>
+ */
+public abstract class AnnotationUtil {
+
+ /**
+ * "null" default annotation value.
+ */
+ public static final String NULL_STRING = "##NULL##";
+
+ /**
+ * Unassigned default.
+ */
+ public static final String UNASSIGNED = "##UNASSIGNED##";
+
+ public static String getPropertyName(PropertyParam propertyParam) {
+ if(propertyParam == null) {
+ return null;
+ }
+
+ if(NULL_STRING.equals(propertyParam.value())) {
+ return null;
+ }
+
+ return propertyParam.value();
+ }
+
+ public static String getBodyName(BodyParam bodyParam) {
+ if(bodyParam == null) {
+ return null;
+ }
+
+ if(NULL_STRING.equals(bodyParam.value())) {
+ return null;
+ }
+
+ return bodyParam.value();
+ }
+
+ public static String getAttachmentName(AttachmentParam attachmentParam) {
+ if(attachmentParam == null) {
+ return null;
+ }
+
+ if(NULL_STRING.equals(attachmentParam.value())) {
+ return null;
+ }
+
+ return attachmentParam.value();
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/AnnotationUtil.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/ConfigProperty.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/ConfigProperty.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/ConfigProperty.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,77 @@
+/*
+ Milyn - Copyright (C) 2006 - 2010
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License (version 2.1) as published by the Free Software
+ Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Lesser General Public License for more details:
+ http://www.gnu.org/licenses/lgpl.txt
+*/
+package org.jboss.soa.esb.configure;
+
+import java.lang.annotation.*;
+
+/**
+ * Configuration property class member annotation.
+ *
+ * @author <a href="mailto:tom.fennelly at gmail.com">tom.fennelly at gmail.com</a>
+ * @see Configurator
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.FIELD, ElementType.METHOD})
+public @interface ConfigProperty {
+
+ /**
+ * The paramater name as defined in the resource configuration. If not defined,
+ * the name defaults to the name of the field.
+ * @return The paramater name.
+ */
+ public String name() default AnnotationUtil.NULL_STRING;
+
+ /**
+ * Paramater required or optional.
+ * <p/>
+ * Defaults to required.
+ *
+ * @return Paramater usage.
+ */
+ public Use use() default Use.REQUIRED;
+
+ /**
+ * The default paramater value.
+ * <p/>
+ * Only relevant when use=OPTIONAL and the paramater is not defined on the configuration..
+ *
+ * @return The default paramater value (un-decoded).
+ */
+ public String defaultVal() default AnnotationUtil.UNASSIGNED;
+
+ /**
+ * Paramater choice values.
+ *
+ * @return List of valid choices (un-decoded).
+ */
+ public String[] choice() default AnnotationUtil.NULL_STRING;
+
+ /**
+ * Configuration paramater use.
+ */
+ public static enum Use {
+ /**
+ * Parameter is required.
+ */
+ REQUIRED,
+
+ /**
+ * Parameter is optional.
+ */
+ OPTIONAL,
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/ConfigProperty.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/Configurator.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/Configurator.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/Configurator.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,329 @@
+/*
+ Milyn - Copyright (C) 2006 - 2010
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License (version 2.1) as published by the Free Software
+ Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU Lesser General Public License for more details:
+ http://www.gnu.org/licenses/lgpl.txt
+*/
+package org.jboss.soa.esb.configure;
+
+import org.apache.commons.logging.*;
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.annotation.Destroy;
+import org.jboss.soa.esb.lifecycle.annotation.Initialize;
+import org.milyn.javabean.DataDecodeException;
+import org.milyn.javabean.DataDecoder;
+import org.milyn.util.ClassUtil;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Utility class for processing configuration annotations on an
+ * ESB Component class.
+ * <p/>
+ * Code donated from Smooks project.
+ *
+ * @author <a href="mailto:tom.fennelly at gmail.com">tom.fennelly at gmail.com</a>
+ */
+public class Configurator {
+
+ private static Log logger = LogFactory.getLog(Configurator.class);
+
+ /**
+ * Configure the supplied object instance using the supplied
+ * {@link ConfigTree} instance.
+ * @param instance The instance to be configured.
+ * @param config The configuration.
+ * @return The configured object instance.
+ * @throws ConfigurationException Invalid field annotations.
+ */
+ public static <U> U configure(U instance, ConfigTree config) throws ConfigurationException {
+ AssertArgument.isNotNull(instance, "instance");
+ AssertArgument.isNotNull(config, "config");
+
+ // process the field annotations (@ConfigParam)...
+ processFieldConfigParamAnnotations(instance.getClass(), instance, config);
+
+ // process the method annotations (@ConfigParam)...
+ processMethodConfigAnnotations(instance, config);
+
+ return instance;
+ }
+
+ private static <U> void processFieldConfigParamAnnotations(Class<?> runtimeClass, U instance, ConfigTree config) throws ConfigurationException {
+ Field[] fields = runtimeClass.getDeclaredFields();
+
+ // Work back up the Inheritance tree first...
+ Class<?> superClass = runtimeClass.getSuperclass();
+ if(superClass != null) {
+ processFieldConfigParamAnnotations(superClass, instance, config);
+ }
+
+ for (Field field : fields) {
+ ConfigProperty configParamAnnotation = null;
+
+ configParamAnnotation = field.getAnnotation(ConfigProperty.class);
+ if(configParamAnnotation != null) {
+ applyConfigParam(configParamAnnotation, field, field.getType(), instance, config);
+ }
+ }
+ }
+
+ private static <U> void checkPropertiesConfigured(Class<?> runtimeClass, U instance) throws ConfigurationException {
+ Field[] fields = runtimeClass.getDeclaredFields();
+
+ // Work back up the Inheritance tree first...
+ Class<?> superClass = runtimeClass.getSuperclass();
+ if(superClass != null) {
+ checkPropertiesConfigured(superClass, instance);
+ }
+
+ for (Field field : fields) {
+ String fieldName = field.getName();
+ Object fieldValue;
+
+ try {
+ fieldValue = ClassUtil.getField(field, instance);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Unable to get property field value for '" + getLongMemberName(field) + "'.", e);
+ }
+
+ if(fieldValue != null) {
+ // It's set so no need to check anything....
+ continue;
+ }
+
+ ConfigProperty configParamAnnotation = field.getAnnotation(ConfigProperty.class);
+ if(configParamAnnotation == null) {
+ // Check is there's a setter method for this property, with the @ConfigParam annotation
+ // configured on it...
+ String setterName = ClassUtil.toSetterName(fieldName);
+ Method setterMethod = ClassUtil.getSetterMethod(setterName, runtimeClass, field.getType());
+
+ if(setterMethod != null) {
+ configParamAnnotation = setterMethod.getAnnotation(ConfigProperty.class);
+ }
+ }
+
+ if(configParamAnnotation != null) {
+ // If it's required and not configured with a default value of AnnotationConstants.NULL_STRING, error...
+ if(configParamAnnotation.use() == ConfigProperty.Use.REQUIRED) {
+ // Property configured and it's required....
+
+ String defaultVal = configParamAnnotation.defaultVal();
+
+ // If there is no default (i.e. it's "UNASSIGNED"), we have an error...
+ if(defaultVal.equals(AnnotationUtil.UNASSIGNED)) {
+ throw new ConfigurationException("Property '" + fieldName + "' not configured on class " + instance.getClass().getName() + "'.");
+ }
+
+ // If the default is "NULL", just continue...
+ if(defaultVal.equals(AnnotationUtil.NULL_STRING)) {
+ continue;
+ }
+
+ // Decode the default and set it on the property...
+ // No decoder specified via annotation. Infer from the field type...
+ DataDecoder decoder = DataDecoder.Factory.create(field.getType());
+ if(decoder == null) {
+ throw new ConfigurationException("Class member '" + getLongMemberName(field) + "' is annotated with the @ConfigParam annotation. Cannot find a DataDecoder from member type '" + field.getType().getName() + "'. Define as a String and manually decode in an @Initialize method.");
+ }
+ try {
+ ClassUtil.setField(field, instance, decoder.decode(defaultVal));
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Unable to set property field value for '" + getLongMemberName(field) + "'.", e);
+ }
+ }
+ }
+ }
+ }
+
+ private static <U> void processMethodConfigAnnotations(U instance, ConfigTree config) throws ConfigurationException {
+ Method[] methods = instance.getClass().getMethods();
+
+ for (Method method : methods) {
+ ConfigProperty configParamAnnotation = method.getAnnotation(ConfigProperty.class);
+ if(configParamAnnotation != null) {
+ Class params[] = method.getParameterTypes();
+
+ if(params.length == 1) {
+ applyConfigParam(configParamAnnotation, method, params[0], instance, config);
+ } else {
+ throw new ConfigurationException("Method '" + getLongMemberName(method) + "' defines a @ConfigParam, yet it specifies more than a single paramater.");
+ }
+ }
+ }
+ }
+
+ private static <U> void applyConfigParam(ConfigProperty configParam, Member member, Class type, U instance, ConfigTree config) throws ConfigurationException {
+ String name = configParam.name();
+ String paramValue;
+
+ // Work out the property name, if not specified via the annotation....
+ if(AnnotationUtil.NULL_STRING.equals(name)) {
+ // "name" not defined. Use the field/method name...
+ if(member instanceof Method) {
+ name = getPropertyName((Method)member);
+ if(name == null) {
+ throw new ConfigurationException("Unable to determine the property name associated with '" +
+ getLongMemberName(member)+ "'. " +
+ "Setter methods that specify the @ConfigParam annotation " +
+ "must either follow the Javabean naming convention ('setX' for propert 'x'), or specify the " +
+ "propery name via the 'name' parameter on the @ConfigParam annotation.");
+ }
+ } else {
+ name = member.getName();
+ }
+ }
+ paramValue = config.getAttribute(name);
+
+ if(paramValue == null) {
+ paramValue = configParam.defaultVal();
+ if(AnnotationUtil.NULL_STRING.equals(paramValue)) {
+ // A null default was assigned...
+ String[] choices = configParam.choice();
+ assertValidChoice(choices, name, AnnotationUtil.NULL_STRING);
+ setMember(member, instance, null);
+ return;
+ } else if(AnnotationUtil.UNASSIGNED.equals(paramValue)) {
+ // No default was assigned...
+ paramValue = null;
+ }
+ }
+
+ if(paramValue != null) {
+ String[] choices = configParam.choice();
+
+ assertValidChoice(choices, name, paramValue);
+
+ DataDecoder decoder = DataDecoder.Factory.create(type);
+ if(decoder == null) {
+ throw new ConfigurationException("Class member '" + getLongMemberName(member) + "' is annotated with the @ConfigParam annotation. Cannot find a DataDecoder from member type '" + type + "'. Define as a String and manually decode in an @Initialize method.");
+ }
+
+ try {
+ setMember(member, instance, decoder.decode(paramValue));
+ } catch (DataDecodeException e) {
+ throw new ConfigurationException("Failed to set property configuration value on '" + getLongMemberName(member) + "'.", e);
+ }
+ } else if(configParam.use() == ConfigProperty.Use.REQUIRED) {
+ throw new ConfigurationException("Property '" + name + "' not specified on configuration:\n" + config);
+ }
+ }
+
+ private static void assertValidChoice(String[] choices, String name, String paramValue) throws ConfigurationException {
+ if(choices == null || choices.length == 0) {
+ throw new RuntimeException("Unexpected annotation default choice value. Should not be null or empty. Code may have changed incompatibly.");
+ } else if(choices.length == 1 && AnnotationUtil.NULL_STRING.equals(choices[0])) {
+ // A choice wasn't specified on the paramater config.
+ return;
+ } else {
+ // A choice was specified. Check it against the value...
+ for (String choice : choices) {
+ if(paramValue.equals(choice)) {
+ return;
+ }
+ }
+ }
+
+ throw new ConfigurationException("Value '" + paramValue + "' for property '" + name + "' is invalid. Valid choices for this property are: " + Arrays.asList(choices));
+ }
+
+ private static String getLongMemberName(Member field) {
+ return field.getDeclaringClass().getName() + "#" + field.getName();
+ }
+
+ private static <U> void setMember(Member member, U instance, Object value) throws ConfigurationException {
+ try {
+ if(member instanceof Field) {
+ ClassUtil.setField((Field)member, instance, value);
+ } else {
+ try {
+ setMethod((Method)member, instance, value);
+ } catch (InvocationTargetException e) {
+ throw new ConfigurationException("Failed to set property configuration value on '" + getLongMemberName(member) + "'.", e.getTargetException());
+ }
+ }
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Failed to set property configuration value on '" + getLongMemberName(member) + "'.", e);
+ }
+ }
+
+ private static <U> void setMethod(Method method, U instance, Object value) throws IllegalAccessException, InvocationTargetException {
+ method.invoke(instance, value);
+ }
+
+ public static <U> void initialise(U instance, ConfigTree config) throws ActionLifecycleException {
+ try {
+ checkPropertiesConfigured(instance.getClass(), instance);
+ } catch (ConfigurationException e) {
+ throw new ActionLifecycleException("Cannot initialize object instance because the objects properties have not been configured.", e);
+ }
+ invoke(instance, Initialize.class, config);
+ }
+
+ public static <U> void destroy(U instance) throws ActionLifecycleException {
+ invoke(instance, Destroy.class, null);
+ }
+
+ private static <U> void invoke(U instance, Class<? extends Annotation> annotation, ConfigTree config) throws ActionLifecycleException {
+ Method[] methods = instance.getClass().getMethods();
+
+ for (Method method : methods) {
+ if(method.getAnnotation(annotation) != null) {
+ Object[] args = null;
+
+ if(method.getParameterTypes().length == 0) {
+ // Nothing
+ } else if(method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == ConfigTree.class && config != null) {
+ // Pass the configTree
+ args = new Object[] {config};
+ } else {
+ logger.warn("Method '" + getLongMemberName(method) + "' defines an @" + annotation.getSimpleName() + " annotation on a paramaterized method. This is not allowed!");
+ }
+
+ try {
+ method.invoke(instance, args);
+ } catch (IllegalAccessException e) {
+ throw new ActionLifecycleException("Error invoking @" + annotation.getSimpleName() + " method '" + method.getName() + "' on class '" + instance.getClass().getName() + "'.", e);
+ } catch (InvocationTargetException e) {
+ Throwable targetException = e.getTargetException();
+ if(targetException instanceof ActionLifecycleException) {
+ throw (ActionLifecycleException) targetException;
+ }
+ throw new ActionLifecycleException("Error invoking @" + annotation.getSimpleName() + " method '" + method.getName() + "' on class '" + instance.getClass().getName() + "'.", targetException);
+ }
+ }
+ }
+ }
+
+ private static String getPropertyName(Method method) {
+ if(!method.getName().startsWith("set")) {
+ return null;
+ }
+
+ StringBuffer methodName = new StringBuffer(method.getName());
+
+ if(methodName.length() < 4) {
+ return null;
+ }
+
+ methodName.delete(0, 3);
+ methodName.setCharAt(0, Character.toLowerCase(methodName.charAt(0)));
+
+ return methodName.toString();
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/configure/Configurator.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/http/HttpRequest.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/http/HttpRequest.java 2010-05-12 19:31:20 UTC (rev 32846)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/http/HttpRequest.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -35,7 +35,7 @@
public class HttpRequest implements Serializable {
/** Request information key in esb message properties */
- private static final String REQUEST_KEY = HttpRequest.class.getName() + "#request";
+ public static final String REQUEST_KEY = "org.jboss.soa.esb.http.HttpRequest#request";
private String authType;
private String characterEncoding;
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Destroy.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Destroy.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Destroy.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.lifecycle.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Destroy lifecycle method annotation.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface Destroy {
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Destroy.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Initialize.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Initialize.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Initialize.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.lifecycle.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Initialize lifecycle method annotation.
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+ at Documented
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD})
+public @interface Initialize {
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/lifecycle/annotation/Initialize.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java 2010-05-12 19:31:20 UTC (rev 32846)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -305,9 +305,23 @@
processor = new OverriddenActionLifecycleProcessor(
actionConfig, currentLifecycle);
}
+ else if (BeanContainerAction.isAnnotatedActionClass(actionClass))
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Using BeanContainerAction for Annotated Action processor for " + actionClassTag);
+ }
+ try {
+ processor = new BeanContainerAction(actionClass.newInstance(), actionConfig);
+ } catch (InstantiationException e) {
+ throw new ConfigurationException("Failed to create an instance of Annotated ESB Action class '" + actionClass.getName() + "'. Class must contain a default public constructor.", e);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Failed to create an instance of Annotated ESB Action class '" + actionClass.getName() + "'. Class must contain a default public constructor.", e);
+ }
+ }
else
{
- LOGGER.warn("Action class " + actionClassTag + " does not implement the ActionLifecycle interface");
+ LOGGER.warn("Action class " + actionClassTag + " does not: a) implement the ActionLifecycle interface, or b) have any public method annotated with the @ProcessMethod annotation.");
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Using overridden actions processor for " + actionClassTag);
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/BeanContainerAction.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/BeanContainerAction.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/BeanContainerAction.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,429 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.listeners.message;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.annotation.AttachmentParam;
+import org.jboss.soa.esb.actions.annotation.BodyParam;
+import org.jboss.soa.esb.actions.annotation.OnExceptionMethod;
+import org.jboss.soa.esb.actions.annotation.OnSuccessMethod;
+import org.jboss.soa.esb.actions.annotation.ProcessMethod;
+import org.jboss.soa.esb.actions.annotation.PropertyParam;
+import org.jboss.soa.esb.configure.AnnotationUtil;
+import org.jboss.soa.esb.configure.Configurator;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.message.Attachment;
+import org.jboss.soa.esb.message.Body;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.MessagePayloadProxy;
+import org.jboss.soa.esb.message.Properties;
+
+/**
+ * Bean Action Container.
+ * <p/>
+ * Container Action class for @ProcessMethod annotated bean action.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class BeanContainerAction extends AbstractActionPipelineProcessor {
+
+ private final static Logger logger = Logger.getLogger(BeanContainerAction.class);
+
+ private String actionName;
+ private Object bean;
+ private ConfigTree configTree;
+ private MessagePayloadProxy payloadProxy;
+ private Method processMethod;
+ private ParamResolver[] paramResolvers;
+ private Map<String, Method> onSuccessMethods;
+ private Map<String, Method> onExceptionMethods;
+
+ public BeanContainerAction(Object bean, ConfigTree configTree) throws ConfigurationException {
+ AssertArgument.isNotNull(bean, "bean");
+ AssertArgument.isNotNull(configTree, "configTree");
+
+ actionName = configTree.getAttribute(ListenerTagNames.ACTION_ELEMENT_TAG);
+
+ this.bean = bean;
+ this.configTree = configTree;
+
+ payloadProxy = new MessagePayloadProxy(configTree);
+
+ Map<String, Method> processMethods = getAnnotatedMethods(bean.getClass(), ProcessMethod.class);
+ if(processMethods.isEmpty()) {
+ throw new IllegalArgumentException("Invalid Bean Action type '" + bean.getClass().getName() + "'. An Action bean must contain at least one public method annotated with the @ProcessMethod annotation.");
+ }
+
+ if(processMethods.size() == 1) {
+ processMethod = processMethods.values().iterator().next();
+ } else {
+ String processMethodName = configTree.getAttribute(ListenerTagNames.PROCESS_METHOD_TAG);
+
+ if(processMethodName == null) {
+ throw new ConfigurationException("Invalid configuration for Bean Action '" + actionName + "' (bean type'" + bean.getClass().getName() + "'). Bean contain 1+ public methods annotated with the @ProcessMethod annotation. The <action> '" + ListenerTagNames.PROCESS_METHOD_TAG + "' attribute must be specified.");
+ } else if (!processMethods.containsKey(processMethodName)) {
+ throw new ConfigurationException("Invalid configuration for Bean Action '" + actionName + "' (bean type'" + bean.getClass().getName() + "'). Bean does not contain a public method named '" + processMethodName + "', annotated with the @ProcessMethod annotation.");
+ }
+
+ processMethod = processMethods.get(processMethodName);
+ }
+
+ Class<?>[] args = processMethod.getParameterTypes();
+ Annotation[][] paramAnnotations = processMethod.getParameterAnnotations();
+
+ paramResolvers = new ParamResolver[args.length];
+ for(int i = 0; i < args.length; i++) {
+ BodyParam bodyParam = findAnnotation(BodyParam.class, paramAnnotations[i]);
+ PropertyParam propertyParam = findAnnotation(PropertyParam.class, paramAnnotations[i]);
+ AttachmentParam attachmentParam = findAnnotation(AttachmentParam.class, paramAnnotations[i]);
+ int annotationCount = 0;
+
+ if(bodyParam != null) {
+ annotationCount++;
+ }
+ if(propertyParam != null) {
+ annotationCount++;
+ }
+ if(attachmentParam != null) {
+ annotationCount++;
+ }
+
+ if(annotationCount == 0) {
+ paramResolvers[i] = new CascadingParamResolver(args[i]);
+ } else if(annotationCount == 1) {
+ if(bodyParam != null) {
+ paramResolvers[i] = new BodyResolver(args[i], bodyParam);
+ } else if(propertyParam != null) {
+ paramResolvers[i] = new PropertyResolver(args[i], propertyParam);
+ } else if(attachmentParam != null) {
+ paramResolvers[i] = new AttachmentResolver(args[i], attachmentParam);
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid Bean Action type '" + bean.getClass().getName() + "'. The @ProcessMethod annotated method '" + processMethod.getName() + "' contains an argument that conflicting ParamResolver annotation.");
+ }
+ }
+
+ onSuccessMethods = getAnnotatedMethods(bean.getClass(), OnSuccessMethod.class);
+ onExceptionMethods = getAnnotatedMethods(bean.getClass(), OnExceptionMethod.class);
+
+ Configurator.configure(bean, configTree);
+ }
+
+ private <T extends Annotation> T findAnnotation(Class<T> annotation, Annotation[] annotations) {
+ for(Annotation annotationEntry : annotations) {
+ if(annotation.isInstance(annotationEntry)) {
+ return annotation.cast(annotationEntry);
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.actions.AbstractActionLifecycle#initialise()
+ */
+ @Override
+ public void initialise() throws ActionLifecycleException {
+ Configurator.initialise(bean, configTree);
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.actions.ActionPipelineProcessor#process(org.jboss.soa.esb.message.Message)
+ */
+ public Message process(Message message) throws ActionProcessingException {
+ Object processResult = null;
+
+ try {
+ Object[] params = new Object[paramResolvers.length];
+
+ for(int i = 0; i < paramResolvers.length; i++) {
+ try {
+ params[i] = paramResolvers[i].getParam(message);
+ } catch (MessageDeliverException e) {
+ throw new ActionProcessingException("Error resolving method parameter from ESB message.", e);
+ }
+ }
+
+ processResult = processMethod.invoke(bean, params);
+ } catch (IllegalArgumentException e) {
+ throw new ActionProcessingException("Bean Action '" + actionName + "' exception.", e);
+ } catch (IllegalAccessException e) {
+ throw new ActionProcessingException("Bean Action '" + actionName + "' exception.", e);
+ } catch (InvocationTargetException e) {
+ Throwable targetException = e.getTargetException();
+ if(targetException instanceof ActionProcessingException) {
+ throw (ActionProcessingException) targetException;
+ } else {
+ throw new ActionProcessingException("Bean Action '" + actionName + "' exception.", targetException);
+ }
+ }
+
+ if(processResult instanceof Message) {
+ return (Message) processResult;
+ } else if(processResult != null) {
+ try {
+ payloadProxy.setPayload(message, processResult);
+ } catch (MessageDeliverException e) {
+ throw new ActionProcessingException("Error injecting 'out' payload into ESB message.", e);
+ }
+ }
+
+ return message;
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.actions.AbstractActionPipelineProcessor#processSuccess(org.jboss.soa.esb.message.Message)
+ */
+ @Override
+ public void processSuccess(Message message) {
+ if(!onSuccessMethods.isEmpty()) {
+ for(Method method : onSuccessMethods.values()) {
+ Class<?>[] args = method.getParameterTypes();
+ try {
+ if(args.length == 0) {
+ method.invoke(bean, new Object[] {});
+ } else if(args.length == 1 && args[0] == Message.class) {
+ method.invoke(bean, new Object[] {message});
+ } else {
+ logger.debug("@OnSuccessMethod '"+ method.getName() + "' has too many arguments, or contains the wrong combination of args [" + Arrays.asList(args) + "].");
+ }
+ } catch (IllegalArgumentException e) {
+ logger.error("Exception while invoking @OnSuccessMethod '"+ method.getName() + "'.", e);
+ } catch (IllegalAccessException e) {
+ logger.error("Exception while invoking @OnSuccessMethod '"+ method.getName() + "'.", e);
+ } catch (InvocationTargetException e) {
+ logger.error("Exception while invoking @OnSuccessMethod '"+ method.getName() + "'.", e.getTargetException());
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.actions.AbstractActionPipelineProcessor#processException(org.jboss.soa.esb.message.Message, java.lang.Throwable)
+ */
+ @Override
+ public void processException(Message message, Throwable th) {
+ if(!onExceptionMethods.isEmpty()) {
+ for(Method method : onExceptionMethods.values()) {
+ Class<?>[] args = method.getParameterTypes();
+ try {
+ if(args.length == 0) {
+ method.invoke(bean, new Object[] {});
+ } else if(args.length == 1 && args[0] == Message.class) {
+ method.invoke(bean, new Object[] {message});
+ } else if(args.length == 2 && args[0] == Message.class && args[1] == Throwable.class) {
+ method.invoke(bean, new Object[] {message, th});
+ } else {
+ logger.debug("@OnExceptionMethod '"+ method.getName() + "' has too many arguments, or contains the wrong combination of args [" + Arrays.asList(args) + "].");
+ }
+ } catch (IllegalArgumentException e) {
+ logger.error("Exception while invoking @OnExceptionMethod '"+ method.getName() + "'.", e);
+ } catch (IllegalAccessException e) {
+ logger.error("Exception while invoking @OnExceptionMethod '"+ method.getName() + "'.", e);
+ } catch (InvocationTargetException e) {
+ logger.error("Exception while invoking @OnExceptionMethod '"+ method.getName() + "'.", e.getTargetException());
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.soa.esb.actions.AbstractActionLifecycle#destroy()
+ */
+ @Override
+ public void destroy() throws ActionLifecycleException {
+ Configurator.destroy(bean);
+ }
+
+ public static boolean isAnnotatedActionClass(Class<?> runtimeClass) {
+ // It's an Action bean if it has one or more @ProcessMethod annotated methods...
+ return (!getAnnotatedMethods(runtimeClass, ProcessMethod.class).isEmpty());
+ }
+
+ private static Map<String, Method> getAnnotatedMethods(Class<?> runtimeClass, Class<? extends Annotation> annotation) {
+ AssertArgument.isNotNull(runtimeClass, "runtimeClass");
+
+ Method[] publicMethods = runtimeClass.getMethods();
+ Map<String, Method> processMethods = new LinkedHashMap<String, Method>();
+
+ for(Method method : publicMethods) {
+ if(method.isAnnotationPresent(annotation)) {
+ processMethods.put(method.getName(), method);
+ }
+ }
+
+ return processMethods;
+ }
+
+ private interface ParamResolver {
+ Object getParam(Message message) throws MessageDeliverException;
+ }
+
+ private class CascadingParamResolver implements ParamResolver {
+
+ private Class<?> paramType;
+ private BodyResolver bodyResolver;
+ private PropertyResolver propertyResolver;
+ private AttachmentResolver attachmentResolver;
+
+ private CascadingParamResolver(Class<?> paramType) {
+ this.paramType = paramType;
+ bodyResolver = new BodyResolver(paramType, null);
+ propertyResolver = new PropertyResolver(paramType, null);
+ attachmentResolver = new AttachmentResolver(paramType, null);
+ }
+
+ public Object getParam(Message message) throws MessageDeliverException {
+ if(Message.class.isAssignableFrom(paramType)) {
+ return message;
+ }
+
+ Object payload = payloadProxy.getPayload(message);
+
+ if(paramType.isInstance(payload)) {
+ return payload;
+ }
+
+ // Now lets cascade, trying the different message parts to find the first match....
+ Object param = bodyResolver.getParam(message);
+ if(param == null) {
+ param = propertyResolver.getParam(message);
+ if(param == null) {
+ param = attachmentResolver.getParam(message);
+ }
+ }
+
+ return param;
+ }
+ }
+
+ private class PropertyResolver implements ParamResolver {
+
+ private Class<?> paramType;
+ private PropertyParam property;
+
+ private PropertyResolver(Class<?> paramType, PropertyParam property) {
+ this.paramType = paramType;
+ this.property = property;
+ }
+
+ public Object getParam(Message message) throws MessageDeliverException {
+ Properties properties = message.getProperties();
+
+ String propertyName = AnnotationUtil.getPropertyName(property);
+ if(propertyName != null) {
+ Object param = properties.getProperty(propertyName);
+ if(param != null && !paramType.isInstance(param)) {
+ throw new MessageDeliverException("Named property '" + propertyName + "' exists on ESB message but is not of type '" + paramType.getName() + "'.");
+ }
+ return param;
+ } else {
+ for(String propertyNameOnMessage : properties.getNames()) {
+ Object param = properties.getProperty(propertyNameOnMessage);
+ if(param != null && paramType.isInstance(param)) {
+ return param;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ private class BodyResolver implements ParamResolver {
+
+ private Class<?> paramType;
+ private BodyParam bodyParam;
+
+ private BodyResolver(Class<?> paramType, BodyParam bodyParam) {
+ this.paramType = paramType;
+ this.bodyParam = bodyParam;
+ }
+
+ public Object getParam(Message message) throws MessageDeliverException {
+ Body body = message.getBody();
+
+ String bodyPartName = AnnotationUtil.getBodyName(bodyParam);
+ if(bodyPartName != null) {
+ Object param = body.get(bodyPartName);
+ if(param != null && !paramType.isInstance(param)) {
+ throw new MessageDeliverException("Named Body part '" + bodyPartName + "' exists on ESB message but is not of type '" + paramType.getName() + "'.");
+ }
+ return param;
+ } else {
+ for(String bodyPartNameOnMessage : body.getNames()) {
+ Object param = body.get(bodyPartNameOnMessage);
+ if(param != null && paramType.isInstance(param)) {
+ return param;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ private class AttachmentResolver implements ParamResolver {
+
+ private Class<?> paramType;
+ private AttachmentParam attachmentParam;
+
+ private AttachmentResolver(Class<?> paramType, AttachmentParam attachmentParam) {
+ this.paramType = paramType;
+ this.attachmentParam = attachmentParam;
+ }
+
+ public Object getParam(Message message) throws MessageDeliverException {
+ Attachment attachment = message.getAttachment();
+
+ String attachPartName = AnnotationUtil.getAttachmentName(attachmentParam);
+ if(attachPartName != null) {
+ Object param = attachment.get(attachPartName);
+ if(param != null && !paramType.isInstance(param)) {
+ throw new MessageDeliverException("Named Attachment part '" + attachPartName + "' exists on ESB message but is not of type '" + paramType.getName() + "'.");
+ }
+ return param;
+ } else {
+ for(String attachPartNameOnMessage : attachment.getNames()) {
+ Object param = attachment.get(attachPartNameOnMessage);
+ if(param != null && paramType.isInstance(param)) {
+ return param;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/src/org/jboss/soa/esb/listeners/message/BeanContainerAction.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/AlphaChar.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/AlphaChar.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/AlphaChar.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,30 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.configure;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public enum AlphaChar {
+ A, B, C
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/AlphaChar.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycle.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycle.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycle.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.configure;
+
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.annotation.Destroy;
+import org.jboss.soa.esb.lifecycle.annotation.Initialize;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class ComponentWithLifecycle extends ComponentWithNoLifecycle {
+
+ public boolean compInit1Called;
+ public ConfigTree configTree;
+ public boolean compDestroyCalled;
+ public ActionLifecycleException lifecycleException;
+
+ @Initialize
+ public void compInit1() throws ActionLifecycleException {
+ compInit1Called = true;
+ if(lifecycleException != null) {
+ throw lifecycleException;
+ }
+ }
+
+ @Initialize
+ public void compInit2(ConfigTree configTree) {
+ this.configTree = configTree;
+ }
+
+ @Destroy
+ public void compDestroy() {
+ compDestroyCalled = true;
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycle.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycleAndSuperLifecycle.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycleAndSuperLifecycle.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycleAndSuperLifecycle.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.configure;
+
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.annotation.Destroy;
+import org.jboss.soa.esb.lifecycle.annotation.Initialize;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class ComponentWithLifecycleAndSuperLifecycle extends ComponentWithLifecycle {
+
+ public boolean compInit3Called;
+ public ConfigTree configTree4;
+
+ @Initialize
+ public void compInit3() {
+ compInit3Called = true;
+ }
+
+ @Initialize
+ public void compInit4(ConfigTree configTree) {
+ this.configTree4 = configTree;
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithLifecycleAndSuperLifecycle.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithNoLifecycle.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithNoLifecycle.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithNoLifecycle.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.configure;
+
+import org.jboss.soa.esb.configure.ConfigProperty.Use;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class ComponentWithNoLifecycle {
+
+ @ConfigProperty
+ private int intVal1;
+
+ @ConfigProperty(defaultVal = "2")
+ private int intVal2;
+
+ @ConfigProperty(use = Use.OPTIONAL)
+ private Integer intVal3;
+
+ @ConfigProperty(choice = {"1", "2"})
+ private String enumVal1;
+
+ // Config'd by setter...
+ private AlphaChar enumVal2;
+
+ // Config'd by setter...
+ private Class classVal1;
+
+ /**
+ * @return the intVal1
+ */
+ public int getIntVal1() {
+ return intVal1;
+ }
+
+ /**
+ * @return the intVal2
+ */
+ public int getIntVal2() {
+ return intVal2;
+ }
+
+ /**
+ * @return the intVal3
+ */
+ public Integer getIntVal3() {
+ return intVal3;
+ }
+
+ /**
+ * @return the enumVal2
+ */
+ public String getEnumVal1() {
+ return enumVal1;
+ }
+
+ /**
+ * @return the enumVal2
+ */
+ public AlphaChar getEnumVal2() {
+ return enumVal2;
+ }
+
+ /**
+ * @param enumVal2 the enumVal2 to set
+ */
+ @ConfigProperty
+ public void setEnumVal2(AlphaChar enumVal2) {
+ this.enumVal2 = enumVal2;
+ }
+
+ /**
+ * @return the classVal1
+ */
+ public Class getClassVal1() {
+ return classVal1;
+ }
+
+ /**
+ * @param classVal1 the classVal1 to set
+ */
+ @ConfigProperty
+ public void setClassVal1(Class classVal1) {
+ this.classVal1 = classVal1;
+ }
+
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ComponentWithNoLifecycle.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ConfiguratorUnitTest.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ConfiguratorUnitTest.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ConfiguratorUnitTest.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.configure;
+
+import java.util.List;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class ConfiguratorUnitTest extends TestCase {
+
+ public void test_config_no_lifecycle_no_errors() throws ConfigurationException {
+ ConfigTree configTree = createConfig();
+
+ ComponentWithNoLifecycle component = new ComponentWithNoLifecycle();
+
+ Configurator.configure(component, configTree);
+
+ assertComponentConfigured(component);
+ }
+
+ public void test_config_no_lifecycle_with_errors_01() throws ConfigurationException {
+ ConfigTree configTree = createConfig();
+
+ // intVal1 not configured
+ configTree.setAttribute("intVal1", null);
+
+ assertFailure(configTree, "Property 'intVal1' not specified on configuration");
+ }
+
+ public void test_config_no_lifecycle_with_errors_02() throws ConfigurationException {
+ ConfigTree configTree = createConfig();
+
+ // enumVal1 set to an invalid choice...
+ configTree.setAttribute("enumVal1", "3");
+
+ assertFailure(configTree, "Value '3' for property 'enumVal1' is invalid. Valid choices for this property are: [1, 2]");
+ }
+
+ public void test_config_no_lifecycle_with_errors_03() throws ConfigurationException {
+ ConfigTree configTree = createConfig();
+
+ // enumVal2 set to an invalid enum constant value...
+ configTree.setAttribute("enumVal2", "X");
+
+ assertFailure(configTree, "Failed to set property configuration value on 'org.jboss.soa.esb.configure.ComponentWithNoLifecycle#setEnumVal2'");
+ }
+
+ public void test_config_with_lifecycle_but_no_lifecycle_methods() throws ConfigurationException, ActionLifecycleException {
+ ConfigTree configTree = createConfig();
+
+ ComponentWithNoLifecycle component = new ComponentWithNoLifecycle();
+
+ Configurator.configure(component, configTree);
+
+ Configurator.initialise(component, configTree);
+ Configurator.destroy(component);
+ }
+
+ public void test_config_with_lifecycle_and_lifecycle_methods() throws ConfigurationException, ActionLifecycleException {
+ ConfigTree configTree = createConfig();
+
+ ComponentWithLifecycle component = new ComponentWithLifecycle();
+
+ Configurator.configure(component, configTree);
+
+ Configurator.initialise(component, configTree);
+ Configurator.destroy(component);
+
+ assertTrue(component.compInit1Called);
+ assertNotNull(component.configTree);
+ assertTrue(component.compDestroyCalled);
+ }
+
+ public void test_config_with_lifecycle_and_super_lifecycle_methods() throws ConfigurationException, ActionLifecycleException {
+ ConfigTree configTree = createConfig();
+
+ ComponentWithLifecycleAndSuperLifecycle component = new ComponentWithLifecycleAndSuperLifecycle();
+
+ Configurator.configure(component, configTree);
+
+ Configurator.initialise(component, configTree);
+ Configurator.destroy(component);
+
+ assertTrue(component.compInit1Called);
+ assertNotNull(component.configTree);
+ assertTrue(component.compDestroyCalled);
+ assertTrue(component.compInit3Called);
+ assertNotNull(component.configTree4);
+ }
+
+ public void test_config_with_lifecycle_and_lifecycle_exception() throws ConfigurationException, ActionLifecycleException {
+ ConfigTree configTree = createConfig();
+
+ ComponentWithLifecycle component = new ComponentWithLifecycle();
+
+ // Set the exception...
+ component.lifecycleException = new ActionLifecycleException("Xception");
+
+ Configurator.configure(component, configTree);
+
+ try {
+ Configurator.initialise(component, configTree);
+ fail("Expected ActionLifecycleException.");
+ } catch(ActionLifecycleException e) {
+ assertEquals(component.lifecycleException, e);
+ }
+ }
+
+ private ConfigTree createConfig() {
+ ConfigTree configTree = new ConfigTree("config");
+
+ configTree.setAttribute("intVal1", "1");
+ configTree.setAttribute("enumVal1", "1");
+ configTree.setAttribute("enumVal2", "B");
+ configTree.setAttribute("classVal1", List.class.getName());
+
+ return configTree;
+ }
+
+ private void assertComponentConfigured(ComponentWithNoLifecycle component) {
+ assertEquals(1, component.getIntVal1());
+ assertEquals(2, component.getIntVal2());
+ assertEquals(null, component.getIntVal3());
+ assertEquals("1", component.getEnumVal1());
+ assertEquals(AlphaChar.B, component.getEnumVal2());
+ assertEquals(List.class, component.getClassVal1());
+ }
+
+ private void assertFailure(ConfigTree configTree, String message) {
+ try {
+ Configurator.configure(new ComponentWithNoLifecycle(), configTree);
+ fail("Expected ConfigurationException");
+ } catch (ConfigurationException e) {
+// e.printStackTrace();
+ if(!e.getMessage().startsWith(message)) {
+ fail("Expected exception starting with: [" + message+ "]. Actual: [" + e.getMessage() + "]");
+ }
+ }
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/configure/ConfiguratorUnitTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java 2010-05-12 19:31:20 UTC (rev 32846)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -640,10 +640,10 @@
checkOrder(MockActionInfo.getDestroyList()) ;
}
- public static void addAction(final ConfigTree configTree, final String actionName) {
- addAction(configTree, actionName, null, null, null);
+ public static ConfigTree addAction(final ConfigTree configTree, final String actionName) {
+ return addAction(configTree, actionName, null, null, null);
}
- public static void addAction(final ConfigTree configTree, final String actionName,
+ public static ConfigTree addAction(final ConfigTree configTree, final String actionName,
final String processOverride, final String successOverride,
final String exceptionOverride)
{
@@ -661,6 +661,8 @@
{
actionChild.setAttribute(ListenerTagNames.EXCEPTION_METHOD_TAG, exceptionOverride) ;
}
+
+ return actionChild;
}
private void checkOrder(final Integer[] list, int ... values)
Added: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/BeanContainerActionUnitTest.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/BeanContainerActionUnitTest.java (rev 0)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/BeanContainerActionUnitTest.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -0,0 +1,364 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.soa.esb.listeners.message;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.annotation.AttachmentParam;
+import org.jboss.soa.esb.actions.annotation.BodyParam;
+import org.jboss.soa.esb.actions.annotation.OnExceptionMethod;
+import org.jboss.soa.esb.actions.annotation.OnSuccessMethod;
+import org.jboss.soa.esb.actions.annotation.ProcessMethod;
+import org.jboss.soa.esb.actions.annotation.PropertyParam;
+import org.jboss.soa.esb.configure.ConfigProperty;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.lifecycle.annotation.Destroy;
+import org.jboss.soa.esb.lifecycle.annotation.Initialize;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class BeanContainerActionUnitTest extends TestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ ActionWithLifecycleWithProperty.throwInitException = false;
+ ActionWithLifecycleWithProperty.throwProcessException = false;
+ }
+
+ public void test_isActionBean() {
+ assertFalse(BeanContainerAction.isAnnotatedActionClass(EmptyBean.class));
+ assertTrue(BeanContainerAction.isAnnotatedActionClass(ActionWithoutLifecycle.class));
+ }
+
+ public void test_ActionNoLifecycle() throws ConfigurationException, ActionProcessingException, ActionLifecycleException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionWithoutLifecycleWithProperty action = new ActionWithoutLifecycleWithProperty();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ containerAction.initialise();
+ containerAction.process(message);
+ containerAction.processSuccess(message);
+ containerAction.processException(message, new Exception());
+ containerAction.destroy();
+
+ assertNotNull(action.targetFile);
+ assertEquals(action.targetFile, message.getBody().get());
+ }
+
+ public void test_ActionWithLifecycle_no_exception() throws ConfigurationException, ActionProcessingException, ActionLifecycleException {
+ ConfigTree pipelineConfig = new ConfigTree("pipline");
+
+ ConfigTree actionConfigTree = ActionProcessingPipelineUnitTest.addAction(pipelineConfig, ActionWithLifecycleWithProperty.class.getName());
+
+ ActionProcessingPipeline pipeline = new ActionProcessingPipeline(pipelineConfig);
+ pipeline.initialise();
+
+ try {
+ Message message = MessageFactory.getInstance().getMessage();
+ pipeline.process(message);
+ } finally {
+ pipeline.destroy();
+ }
+
+ assertTrue(ActionWithLifecycleWithProperty.init1Called);
+ assertTrue(ActionWithLifecycleWithProperty.init2Called);
+ assertEquals(actionConfigTree, ActionWithLifecycleWithProperty.config);
+ assertTrue(ActionWithLifecycleWithProperty.processCalled);
+ assertTrue(ActionWithLifecycleWithProperty.onsuccess1Called);
+ assertTrue(ActionWithLifecycleWithProperty.onsuccess2Called);
+ assertFalse(ActionWithLifecycleWithProperty.onexception1Called);
+ assertFalse(ActionWithLifecycleWithProperty.onexception2Called);
+ assertFalse(ActionWithLifecycleWithProperty.onexception3Called);
+ assertTrue(ActionWithLifecycleWithProperty.destroyCalled);
+ }
+
+ public void test_ActionWithLifecycle_init_exception() throws ConfigurationException, ActionProcessingException, ActionLifecycleException {
+ ConfigTree pipelineConfig = new ConfigTree("pipline");
+
+ ActionProcessingPipelineUnitTest.addAction(pipelineConfig, ActionWithLifecycleWithProperty.class.getName());
+ ActionWithLifecycleWithProperty.throwInitException = true;
+
+ ActionProcessingPipeline pipeline = new ActionProcessingPipeline(pipelineConfig);
+ try {
+ pipeline.initialise();
+ fail("Expected ConfigurationException");
+ } catch(ConfigurationException e) {
+ assertEquals("Unexpected exception during lifecycle initialisation", e.getMessage());
+ assertEquals("init exception", e.getCause().getMessage());
+ }
+ }
+
+ public void test_ActionWithLifecycle_process_exception() throws ConfigurationException, ActionProcessingException, ActionLifecycleException {
+ ConfigTree pipelineConfig = new ConfigTree("pipline");
+
+ ConfigTree actionConfigTree = ActionProcessingPipelineUnitTest.addAction(pipelineConfig, ActionWithLifecycleWithProperty.class.getName());
+
+ ActionProcessingPipeline pipeline = new ActionProcessingPipeline(pipelineConfig);
+ ActionWithLifecycleWithProperty.throwProcessException = true;
+ pipeline.initialise();
+
+ try {
+ Message message = MessageFactory.getInstance().getMessage();
+ pipeline.process(message);
+ } finally {
+ pipeline.destroy();
+ }
+
+ assertTrue(ActionWithLifecycleWithProperty.init1Called);
+ assertTrue(ActionWithLifecycleWithProperty.init2Called);
+ assertEquals(actionConfigTree, ActionWithLifecycleWithProperty.config);
+ assertTrue(ActionWithLifecycleWithProperty.processCalled);
+ assertFalse(ActionWithLifecycleWithProperty.onsuccess1Called);
+ assertFalse(ActionWithLifecycleWithProperty.onsuccess2Called);
+ assertTrue(ActionWithLifecycleWithProperty.onexception1Called);
+ assertTrue(ActionWithLifecycleWithProperty.onexception2Called);
+ assertTrue(ActionWithLifecycleWithProperty.onexception3Called);
+ assertTrue(ActionWithLifecycleWithProperty.destroyCalled);
+ }
+
+ public void test_paramResolution_01() throws ConfigurationException, ActionProcessingException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionA action = new ActionA();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ message.getBody().add(new PayloadObj("aPay"));
+ containerAction.process(message);
+
+ assertEquals("aPay", message.getBody().get());
+ }
+
+ public void test_paramResolution_02() throws ConfigurationException, ActionProcessingException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionA action = new ActionA();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ message.getBody().add("Not the action arg");
+ message.getBody().add("someother location", new PayloadObj("aPay"));
+ containerAction.process(message);
+
+ assertEquals("aPay", message.getBody().get());
+ }
+
+ public void test_paramResolution_03() throws ConfigurationException, ActionProcessingException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionA action = new ActionA();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ message.getBody().add("Not the action arg");
+ message.getProperties().setProperty("payX", new PayloadObj("aPay"));
+ containerAction.process(message);
+
+ assertEquals("aPay", message.getBody().get());
+ }
+
+ public void test_paramResolution_04() throws ConfigurationException, ActionProcessingException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionA action = new ActionA();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ message.getBody().add("Not the action arg");
+ message.getAttachment().put("payX", new PayloadObj("aPay"));
+ containerAction.process(message);
+
+ assertEquals("aPay", message.getBody().get());
+ }
+
+ public void test_paramResolution_05() throws ConfigurationException, ActionProcessingException {
+ ConfigTree configTree = new ConfigTree("conf");
+ ActionB action = new ActionB();
+
+ configTree.setAttribute("targetFile", "./somefile.xml");
+
+ BeanContainerAction containerAction = new BeanContainerAction(action, configTree);
+ Message message = MessageFactory.getInstance().getMessage();
+
+ message.getBody().add("BodyString");
+ message.getAttachment().put("payX", new PayloadObj("aPay"));
+ containerAction.process(message);
+
+ assertEquals("BodyString-aPay", message.getBody().get());
+ }
+
+ public class EmptyBean {
+ }
+
+ public class ActionWithoutLifecycle {
+ @ProcessMethod
+ public void processMethod(Message m) {
+ }
+ }
+
+ public static class ActionWithoutLifecycleWithProperty {
+ @ConfigProperty
+ private File targetFile;
+
+ @ProcessMethod
+ public void processMethod(Message m) {
+ m.getBody().add(targetFile);
+ }
+ }
+
+ public static class ActionWithLifecycleWithProperty {
+
+ private static boolean throwInitException;
+ private static boolean throwProcessException;
+ private static boolean init1Called;
+ private static boolean init2Called;
+ private static boolean processCalled;
+ private static boolean destroyCalled;
+ private static ConfigTree config;
+ private static boolean onsuccess1Called;
+ private static boolean onsuccess2Called;
+ private static boolean onexception1Called;
+ private static boolean onexception2Called;
+ private static boolean onexception3Called;
+
+ public ActionWithLifecycleWithProperty() {
+ init1Called = false;
+ init2Called = false;
+ processCalled = false;
+ destroyCalled = false;
+ config = null;
+ onsuccess1Called = false;
+ onsuccess2Called = false;
+ onexception1Called = false;
+ onexception2Called = false;
+ onexception3Called = false;
+ }
+
+ @Initialize
+ public void init1() {
+ init1Called = true;
+ }
+
+ @Initialize
+ public void init2(ConfigTree config) throws ActionLifecycleException {
+ this.config = config;
+ init2Called = true;
+ if(throwInitException) {
+ throw new ActionLifecycleException("init exception");
+ }
+ }
+
+ @ProcessMethod
+ public void process(Message m) throws ActionProcessingException {
+ processCalled = true;
+ if(throwProcessException) {
+ throw new ActionProcessingException("process exception");
+ }
+ }
+
+ @OnSuccessMethod
+ public void onSuccess1() {
+ onsuccess1Called = true;
+ }
+
+ @OnSuccessMethod
+ public void onSuccess2(Message message) {
+ assertNotNull("message passed to onSuccess method is null", message);
+ onsuccess2Called = true;
+ }
+
+ @OnExceptionMethod
+ public void onException1() {
+ onexception1Called = true;
+ }
+
+ @OnExceptionMethod
+ public void onException2(Message message) {
+ assertNotNull("message passed to onException method is null", message);
+ onexception2Called = true;
+ }
+
+ @OnExceptionMethod
+ public void onException3(Message message, Throwable th) {
+ assertNotNull("message passed to onException method is null", message);
+ assertNotNull("throwable passed to onException method is null", th);
+ assertTrue(th instanceof ActionProcessingException);
+ assertEquals("process exception", th.getMessage());
+ onexception3Called = true;
+ }
+
+ @Destroy
+ public void destroy() {
+ destroyCalled = true;
+ }
+ }
+
+ public class ActionA {
+ @ProcessMethod
+ public String processA(PayloadObj pay) {
+ return pay.toString();
+ }
+ }
+
+ public class ActionB {
+ @ProcessMethod
+ public String processB(String bodyString, @AttachmentParam PayloadObj pay) {
+ return bodyString + "-" + pay.toString();
+ }
+ }
+
+ public class PayloadObj implements Serializable {
+
+ private String name;
+
+ public PayloadObj(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
Property changes on: labs/jbossesb/workspace/tfennelly/annotated_components/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/BeanContainerActionUnitTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: labs/jbossesb/workspace/tfennelly/annotated_components/product/samples/quickstarts/http_gateway/src/org/jboss/soa/esb/samples/quickstart/httpgateway/MyAction.java
===================================================================
--- labs/jbossesb/workspace/tfennelly/annotated_components/product/samples/quickstarts/http_gateway/src/org/jboss/soa/esb/samples/quickstart/httpgateway/MyAction.java 2010-05-12 19:31:20 UTC (rev 32846)
+++ labs/jbossesb/workspace/tfennelly/annotated_components/product/samples/quickstarts/http_gateway/src/org/jboss/soa/esb/samples/quickstart/httpgateway/MyAction.java 2010-05-12 20:13:01 UTC (rev 32847)
@@ -20,34 +20,34 @@
*/
package org.jboss.soa.esb.samples.quickstart.httpgateway;
-import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
-import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.actions.annotation.BodyParam;
+import org.jboss.soa.esb.actions.annotation.ProcessMethod;
+import org.jboss.soa.esb.actions.annotation.PropertyParam;
import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.lifecycle.annotation.Initialize;
import org.jboss.soa.esb.listeners.ListenerTagNames;
import org.jboss.soa.esb.Service;
import org.jboss.soa.esb.http.HttpRequest;
import com.thoughtworks.xstream.XStream;
-public class MyAction extends AbstractActionPipelineProcessor {
+public class MyAction {
- protected ConfigTree _config;
private Service service;
- public MyAction(ConfigTree config) {
- _config = config;
- service = new Service(_config.getParent().getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG), _config.getParent().getAttribute(ListenerTagNames.SERVICE_NAME_TAG));
+ @Initialize
+ public void init(ConfigTree config) {
+ service = new Service(config.getParent().getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG), config.getParent().getAttribute(ListenerTagNames.SERVICE_NAME_TAG));
}
- public Message process(Message message) throws ActionProcessingException {
+ @ProcessMethod
+ public String printHttpRequestInfo(@BodyParam byte[] httpPayload, @PropertyParam HttpRequest requestInfo ) {
System.out.println("&&&&&&&&&&&&&&&& MyAction &&&&&&&&&&&&&&&&&&&&&");
System.out.println("");
System.out.println("Service: " + service);
System.out.println("");
System.out.println("------------Http Request Info (XStream Encoded)-------------------");
- HttpRequest requestInfo = HttpRequest.getRequest(message);
String requestInfoXML;
XStream xstream = new XStream();
@@ -56,7 +56,7 @@
System.out.println(requestInfoXML);
System.out.println("------------Http Request body -------------------");
- System.out.println(message.getBody().get());
+ System.out.println(httpPayload);
System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
@@ -66,9 +66,6 @@
response.append("------------Http Request Info (XStream Encoded)-------------------\n");
response.append(requestInfoXML);
- message.getBody().add(response.toString());
-
- return message;
-
+ return response.toString();
}
}
More information about the jboss-svn-commits
mailing list