You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by jb...@apache.org on 2011/04/04 12:41:29 UTC

svn commit: r1088548 [5/15] - in /servicemix/smx3/trunk: ./ common/ common/servicemix-components/ common/servicemix-components/src/main/java/org/apache/servicemix/components/activesoap/ common/servicemix-components/src/main/java/org/apache/servicemix/c...

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JBIJMSException.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JBIJMSException.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JBIJMSException.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JBIJMSException.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.JBIException;
+import javax.jms.JMSException;
+
+/**
+ * Thrown when a JMS message is thrown from inside a JMS binding
+ * component for the JBI container
+ *
+ * @version $Revision: 426415 $
+ */
+public class JBIJMSException extends JBIException {
+    public JBIJMSException(JMSException cause) {
+        super(cause);
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInBinding.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInBinding.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInBinding.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInBinding.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.ExchangeStatus;
+import javax.jbi.messaging.InOnly;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.MessageExchangeListener;
+import org.apache.servicemix.components.util.ComponentSupport;
+import org.apache.servicemix.jbi.RuntimeJBIException;
+
+/**
+ * A JMS {@link MessageListener} which sends the inbound JMS message into the JBI container
+ * for processing
+ *
+ * @version $Revision: 487499 $
+ */
+public class JmsInBinding extends ComponentSupport implements MessageListener, MessageExchangeListener {
+    private static final Log log = LogFactory.getLog(JmsInBinding.class);
+
+    private JmsMarshaler marshaler = new JmsMarshaler();
+    private boolean synchronous = false;
+
+    /**
+     * @return the synchronous
+     */
+    public boolean isSynchronous() {
+        return synchronous;
+    }
+
+    /**
+     * @param synchronous the synchronous to set
+     */
+    public void setSynchronous(boolean synchronous) {
+        this.synchronous = synchronous;
+    }
+
+    public JmsMarshaler getMarshaler() {
+        return marshaler;
+    }
+
+    public void setMarshaler(JmsMarshaler marshaler) {
+        this.marshaler = marshaler;
+    }
+
+    public void onMessage(Message jmsMessage) {
+        if (log.isTraceEnabled()) {
+            log.trace("Received: " + jmsMessage);
+        }
+
+        try {
+            InOnly messageExchange = getDeliveryChannel().createExchangeFactory().createInOnlyExchange();
+            NormalizedMessage inMessage = messageExchange.createMessage();
+
+            try {
+                marshaler.toNMS(inMessage, jmsMessage);
+
+                messageExchange.setInMessage(inMessage);
+                if (synchronous) {
+                    getDeliveryChannel().sendSync(messageExchange);
+                } else {
+                    getDeliveryChannel().send(messageExchange);
+                }
+            }
+            catch (JMSException e) {
+                messageExchange.setError(e);
+                messageExchange.setStatus(ExchangeStatus.ERROR);
+            }
+        }
+        catch (JBIException e) {
+            throw new RuntimeJBIException(e);
+        }
+    }
+
+    public void onMessageExchange(MessageExchange exchange) throws MessagingException {
+        // Do nothing as we only send in-only
+        // but this ensure that messages are not queued in the DeliveryChannel
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInUsingJCABinding.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInUsingJCABinding.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInUsingJCABinding.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsInUsingJCABinding.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.JBIException;
+import javax.resource.spi.ActivationSpec;
+import javax.transaction.TransactionManager;
+
+import org.jencks.JCAConnector;
+import org.jencks.JCAContainer;
+import org.jencks.SingletonEndpointFactory;
+import org.springframework.beans.factory.BeanNameAware;
+
+/**
+ * Uses the JCA Container for better inbound subscription.
+ *
+ * @version $Revision: 487499 $
+ */
+public class JmsInUsingJCABinding extends JmsInBinding implements BeanNameAware {
+
+    private JCAContainer jcaContainer;
+    private ActivationSpec activationSpec;
+    private TransactionManager transactionManager;
+    private JCAConnector jcaConnector;
+    private String name;
+
+    protected void init() throws JBIException {
+        if (jcaContainer == null) {
+            throw new IllegalArgumentException("Must specify a jcaContainer property");
+        }
+        if (activationSpec == null) {
+            throw new IllegalArgumentException("Must specify an activationSpec property");
+        }
+        jcaConnector = jcaContainer.addConnector();
+        jcaConnector.setActivationSpec(activationSpec);
+        if (transactionManager == null) {
+        	transactionManager = (TransactionManager) getContext().getTransactionManager();
+        }
+        if (transactionManager != null) {
+            jcaConnector.setTransactionManager(transactionManager);
+        }
+        SingletonEndpointFactory ef = new SingletonEndpointFactory(this, transactionManager);
+        ef.setName(name);
+        jcaConnector.setEndpointFactory(ef);
+        try {
+        	jcaConnector.afterPropertiesSet();
+        } catch (Exception e) {
+        	throw new JBIException("Unable to initialize jca connector", e);
+        }
+        super.init();
+    }
+    
+    public void start() throws JBIException {
+        try {
+            jcaConnector.start();
+        } catch (Exception e) {
+            throw new JBIException("Unable to start jca connector", e);
+        }
+        super.start();
+    }
+    
+    public void stop() throws JBIException {
+        super.stop();
+        try {
+            jcaConnector.destroy();
+        } catch (Exception e) {
+            throw new JBIException("Unable to stop jca connector", e);
+        }
+    }
+
+    public JCAContainer getJcaContainer() {
+        return jcaContainer;
+    }
+
+    public void setJcaContainer(JCAContainer jcaContainer) {
+        this.jcaContainer = jcaContainer;
+    }
+
+    public ActivationSpec getActivationSpec() {
+        return activationSpec;
+    }
+
+    public void setActivationSpec(ActivationSpec activationSpec) {
+        this.activationSpec = activationSpec;
+    }
+
+    public TransactionManager getTransactionManager() {
+        return transactionManager;
+    }
+
+    public void setTransactionManager(TransactionManager transactionManager) {
+        this.transactionManager = transactionManager;
+    }
+
+    public JCAConnector getJcaConnector() {
+        return jcaConnector;
+    }
+
+    public void setBeanName(String name) {
+        this.name = name;
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsMarshaler.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsMarshaler.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsMarshaler.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsMarshaler.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import org.apache.servicemix.jbi.jaxp.SourceMarshaler;
+
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * Marshalls JMS messages into and out of NMS messages
+ *
+ * @version $Revision: 426415 $
+ */
+public class JmsMarshaler {
+    private SourceMarshaler sourceMarshaler;
+    
+    private boolean needJavaIdentifiers;
+
+    public JmsMarshaler() {
+        this(new SourceMarshaler());
+    }
+
+    public JmsMarshaler(SourceMarshaler sourceMarshaler) {
+        this.sourceMarshaler = sourceMarshaler;
+    }
+
+    /**
+     * Marshalls the JMS message into an NMS message
+     *
+     * @throws MessagingException
+     */
+    public void toNMS(NormalizedMessage normalizedMessage, Message message) throws JMSException, MessagingException {
+        addNmsProperties(normalizedMessage, message);
+        if (message instanceof TextMessage) {
+            TextMessage textMessage = (TextMessage) message;
+            Source source = sourceMarshaler.asSource(textMessage.getText());
+            normalizedMessage.setContent(source);
+        }
+
+        // lets add the message to the NMS
+        // Fix SM-178 : the message exchange is not serializable
+        //normalizedMessage.setProperty("org.apache.servicemix.jms.message", message);
+    }
+
+    public Message createMessage(NormalizedMessage normalizedMessage, Session session) throws JMSException, TransformerException {
+        // lets create a text message
+        String xml = messageAsString(normalizedMessage);
+        TextMessage message = session.createTextMessage(xml);
+        addJmsProperties(message, normalizedMessage);
+        return message;
+    }
+
+    // Properties
+    //-------------------------------------------------------------------------
+    public SourceMarshaler getSourceMarshaller() {
+        return sourceMarshaler;
+    }
+
+    public void setSourceMarshaller(SourceMarshaler sourceMarshaler) {
+        this.sourceMarshaler = sourceMarshaler;
+    }
+
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Converts the inbound message to a String that can be sent
+     */
+    protected String messageAsString(NormalizedMessage normalizedMessage) throws TransformerException {
+        return sourceMarshaler.asString(normalizedMessage.getContent());
+    }
+
+    /**
+     * Appends properties on the NMS to the JMS Message
+     */
+    protected void addJmsProperties(Message message, NormalizedMessage normalizedMessage) throws JMSException {
+        for (Iterator iter = normalizedMessage.getPropertyNames().iterator(); iter.hasNext();) {
+            String name = (String) iter.next();
+            Object value = normalizedMessage.getProperty(name);
+            if (shouldIncludeHeader(normalizedMessage, name, value)) {
+                message.setObjectProperty(name, value);
+            }
+        }
+    }
+
+    protected void addNmsProperties(NormalizedMessage message, Message jmsMessage) throws JMSException {
+        Enumeration enumeration = jmsMessage.getPropertyNames();
+        while (enumeration.hasMoreElements()) {
+            String name = (String) enumeration.nextElement();
+            Object value = jmsMessage.getObjectProperty(name);
+            message.setProperty(name, value);
+        }
+    }
+
+    /**
+     * Decides whether or not the given header should be included in the JMS message.
+     * By default this includes all suitable typed values
+     */
+    protected boolean shouldIncludeHeader(NormalizedMessage normalizedMessage, String name, Object value) {
+        return (value instanceof String || value instanceof Number || value instanceof Date) &&
+               (!isNeedJavaIdentifiers() || isJavaIdentifier(name));
+    }
+    
+    private static boolean isJavaIdentifier(String s) {
+        int n = s.length();
+        if (n==0) return false;
+        if (!Character.isJavaIdentifierStart(s.charAt(0)))
+            return false;
+        for (int i = 1; i < n; i++)
+            if (!Character.isJavaIdentifierPart(s.charAt(i)))
+                return false;
+        return true;
+      }
+
+    /**
+     * @return Returns the needJavaIdentifiers.
+     */
+    public boolean isNeedJavaIdentifiers() {
+        return needJavaIdentifiers;
+    }
+
+    /**
+     * @param needJavaIdentifiers The needJavaIdentifiers to set.
+     */
+    public void setNeedJavaIdentifiers(boolean needJavaIdentifiers) {
+        this.needJavaIdentifiers = needJavaIdentifiers;
+    }    
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsReceiverComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsReceiverComponent.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsReceiverComponent.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsReceiverComponent.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.JBIException;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.jms.core.JmsTemplate;
+
+/**
+ * A component which uses a {@link JmsTemplate} to consume messages from a
+ * destination.
+ *
+ * @version $Revision: 466982 $
+ */
+public class JmsReceiverComponent extends JmsInBinding implements InitializingBean {
+    private JmsTemplate template;
+    private String selector;
+    private MessageConsumer consumer;
+    private ConnectionFactory connectionFactory;
+    private Connection connection;
+    private Session session;
+
+    public void afterPropertiesSet() throws Exception {
+        if (template == null) {
+            throw new IllegalArgumentException("Must have a template set");
+        }
+    }
+    
+    public void start() throws JBIException {
+        // Start receiving messages only when the component has actually been started.
+        super.start();
+        try {
+            connectionFactory = template.getConnectionFactory();
+            /*
+             * Component code did not work for JMS 1.02 compliant provider because uses APIs
+             * that did not exist in JMS 1.02 : ConnectionFactory.createConnection,
+             * Connection.createSession
+             */
+            if (template instanceof org.springframework.jms.core.JmsTemplate102) {
+                //Note1 - would've preferred to call JmsTemplate102 methods but they are protected.
+                if (template.isPubSubDomain()) {
+                    javax.jms.TopicConnection tc;
+                    connection = tc = ((javax.jms.TopicConnectionFactory)connectionFactory).createTopicConnection();
+                    session = tc.createTopicSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+                }
+                else {
+                    javax.jms.QueueConnection qc;
+                    connection = qc = ((javax.jms.QueueConnectionFactory)connectionFactory).createQueueConnection();
+                    session = qc.createQueueSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+                }
+            } else { // JMS 1.1 style
+                connection = connectionFactory.createConnection();
+                session = connection.createSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+            }
+
+            Destination defaultDestination = template.getDefaultDestination();
+            if (defaultDestination == null) {
+                defaultDestination = template.getDestinationResolver().resolveDestinationName(session, template.getDefaultDestinationName(),
+                        template.isPubSubDomain());
+            }
+
+            /*
+             * Component code did not work for JMS 1.02 compliant provider because uses APIs
+             * that did not exist in JMS 1.02: Session.createConsumer
+             */
+            if (template instanceof org.springframework.jms.core.JmsTemplate102) {
+                //Note1 - would've preferred to call JmsTemplate102.createConsumer but it is protected. Code below is same.
+                //Note2 - assert that defaultDestination is correct type according to isPubSubDomain()
+                if (template.isPubSubDomain()) {
+                    consumer = ((javax.jms.TopicSession)session).createSubscriber((javax.jms.Topic)defaultDestination, selector, template.isPubSubNoLocal());
+                } else {
+                    consumer = ((javax.jms.QueueSession)session).createReceiver((javax.jms.Queue)defaultDestination, selector);
+                }
+            } else { // JMS 1.1 style
+                consumer = session.createConsumer(defaultDestination, selector);
+            }
+            connection.start();
+            consumer.setMessageListener(this);
+        } catch (JMSException e) {
+            throw new JBIException("Unable to start jms component", e);
+        }
+    }
+
+    public void stop() throws JBIException {
+        try {
+            if (consumer != null) {
+                consumer.close();
+            }
+            if (session != null) {
+                session.close();
+            }
+            if (connection != null) {
+                connection.close();
+            }
+        } catch (JMSException e) {
+            throw new JBIException("Unable to stop jms component", e);
+        } finally {
+            connection = null;
+            session = null;
+            consumer = null;
+        }
+    }
+
+    public JmsTemplate getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(JmsTemplate template) {
+        this.template = template;
+    }
+
+    public String getSelector() {
+        return selector;
+    }
+
+    public void setSelector(String selector) {
+        this.selector = selector;
+    }
+
+}
+

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsSenderComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsSenderComponent.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsSenderComponent.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsSenderComponent.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.components.util.OutBinding;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.jms.core.MessageCreator;
+
+/**
+ * Consumers JBI messages and sends them to a JMS destination using the Spring
+ * {@link JmsTemplate}
+ *
+ * @version $Revision: 426415 $
+ */
+public class JmsSenderComponent extends OutBinding {
+
+    private static final Log log = LogFactory.getLog(JmsSenderComponent.class);
+
+    private JmsTemplate template;
+    private JmsMarshaler marshaler = new JmsMarshaler();
+
+
+    // Properties
+    //-------------------------------------------------------------------------
+    public JmsTemplate getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(JmsTemplate template) {
+        this.template = template;
+    }
+
+    public JmsMarshaler getMarshaler() {
+        return marshaler;
+    }
+
+    public void setMarshaler(JmsMarshaler marshaler) {
+        this.marshaler = marshaler;
+    }
+
+    /**
+     * @return Returns the needJavaIdentifiers.
+     */
+    public boolean isNeedJavaIdentifiers() {
+        return this.marshaler.isNeedJavaIdentifiers();
+    }
+
+    /**
+     * @param needJavaIdentifiers The needJavaIdentifiers to set.
+     */
+    public void setNeedJavaIdentifiers(boolean needJavaIdentifiers) {
+        this.marshaler.setNeedJavaIdentifiers(needJavaIdentifiers);
+    }    
+    
+    // Implementation methods
+    //-------------------------------------------------------------------------
+    protected void process(MessageExchange exchange, final NormalizedMessage inMessage) throws Exception {
+        template.send(new MessageCreator() {
+            public Message createMessage(Session session) throws JMSException {
+                try {
+                    Message message = marshaler.createMessage(inMessage, session);
+                    if (log.isTraceEnabled()) {
+                        log.trace("Sending message to: " + template.getDefaultDestinationName() + " message: " + message);
+                    }
+                    return message;
+                }
+                catch (TransformerException e) {
+                    JMSException jmsEx =  new JMSException("Failed to create JMS Message: " + e);
+                    jmsEx.setLinkedException(e);
+                    throw jmsEx;
+                }
+            }
+        });
+        done(exchange);
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsServiceComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsServiceComponent.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsServiceComponent.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/JmsServiceComponent.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.ExchangeStatus;
+import javax.jbi.messaging.InOut;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.components.util.ComponentSupport;
+import org.apache.servicemix.executors.Executor;
+import org.apache.servicemix.executors.ExecutorFactory;
+import org.apache.servicemix.jbi.framework.ComponentContextImpl;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.jms.JmsException;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.jms.core.MessageCreator;
+
+/**
+ * A component which uses a {@link JmsTemplate} to consume messages from a destination, forward then intot the JBI
+ * container for processing, and send back the result to the JMS requestor - used for the TopipcRequestor and
+ * QueueRequestor pattern
+ * 
+ * @version $Revision: 466982 $
+ */
+public class JmsServiceComponent extends ComponentSupport implements MessageListener, InitializingBean {
+    private static final Log log = LogFactory.getLog(JmsServiceComponent.class);
+    private DestinationChooser destinationChooser;
+    private JmsMarshaler marshaler = new JmsMarshaler();
+    private JmsTemplate template;
+    private String selector;
+    private MessageConsumer consumer;
+    private ConnectionFactory connectionFactory;
+    private Connection connection;
+    private Session session;
+    private Executor executor;
+
+    /**
+     * called by Spring framework after initialization
+     * @throws Exception 
+     */
+    public void afterPropertiesSet() throws Exception {
+        if (template == null) {
+            throw new IllegalArgumentException("Must have a template set");
+        }
+    }
+
+    public void start() throws JBIException {
+        // Start receiving messages only when the component has actually been started.
+        super.start();
+        try {
+            connectionFactory = template.getConnectionFactory();
+            /*
+             * Component code did not work for JMS 1.02 compliant provider because uses APIs
+             * that did not exist in JMS 1.02 : ConnectionFactory.createConnection,
+             * Connection.createSession
+             */
+            if (template instanceof org.springframework.jms.core.JmsTemplate102) {
+                //Note1 - would've preferred to call JmsTemplate102 methods but they are protected.
+                if (template.isPubSubDomain()) {
+                    javax.jms.TopicConnection tc;
+                    connection = tc = ((javax.jms.TopicConnectionFactory)connectionFactory).createTopicConnection();
+                    session = tc.createTopicSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+                }
+                else {
+                    javax.jms.QueueConnection qc;
+                    connection = qc = ((javax.jms.QueueConnectionFactory)connectionFactory).createQueueConnection();
+                    session = qc.createQueueSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+                }
+            } else { // JMS 1.1 style
+                connection = connectionFactory.createConnection();
+                session = connection.createSession(template.isSessionTransacted(), template.getSessionAcknowledgeMode());
+            }
+
+            Destination defaultDestination = template.getDefaultDestination();
+            if (defaultDestination == null) {
+                defaultDestination = template.getDestinationResolver().resolveDestinationName(session, template.getDefaultDestinationName(),
+                        template.isPubSubDomain());
+            }
+            
+            /*
+             * Component code did not work for JMS 1.02 compliant provider because uses APIs
+             * that did not exist in JMS 1.02: Session.createConsumer
+             */
+            if (template instanceof org.springframework.jms.core.JmsTemplate102) {
+                //Note1 - would've preferred to call JmsTemplate102.createConsumer but it is protected. Code below is same.
+                //Note2 - assert that defaultDestination is correct type according to isPubSubDomain()
+                if (template.isPubSubDomain()) {
+                    consumer = ((javax.jms.TopicSession)session).createSubscriber((javax.jms.Topic)defaultDestination, selector, template.isPubSubNoLocal());
+                } else {
+                    consumer = ((javax.jms.QueueSession)session).createReceiver((javax.jms.Queue)defaultDestination, selector);
+                }
+            } else { // JMS 1.1 style
+                consumer = session.createConsumer(defaultDestination, selector);
+            }
+            connection.start();
+            consumer.setMessageListener(this);
+        } catch (JMSException e) {
+            throw new JBIException("Unable to start jms component", e);
+        }
+    }
+
+    public void stop() throws JBIException {
+        try {
+            if (consumer != null) {
+                consumer.close();
+            }
+            if (session != null) {
+                session.close();
+            }
+            if (connection != null) {
+                connection.close();
+            }
+        } catch (JMSException e) {
+            throw new JBIException("Unable to stop jms component", e);
+        } finally {
+            connection = null;
+            session = null;
+            consumer = null;
+        }
+    }
+
+    protected void init() throws JBIException {
+        ComponentContextImpl context = (ComponentContextImpl) getContext();
+        ExecutorFactory factory = context.getContainer().getExecutorFactory();
+        executor = factory.createExecutor("component." + context.getComponentName());
+        super.init();
+    }
+
+    /**
+     * @return Return the DestinationChooser
+     */
+    public DestinationChooser getDestinationChooser() {
+        return destinationChooser;
+    }
+
+    /**
+     * Set the DestinationChooser
+     * 
+     * @param destinationChooser
+     */
+    public void setDestinationChooser(DestinationChooser destinationChooser) {
+        this.destinationChooser = destinationChooser;
+    }
+
+    /**
+     * Get the JMSMarshaler
+     * 
+     * @return the marshaler
+     */
+    public JmsMarshaler getMarshaler() {
+        return marshaler;
+    }
+
+    /**
+     * Set the JMSMarshaler
+     * 
+     * @param marshaler
+     */
+    public void setMarshaler(JmsMarshaler marshaler) {
+        this.marshaler = marshaler;
+    }
+
+    /**
+     * @return the JmsTemplate
+     */
+    public JmsTemplate getTemplate() {
+        return template;
+    }
+
+    /**
+     * Set the JmsTemplate
+     * 
+     * @param template
+     */
+    public void setTemplate(JmsTemplate template) {
+        this.template = template;
+    }
+
+    /**
+     * @return Return the selector
+     */
+    public String getSelector() {
+        return selector;
+    }
+
+    /**
+     * Set the Selector
+     * 
+     * @param selector
+     */
+    public void setSelector(String selector) {
+        this.selector = selector;
+    }
+
+    /**
+     * MessageListener implementation
+     * @param jmsMessage 
+     */
+    public void onMessage(final Message jmsMessage) {
+        executor.execute(new Runnable() {
+            public void run() {
+                handleMessage(jmsMessage);
+            }
+        });
+    }
+    
+    protected void handleMessage(final Message jmsMessage) {
+        try {
+            final InOut messageExchange = getDeliveryChannel().createExchangeFactory().createInOutExchange();
+            NormalizedMessage inMessage = messageExchange.createMessage();
+            try {
+                marshaler.toNMS(inMessage, jmsMessage);
+                messageExchange.setInMessage(inMessage);
+                if (getDeliveryChannel().sendSync(messageExchange)) {
+                    Destination destination = getReplyToDestination(jmsMessage, messageExchange);
+                    try {
+                        template.send(destination, new MessageCreator() {
+                            public Message createMessage(Session session) throws JMSException {
+                                try {
+                                    Message message = marshaler.createMessage(messageExchange.getOutMessage(), session);
+                                    message.setJMSCorrelationID(jmsMessage.getJMSCorrelationID());
+                                    if (log.isTraceEnabled()) {
+                                        log.trace("Sending message to: " + template.getDefaultDestinationName()
+                                                + " message: " + message);
+                                    }
+                                    return message;
+                                }
+                                catch (TransformerException e) {
+                                    JMSException jmsEx = new JMSException("Failed to create a JMS Message: " + e);
+                                    jmsEx.setLinkedException(e);
+                                    throw jmsEx;
+                                }
+                            }
+                        });
+                        done(messageExchange);
+                    }
+                    catch (JmsException e) {
+                        fail(messageExchange, e);
+                    }
+                }
+            }
+            catch (JMSException e) {
+                log.error("Couldn't process " + jmsMessage, e);
+                messageExchange.setError(e);
+                messageExchange.setStatus(ExchangeStatus.ERROR);
+            }
+        }
+        catch (MessagingException e) {
+            log.error("Failed to process inbound JMS Message: " + jmsMessage, e);
+        }
+    }
+
+    protected Destination getReplyToDestination(Message jmsMessage, final InOut messageExchange) throws JMSException {
+        if (destinationChooser == null) {
+            return jmsMessage.getJMSReplyTo();
+        }
+        return destinationChooser.chooseDestination(messageExchange);
+    }
+
+    /**
+     * Choose the out bound destination to send the repsonse from JBI too If a DestinatonChooser is set, this is used,
+     * else the replyTo destination on the inbound message is used
+     * 
+     * @param exchange
+     * @param inboundMessage
+     * @return the choosen outbound destination or null
+     * @throws JMSException if no destination can be found
+     */
+    protected Destination chooseOutBoundDestination(MessageExchange exchange, Message inboundMessage)
+            throws JMSException {
+        Destination result = null;
+        if (destinationChooser != null) {
+            result = destinationChooser.chooseDestination(exchange);
+        }
+        else if (inboundMessage != null && inboundMessage.getJMSReplyTo() != null) {
+            result = inboundMessage.getJMSReplyTo();
+        }
+        if (result == null) {
+            log.error("Could not find an outbound destination for " + inboundMessage);
+            throw new JMSException("No outbound JMS Destination can be found");
+        }
+        return result;
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/RuntimeJMSException.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/RuntimeJMSException.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/RuntimeJMSException.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/RuntimeJMSException.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jms.JMSException;
+
+/**
+ * A runtime exception caused when a JMS exception is thrown
+ * in a method which cannot throw a checked exception such
+ * as inside a JMS {@link javax.jms.MessageListener#onMessage(javax.jms.Message)} method.
+ *
+ * @version $Revision: 426415 $
+ */
+public class RuntimeJMSException extends RuntimeException {
+
+    public RuntimeJMSException(JMSException cause) {
+        super(cause);
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/SimpleDestinationChooser.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/SimpleDestinationChooser.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/SimpleDestinationChooser.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/SimpleDestinationChooser.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jms;
+
+import javax.jbi.messaging.MessageExchange;
+import javax.jms.Destination;
+
+/**
+ * A simple destination chooser which will use the value of the {@link #OUT_DESTINATION_KEY}
+ * property on the message exchange, or fall back to a default destination
+ *
+ * @version $Revision: 426415 $
+ */
+public class SimpleDestinationChooser implements DestinationChooser {
+    public static final String OUT_DESTINATION_KEY = "org.apache.servicemix.binding.jms.out.destination";
+
+    private Destination defaultDestination;
+
+    public SimpleDestinationChooser() {
+    }
+
+    public SimpleDestinationChooser(Destination defaultDestination) {
+        this.defaultDestination = defaultDestination;
+    }
+
+    public Destination chooseDestination(MessageExchange messageExchange) {
+        Object property = messageExchange.getProperty(OUT_DESTINATION_KEY);
+        if (property instanceof Destination) {
+            return (Destination) property;
+        }
+        return getDefaultDestination();
+    }
+
+    // Properties
+    //-------------------------------------------------------------------------
+    public Destination getDefaultDestination() {
+        return defaultDestination;
+    }
+
+    public void setDefaultDestination(Destination defaultDestination) {
+        this.defaultDestination = defaultDestination;
+    }
+
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/package.html
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/package.html?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/package.html (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jms/package.html Mon Apr  4 10:41:21 2011
@@ -0,0 +1,27 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<html>
+<head>
+</head>
+<body>
+
+Bindings for <a href="http://java.sun.com/products/jms/">JMS</a>
+
+</body>
+</html>

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jmx/CounterMonitorComponent.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jmx/CounterMonitorComponent.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jmx/CounterMonitorComponent.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/jmx/CounterMonitorComponent.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.jmx;
+
+import javax.jbi.JBIException;
+import javax.jbi.component.ComponentContext;
+import javax.jbi.management.DeploymentException;
+import javax.jbi.messaging.InOnly;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.monitor.CounterMonitor;
+import javax.xml.transform.Source;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.MessageExchangeListener;
+import org.apache.servicemix.components.util.ComponentSupport;
+import org.apache.servicemix.jbi.jaxp.StringSource;
+
+/**
+ * A JMX Counter Monitor as a Component to enable firing notifications
+ * 
+ * @version $Revision: 426415 $
+ */
+public class CounterMonitorComponent extends ComponentSupport implements NotificationListener, MessageExchangeListener {
+    
+    private static final Log log = LogFactory.getLog(ComponentSupport.class);
+    private String name;
+    private ObjectName ourName;
+    private String observedObjectName;
+    private String attributeName;
+    private long granularityPeriod =5000;
+    private Number threshold;
+    private Number offset;
+    private MBeanServer mbeanServer;
+    private CounterMonitor counterMonitor = new CounterMonitor();
+
+    /**
+     * Called when the Component is initialized
+     * 
+     * @param cc
+     * @throws JBIException
+     */
+    public void init(ComponentContext cc) throws JBIException {
+        super.init(cc);
+        validate();
+        if (mbeanServer == null) {
+            mbeanServer = cc.getMBeanServer();
+        }
+        try {
+            ObjectName observedName = new ObjectName(observedObjectName);
+            if (name == null) {
+                String type = observedName.getKeyProperty("type");
+                type = type != null ? type : "UNKNOWN";
+                name = mbeanServer.getDefaultDomain() + ":type=CounterMonitor_" + type;
+            }
+            ourName = new ObjectName(name);
+            counterMonitor.setNotify(true);
+            counterMonitor.addObservedObject(observedName);
+            counterMonitor.setObservedAttribute(attributeName);
+            counterMonitor.setGranularityPeriod(granularityPeriod);
+            counterMonitor.setDifferenceMode(false);
+            counterMonitor.setInitThreshold(threshold);
+            counterMonitor.setOffset(offset);
+            mbeanServer.registerMBean(counterMonitor, ourName);
+            mbeanServer.addNotificationListener(ourName, this, null, new Object());
+        } catch (Exception e) {
+            throw new DeploymentException(e);
+        }
+    }
+
+    /**
+     * Start the item.
+     * 
+     * @exception javax.jbi.JBIException
+     *                if the item fails to start.
+     */
+    public void start() throws javax.jbi.JBIException {
+        super.start();
+        counterMonitor.start();
+    }
+
+    /**
+     * Stop the item. This suspends current messaging activities.
+     * 
+     * @exception javax.jbi.JBIException
+     *                if the item fails to stop.
+     */
+    public void stop() throws javax.jbi.JBIException {
+        counterMonitor.stop();
+        super.stop();
+    }
+
+    /**
+     * Shut down the item. The releases resources, preparatory to uninstallation.
+     * 
+     * @exception javax.jbi.JBIException
+     *                if the item fails to shut down.
+     */
+    public void shutDown() throws javax.jbi.JBIException {
+        stop();
+        if (ourName != null && mbeanServer != null) {
+            try{
+                mbeanServer.removeNotificationListener(ourName,this);
+            } catch(Exception e) {
+                throw new JBIException(e);
+            }
+        }
+        super.shutDown();
+    }
+
+   
+    /**
+     * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object)
+     */
+    public void handleNotification(Notification notification,Object arg1) {
+        try {
+            Source source = new StringSource(notification.getMessage());
+            InOnly exchange = getExchangeFactory().createInOnlyExchange();
+            NormalizedMessage message = exchange.createMessage();
+            message.setContent(source);
+            exchange.setInMessage(message);
+            send(exchange);
+        }
+        catch (Exception e) {
+            log.error("Failed to send Notification message to the NMR");
+        }
+        
+    }
+
+    protected void validate() throws JBIException {
+        if (observedObjectName == null) {
+            throw new DeploymentException("observedObjectName is null");
+        }
+        if (attributeName == null) {
+            throw new DeploymentException("attributeName is null");
+        }
+        if (threshold == null) {
+            throw new DeploymentException("threshold is null");
+        }
+        if (offset == null) {
+            throw new DeploymentException("offset is null");
+        }
+    }
+
+    /**
+     * @return Returns the attributeName.
+     */
+    public String getAttributeName() {
+        return attributeName;
+    }
+
+    /**
+     * @param attributeName
+     *            The attributeName to set.
+     */
+    public void setAttributeName(String attributeName) {
+        this.attributeName = attributeName;
+    }
+
+    /**
+     * @return Returns the counterMonitor.
+     */
+    public CounterMonitor getCounterMonitor() {
+        return counterMonitor;
+    }
+
+    /**
+     * @param counterMonitor The counterMonitor to set.
+     */
+    public void setCounterMonitor(CounterMonitor counterMonitor) {
+        this.counterMonitor = counterMonitor;
+    }
+
+    /**
+     * @return Returns the granularityPeriod.
+     */
+    public long getGranularityPeriod() {
+        return granularityPeriod;
+    }
+
+    /**
+     * @param granularityPeriod The granularityPeriod to set.
+     */
+    public void setGranularityPeriod(long granularityPeriod) {
+        this.granularityPeriod = granularityPeriod;
+    }
+
+    /**
+     * @return Returns the mbeanServer.
+     */
+    public MBeanServer getMbeanServer() {
+        return mbeanServer;
+    }
+
+    /**
+     * @param mbeanServer The mbeanServer to set.
+     */
+    public void setMbeanServer(MBeanServer mbeanServer) {
+        this.mbeanServer = mbeanServer;
+    }
+
+    /**
+     * @return Returns the name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return Returns the observedObjectName.
+     */
+    public String getObservedObjectName() {
+        return observedObjectName;
+    }
+
+    /**
+     * @param observedObjectName The observedObjectName to set.
+     */
+    public void setObservedObjectName(String observedObjectName) {
+        this.observedObjectName = observedObjectName;
+    }
+
+    /**
+     * @return Returns the offset.
+     */
+    public Number getOffset() {
+        return offset;
+    }
+
+    /**
+     * @param offset The offset to set.
+     */
+    public void setOffset(Number offset) {
+        this.offset = offset;
+    }
+
+    /**
+     * @return Returns the threshold.
+     */
+    public Number getThreshold() {
+        return threshold;
+    }
+
+    /**
+     * @param threshold The threshold to set.
+     */
+    public void setThreshold(Number threshold) {
+        this.threshold = threshold;
+    }
+
+    public void onMessageExchange(MessageExchange exchange) throws MessagingException {
+        // We can only receive acks, so do nothing
+    }
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ConfigNotSupportedException.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ConfigNotSupportedException.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ConfigNotSupportedException.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ConfigNotSupportedException.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+public class ConfigNotSupportedException extends Exception {
+
+	public ConfigNotSupportedException() {
+		super();
+	}
+	public ConfigNotSupportedException(String message) {
+		super(message);
+	}
+
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ExistingPropertyCopier.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ExistingPropertyCopier.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ExistingPropertyCopier.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/ExistingPropertyCopier.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.NormalizedMessage;
+
+
+/**
+ * Copy a property value from an existing property (somewhere)
+ * @author rbuckland
+ *
+ */
+public class ExistingPropertyCopier implements PropertyValue {
+
+	public final static String XML_ELEMENT_NAME = "existing-property";
+	
+	private String name;
+
+	public ExistingPropertyCopier(String name) {
+		this.name = name;
+	}
+	public String getPropertyValue(NormalizedMessage msg) throws JBIException {
+		if (msg.getProperty(name) != null) {
+			return msg.getProperty(name).toString();
+		} else {
+			return null;
+		}
+		
+	}
+
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/MessagePropertySetterXML.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/MessagePropertySetterXML.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/MessagePropertySetterXML.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/MessagePropertySetterXML.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jbi.JBIException;
+import javax.jbi.component.ComponentContext;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.components.util.TransformComponentSupport;
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.xpath.CachedXPathAPI;
+import org.apache.xpath.objects.XObject;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+
+
+/**
+ * Sets properties on the message, loaded from an XML MPS file 
+ * where the properties to set are located in a <property-set ..>
+ * inside the XML config file.
+ * 
+ * There can be more than one propertySet to "load".
+ *
+ *  The property values are derived from 3 types of config.
+ *  The first config that can return a value as a String to
+ *  set onto the message, will be the "value" that is set
+ *  as the property.
+ *  
+ *  <static-value>
+ *  		As it's name suggests, the "value" of this element
+ *          will be the value of the JBI property.
+ *          
+ *          This is helpful as a default value, or as a static value.
+ *          
+ *  <exisiting-property> and <existint-property name="..."/>
+ *    		This will obtain the value of an existing property (itself)
+ *          or another property on the same message.
+ *          
+ *           This can be helpful when you want the to "ONLY" change the
+ *           the value of the property if there is some "xpath" expression
+ *           that could not be derived. 
+ *           
+ *           name=".." form will copy the string value of the other JBI property
+ *           onto this one, (duping it). This may be handy when you have a component 
+ *           which expects a new property, but you have it as a different name at the moment.
+ *           
+ *  <xpath-expression>
+ *           As it's name suggests, will locate a value in the inMessage source
+ *           and set the resulting XPath String as the value of the JBI property.
+ *           
+ *  So given the three types, they can be arranged in any order. and the first
+ *  PropertyValue Type that returns a value, will become the "value" of the JBI property.
+ *  
+ *
+ * <!-- 
+ * <mps>
+ *	 <property-set name="someSetNameForASetOfProperties">
+ *	     <property name="some.property.name1">
+ *	         <static-value><![CDATA[value for the property]]></static-value>
+ *	     </property>
+ *	     <property name="some.property.name2">
+ *	         <xpath-expression>
+ *		 	      <![CDATA[/someexpath/statement/to/be/applied/to/message/source]]>
+ *		 	 </xpath-expression>
+ *	         <existing-property name="someproperty"/>
+ *		 	 <static-value><![CDATA[a value in the raw]]></static-value>
+ *	     </property>
+ *	     <property name="prop.xpath.with.static.default">
+ *	        <xpath-expression>
+ *		 	    <![CDATA[/someexpath/statement]]>
+ *		 	</xpath-expression>
+ *		 	<static-value><![CDATA[some default if xpath does not resolve]]></static-value>
+ *	     </property>
+ *	     <property name="prop.xpath.or.keep.existing">
+ *	        <xpath-expression>
+ *		 	    <![CDATA[/someexpath/statement]]>
+ *		 	</xpath-expression>
+ *		 	<existing-property/>
+ *	     </property>
+ *	     <property name="new.prop.name">
+ *		 	<existing-property name="other.property"/>
+ *	     </property>
+ *       <property name="..."> 
+ *              ...
+ *       </property>
+ *	 </property-set>
+ *   <property-set name="...">
+ *        ...
+ *   </property-set>
+ * </mps>
+ * -->
+ *
+ * 
+ * @author rbuckland
+ * 
+ */
+public class MessagePropertySetterXML extends TransformComponentSupport  {
+	
+	/**
+	 * Apache commons logger
+	 */
+	private final transient Log logger = LogFactory.getLog(getClass());
+
+	/**
+	 * The name of our JBI property we may have to interrogate to 
+	 * use as the "xpath" for the set of config.
+	 */
+	public static final String MPS_PROP_NAME_PROPERTYSET = "org.apache.servicemix.components.mps.propertyset";
+	
+	/**
+	 * The XML Element name "property-set"
+	 */
+	public static final String XML_ELEMENT_NAME = "property-set";
+	
+	/**
+	 * This is our XML file
+	 */
+	private Resource xmlConfiguration = null;
+	
+	/**
+	 * Our XML config MPS.
+	 */
+	private Document xmlMPSdom = null;
+	
+	/**
+	 * Holds the propertyValueResolver objects.
+	 * if propertySet is not null, this holds one.
+	 * if propertySet is null, this will hold
+	 * one for each propertyvalue entry used during the time
+	 * we are "active".
+	 */
+	private Map propertSets = new HashMap();
+
+	/**
+	 * If this is set, it is hardcoded as the fixed value.
+	 * 
+	 * If this is null 
+	 * we will look for a propery MPS_PROP_NAME_PROPERTYSET
+	 * as the "name" of the property set we will work with.
+	 * So the message incoming, seeds the set of properties to load, just by
+	 * the JBI property itself.
+	 */
+	private String propertySet = null;
+	
+	
+	/**
+	 * If the XPath for a propertySet is not null
+	 * we will try and locate the propertySet to use by 
+	 * pulling a String from the inMessage content using this
+	 * XPath.
+	 */
+	private String xpathForPropertySet = null;
+	
+	/**
+	 * Here is the transform of the message
+	 * We will locate the propertySetName to use 
+	 * and the load up our propertySet magic wand and apply all the properties
+	 * we can to the outgoing NormalizedMessage
+	 */
+	protected boolean transform(MessageExchange arg0, NormalizedMessage in, NormalizedMessage out) throws MessagingException {
+		try {
+			copyPropertiesAndAttachments(arg0,in,out);
+			out.setContent(in.getContent());
+			
+			String propertySetName = "";
+			if (xpathForPropertySet != null) {
+				try {
+					CachedXPathAPI xpathApi = new org.apache.xpath.CachedXPathAPI();
+					Document doc = new SourceTransformer().toDOMDocument(in);
+					XObject propSetXO = xpathApi.eval(doc.getDocumentElement(),xpathForPropertySet);
+					propertySetName = propSetXO.str();
+				} catch (Exception e) {
+					throw new MessagingException("Problem getting the propertySet using XPath", e);
+				}
+			} else if (this.propertySet != null) {
+				propertySetName = this.propertySet;
+			} else if (in.getProperty(MPS_PROP_NAME_PROPERTYSET) != null) {
+				propertySetName = in.getProperty(MPS_PROP_NAME_PROPERTYSET).toString();
+			} else {
+				return false;
+			}
+			logger.info("Applying properties from property-set [" + propertySetName + "]");
+			getPropertySetByName(propertySetName).applyProperties(in,out);
+			return true;				
+		} catch (JBIException e) {
+			throw new MessagingException("Problem setting properties",e);
+		} catch (PropertySetNotFoundException e) {
+			logger.warn(e.getLocalizedMessage());
+			return false;
+		}
+	}
+
+	/**
+	 * Initialise by loading the mps.xml file up into an internal DOM.
+	 * 
+	 * @throws JBIException
+	 */
+	private void initConfig() throws JBIException {
+		Assert.notNull(this.xmlConfiguration);
+		DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+		domFactory.setIgnoringElementContentWhitespace(true);
+		domFactory.setIgnoringComments(true);
+		domFactory.setCoalescing(true); // convert CDATA to test nodes
+        DocumentBuilder domBuilder;
+		try {
+			logger.info("Intialising MessagePropertySetterXML, loading settings from " + this.xmlConfiguration.getFile().getAbsolutePath());
+			domBuilder = domFactory.newDocumentBuilder();
+			xmlMPSdom = domBuilder.parse(this.xmlConfiguration.getInputStream());
+		} catch (ParserConfigurationException e) {
+			throw new JBIException("Problem parsing the XML config file for MPS",e);
+		} catch (SAXException e) {
+			throw new JBIException("Problem loading the XML config file for MPS",e);
+		} catch (IOException e) {
+			throw new JBIException("Problem loading the XML config file for MPS",e);
+		}
+		
+	}
+
+	/**
+	 * We are only interested  in loading the XML onfig, nothing else
+	 */
+	public void init(ComponentContext context) throws JBIException {
+		super.init(context);
+		initConfig();
+	}
+
+	/**
+	 * Create a propertyset (loading up the Object config based on the XML config)
+	 * 
+	 * @param propertySetName
+	 * @return
+	 * @throws JBIException
+	 * @throws PropertySetNotFoundException
+	 */
+	private PropertySet createPropertySet(String propertySetName) throws JBIException , PropertySetNotFoundException{
+		PropertySet ps;	
+		CachedXPathAPI xpath = new CachedXPathAPI();
+		StringBuffer xpathSB = new StringBuffer("//")
+									.append(XML_ELEMENT_NAME)
+									.append("[@name='")
+									.append(propertySetName)
+									.append("']");
+		try {
+			Node propertySetNode = xpath.selectSingleNode(xmlMPSdom,xpathSB.toString());
+			if (propertySetNode == null) {
+				throw new PropertySetNotFoundException("Could not find a property-set for [" + propertySetName + "] in " + xmlConfiguration.getFilename());
+			}
+			ps = new PropertySet(propertySetName,(Element) propertySetNode);
+			this.propertSets.put(propertySetName, ps);
+		} catch (TransformerException e) {
+			throw new JBIException("Could not load the PropertySet for " + propertySet,e);		
+		} catch (ConfigNotSupportedException e) {
+			throw new JBIException("Could not load the PropertySet for. XMLConfig is not good for " + propertySet,e);		
+		}
+		return ps;
+
+	}
+	
+	/**
+	 * Get a property set from ou
+	 * @param name
+	 * @return
+	 * @throws JBIException 
+	 */
+	private PropertySet getPropertySetByName(String name) throws JBIException, PropertySetNotFoundException {
+		// find a pre "created" one
+		if (this.propertSets.containsKey(name)) {
+			return (PropertySet)this.propertSets.get(name);
+		} else {
+			return this.createPropertySet(name);
+		}
+		
+	}
+
+	/**
+	 * @param propertySet The propertySet to set.
+	 */
+	public void setPropertySet(String propertySet) {
+		this.propertySet = propertySet;
+	}
+
+	/**
+	 * @param xmlConfiguration The xmlConfiguration to set.
+	 */
+	public void setXmlConfiguration(Resource xmlConfiguration) {
+		this.xmlConfiguration = xmlConfiguration;
+	}
+
+	/**
+	 * @param xpathForPropertySet xpath to apply to a message to derive the name of the property-set we want to load
+	 */
+	public void setXpathForPropertySet(String xpathForPropertySet) {
+		this.xpathForPropertySet = xpathForPropertySet;
+	}
+
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySet.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySet.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySet.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySet.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.NormalizedMessage;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class PropertySet {
+
+	
+	public final static String XML_ELEMENT_NAME = "property-set";
+	
+	public final static String XML_ATTR_NAME_NAME = "name";
+	
+	/**
+	 * Our name
+	 */
+	private String propertySetName;
+
+	/**
+	 * Our list of property value resolvers
+	 */
+	private ArrayList pvrs = new ArrayList();
+	
+	/**
+	 * Create a propertySet with a particular name
+	 * Element self is //property-set
+	 * 
+	 * @param name
+	 */
+	public PropertySet(String name, Element self) throws ConfigNotSupportedException{
+		this.propertySetName = name;
+		NodeList properties = self.getElementsByTagName(PropertyValueResolver.XML_ELEMENT_NAME);
+		for (int i=0; i < properties.getLength();i++) {
+			Element property = (Element)properties.item(i);
+			this.pvrs.add((new PropertyValueResolver(property.getAttribute(XML_ATTR_NAME_NAME),property)));
+		}
+	}
+	
+	/**
+	 * Apply all the property values for this in/out pair
+	 * 
+	 * @param in
+	 * @param out
+	 */
+	public void applyProperties(NormalizedMessage in, NormalizedMessage out) throws JBIException {
+		
+		// for every property, set the value on the message
+		for (Iterator iter = pvrs.iterator(); iter.hasNext();) {
+			((PropertyValueResolver)iter.next()).setProperty(in,out);
+		}
+	}
+
+	public String getName() {
+		return propertySetName;
+	}
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySetNotFoundException.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySetNotFoundException.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySetNotFoundException.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertySetNotFoundException.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+public class PropertySetNotFoundException extends Exception {
+
+	public PropertySetNotFoundException() {
+		super();
+	}
+
+	public PropertySetNotFoundException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public PropertySetNotFoundException(String message) {
+		super(message);
+	}
+
+	public PropertySetNotFoundException(Throwable cause) {
+		super(cause);
+	}
+
+	
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValue.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValue.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValue.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValue.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.NormalizedMessage;
+
+public interface PropertyValue {
+
+	public String getPropertyValue(NormalizedMessage msg) throws JBIException;
+	
+}

Added: servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValueResolver.java
URL: http://svn.apache.org/viewvc/servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValueResolver.java?rev=1088548&view=auto
==============================================================================
--- servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValueResolver.java (added)
+++ servicemix/smx3/trunk/common/servicemix-components/src/main/java/org/apache/servicemix/components/mps/PropertyValueResolver.java Mon Apr  4 10:41:21 2011
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.components.mps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jbi.JBIException;
+import javax.jbi.messaging.NormalizedMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.jbi.util.DOMUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * Class to hold the list of propertyValues
+ * 
+ * @author rbuckland
+ * 
+ */
+public class PropertyValueResolver {
+
+	private final transient Log logger = LogFactory.getLog(getClass());
+
+	public static final String XML_ELEMENT_NAME = "property";
+
+	/**
+	 * The name of the JBI property that this class will set.
+	 */
+	private String name;
+
+	/**
+	 * if the set contains a static-string propertyvalue at the top of the
+	 * config, we don't need to do anything so the value is stored "here". Null
+	 * if the list has to be evald
+	 */
+	private String staticValue = null;
+
+	/**
+	 * Our list of PropertySetTypes
+	 */
+	private List propertySetTypes = new ArrayList();
+
+	/**
+	 * Construct this PVR, the Element is the .. //property-set/property element
+	 * 
+	 * @param propertyName
+	 *            the name of the property that will be set
+	 * @param self
+	 *            Element
+	 * @throws JBIException
+	 */
+	public PropertyValueResolver(String propertyName, Element self)
+			throws ConfigNotSupportedException {
+		this.name = propertyName;
+		addPropertySetTypes(self);
+	}
+
+	/**
+	 * Set the property (this.name) on the out message based on any properties
+	 * on the message
+	 * 
+	 * @param msg
+	 */
+	public void setProperty(NormalizedMessage in, NormalizedMessage out)
+			throws JBIException {
+
+		if (this.staticValue != null) {
+			out.setProperty(name, staticValue);
+		} else {
+			String value = resolveValue(in);
+			if (value != null) {
+				out.setProperty(name, value);
+			} else {
+				logger.warn("Property " + name
+						+ " was not set as the value was unresolved");
+			}
+		}
+	}
+
+	/**
+	 * Get the value out of the in, and put it in the out.
+	 * 
+	 * @param in
+	 * @param out
+	 * @return
+	 */
+	private String resolveValue(NormalizedMessage message) throws JBIException {
+		// go through the list
+		// if a value is found on the one, return it, until the list is
+		// exhausted
+		String propValue = null;
+		logger.debug("propvrsize=" + propertySetTypes.size());
+		for (int i = 0; i < propertySetTypes.size(); i++) {
+			PropertyValue pv = (PropertyValue) propertySetTypes.get(i);
+			propValue = pv.getPropertyValue(message);
+			logger.debug("value from" + pv.getClass() + " = " + propValue);
+			if (propValue != null && !"".equals(propValue)) {
+				break;
+			}
+			if (logger.isDebugEnabled()) {
+				logger.debug(this.name + ": " + pv.getClass() + " was empty");
+			}
+		}
+		return propValue;
+	}
+
+	/**
+	 * Given the XML below, we will locate the different propertyValueTypes and
+	 * set them on us.
+	 * 
+	 * <property name="some.property.name"> <existing-property/>
+	 * <existing-property name="someproperty"/> <xpath-expression>
+	 * <![CDATA[/someexpath/statement]]> </xpath-expression> <static-value><![CDATA[a
+	 * value in the raw]]></static-value> </property>
+	 * 
+	 * @param propertyNode
+	 */
+	private void addPropertySetTypes(Element propertyElement)
+			throws ConfigNotSupportedException {
+
+		NodeList propertyValueNodes = propertyElement.getChildNodes();
+		// iterate of all the propertyValue nodes ..
+		// (same as equiv to select='//property[@name='x']/*'
+		for (int i = 0; i < propertyValueNodes.getLength(); i++) {
+			if (propertyValueNodes.item(i).getNodeType() != Element.ELEMENT_NODE) {
+				continue;
+			}
+			Element pvElem = (Element) propertyValueNodes.item(i);
+			PropertyValue pv;
+			if (pvElem.getNodeName().equals(
+					StaticStringPropertyValue.XML_ELEMENT_NAME)) {
+				if (this.propertySetTypes.size() == 0) {
+					this.staticValue = DOMUtil.getElementText(pvElem);
+				}
+				pv = new StaticStringPropertyValue(DOMUtil
+						.getElementText(pvElem));
+			} else if (pvElem.getNodeName().equals(
+					XPathContentMessagePropertyValue.XML_ELEMENT_NAME)) {
+				String xpath = DOMUtil.getElementText(pvElem);
+				pv = new XPathContentMessagePropertyValue(xpath);
+				if (logger.isDebugEnabled()) {
+					logger.debug("Created an XPath VR :" + xpath);
+				}
+			} else if (pvElem.getNodeName().equals(
+					ExistingPropertyCopier.XML_ELEMENT_NAME)) {
+				// default to this parents name (so it acts like a property
+				// copy)
+
+				String propertyName = this.name;
+				if (pvElem.getAttribute("name") != null
+						&& !"".equals(pvElem.getAttribute("name"))) {
+					// if there was a <existing-property name="somename"/>
+					// then use that name as the source JBI property
+					// in this mode it acts like a cp src dest and not a dupe.
+					propertyName = pvElem.getAttribute("name");
+				}
+				pv = new ExistingPropertyCopier(propertyName);
+			} else {
+				throw new ConfigNotSupportedException("Property value type "
+						+ pvElem.getNodeName()
+						+ " is not supported for the MessagePropertySetter");
+			}
+			this.propertySetTypes.add(pv);
+
+		}
+	}
+}