001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.wsn.jms;
018    
019    import java.io.StringReader;
020    import java.io.StringWriter;
021    import java.util.ArrayList;
022    import java.util.List;
023    
024    import javax.jms.Connection;
025    import javax.jms.JMSException;
026    import javax.jms.Message;
027    import javax.jms.MessageConsumer;
028    import javax.jms.MessageProducer;
029    import javax.jms.Queue;
030    import javax.jms.Session;
031    import javax.jms.TextMessage;
032    import javax.xml.bind.JAXBContext;
033    import javax.xml.bind.JAXBException;
034    
035    import org.apache.commons.logging.Log;
036    import org.apache.commons.logging.LogFactory;
037    import org.apache.servicemix.wsn.AbstractPullPoint;
038    import org.apache.servicemix.wsn.jaxws.ResourceUnknownFault;
039    import org.apache.servicemix.wsn.jaxws.UnableToGetMessagesFault;
040    import org.oasis_open.docs.wsn.b_2.NotificationMessageHolderType;
041    import org.oasis_open.docs.wsn.b_2.Notify;
042    import org.oasis_open.docs.wsn.b_2.UnableToGetMessagesFaultType;
043    
044    public class JmsPullPoint extends AbstractPullPoint {
045    
046        private static Log log = LogFactory.getLog(JmsPullPoint.class);
047    
048        private JAXBContext jaxbContext;
049    
050        private Connection connection;
051    
052        private Session session;
053    
054        private Queue queue;
055    
056        private MessageProducer producer;
057    
058        private MessageConsumer consumer;
059    
060        public JmsPullPoint(String name) {
061            super(name);
062            try {
063                jaxbContext = JAXBContext.newInstance(Notify.class);
064            } catch (JAXBException e) {
065                throw new RuntimeException("Could not create PullEndpoint", e);
066            }
067        }
068    
069        protected void initSession() throws JMSException {
070            if (session == null) {
071                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
072                queue = session.createQueue(getName());
073                producer = session.createProducer(queue);
074                consumer = session.createConsumer(queue);
075            }
076        }
077    
078        @Override
079        protected synchronized void store(NotificationMessageHolderType messageHolder) {
080            try {
081                initSession();
082                Notify notify = new Notify();
083                notify.getNotificationMessage().add(messageHolder);
084                StringWriter writer = new StringWriter();
085                jaxbContext.createMarshaller().marshal(notify, writer);
086                Message message = session.createTextMessage(writer.toString());
087                producer.send(message);
088            } catch (JMSException e) {
089                log.warn("Error storing message", e);
090                if (session != null) {
091                    try {
092                        session.close();
093                    } catch (JMSException inner) {
094                        log.debug("Error closing session", inner);
095                    } finally {
096                        session = null;
097                    }
098                }
099            } catch (JAXBException e) {
100                log.warn("Error storing message", e);
101            }
102        }
103    
104        @Override
105        protected synchronized List<NotificationMessageHolderType> getMessages(int max) throws ResourceUnknownFault,
106                UnableToGetMessagesFault {
107            Session jmsSession = null;
108            try {
109                if (max == 0) {
110                    max = 256;
111                }
112                initSession();
113                List<NotificationMessageHolderType> messages = new ArrayList<NotificationMessageHolderType>();
114                for (int i = 0; i < max; i++) {
115                    Message msg = consumer.receiveNoWait();
116                    if (msg == null) {
117                        break;
118                    }
119                    TextMessage txtMsg = (TextMessage) msg;
120                    StringReader reader = new StringReader(txtMsg.getText());
121                    Notify notify = (Notify) jaxbContext.createUnmarshaller().unmarshal(reader);
122                    messages.addAll(notify.getNotificationMessage());
123                }
124                return messages;
125            } catch (JMSException e) {
126                log.info("Error retrieving messages", e);
127                if (jmsSession != null) {
128                    try {
129                        jmsSession.close();
130                    } catch (JMSException inner) {
131                        log.debug("Error closing session", inner);
132                    } finally {
133                        jmsSession = null;
134                    }
135                }
136                UnableToGetMessagesFaultType fault = new UnableToGetMessagesFaultType();
137                throw new UnableToGetMessagesFault("Unable to retrieve messages", fault, e);
138            } catch (JAXBException e) {
139                log.info("Error retrieving messages", e);
140                UnableToGetMessagesFaultType fault = new UnableToGetMessagesFaultType();
141                throw new UnableToGetMessagesFault("Unable to retrieve messages", fault, e);
142            }
143        }
144    
145        public Connection getConnection() {
146            return connection;
147        }
148    
149        public void setConnection(Connection connection) {
150            this.connection = connection;
151        }
152    
153    }