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.oasis_open.docs.wsn.b_2.NotificationMessageHolderType;
039    import org.oasis_open.docs.wsn.b_2.Notify;
040    import org.oasis_open.docs.wsn.b_2.UnableToGetMessagesFaultType;
041    import org.oasis_open.docs.wsn.bw_2.UnableToGetMessagesFault;
042    import org.oasis_open.docs.wsrf.rw_2.ResourceUnknownFault;
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            try {
108                if (max == 0) {
109                    max = 256;
110                }
111                initSession();
112                List<NotificationMessageHolderType> messages = new ArrayList<NotificationMessageHolderType>();
113                for (int i = 0; i < max; i++) {
114                    Message msg = consumer.receiveNoWait();
115                    if (msg == null) {
116                        break;
117                    }
118                    TextMessage txtMsg = (TextMessage) msg;
119                    StringReader reader = new StringReader(txtMsg.getText());
120                    Notify notify = (Notify) jaxbContext.createUnmarshaller().unmarshal(reader);
121                    messages.addAll(notify.getNotificationMessage());
122                }
123                return messages;
124            } catch (JMSException e) {
125                log.info("Error retrieving messages", e);
126                if (session != null) {
127                    try {
128                        session.close();
129                    } catch (JMSException inner) {
130                        log.debug("Error closing session", inner);
131                    } finally {
132                        session = null;
133                    }
134                }
135                UnableToGetMessagesFaultType fault = new UnableToGetMessagesFaultType();
136                throw new UnableToGetMessagesFault("Unable to retrieve messages", fault, e);
137            } catch (JAXBException e) {
138                log.info("Error retrieving messages", e);
139                UnableToGetMessagesFaultType fault = new UnableToGetMessagesFaultType();
140                throw new UnableToGetMessagesFault("Unable to retrieve messages", fault, e);
141            }
142        }
143    
144        public Connection getConnection() {
145            return connection;
146        }
147    
148        public void setConnection(Connection connection) {
149            this.connection = connection;
150        }
151    
152    }