001    /**
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * 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     **/
018    package org.activemq.util;
019    
020    import org.apache.log4j.AppenderSkeleton;
021    import org.apache.log4j.spi.LoggingEvent;
022    
023    import javax.jms.Connection;
024    import javax.jms.Destination;
025    import javax.jms.JMSException;
026    import javax.jms.Message;
027    import javax.jms.MessageProducer;
028    import javax.jms.Session;
029    import javax.naming.NamingException;
030    import java.io.Serializable;
031    import java.util.ArrayList;
032    import java.util.Iterator;
033    import java.util.List;
034    
035    /**
036     * An abstract base class for implementation inheritence for a log4j JMS appender
037     *
038     * @version $Revision: 1.1.1.1 $
039     */
040    public abstract class JmsLogAppenderSupport extends AppenderSkeleton {
041    
042        public static final int JMS_PUBLISH_ERROR_CODE = 61616;
043    
044        private Connection connection;
045        private Session session;
046        private MessageProducer producer;
047        private boolean allowTextMessages = true;
048        private String subjectPrefix = "log4j.";
049    
050        public JmsLogAppenderSupport() {
051        }
052    
053        public Connection getConnection() throws JMSException, NamingException {
054            if (connection == null) {
055                connection = createConnection();
056            }
057            return connection;
058        }
059    
060        public void setConnection(Connection connection) {
061            this.connection = connection;
062        }
063    
064        public Session getSession() throws JMSException, NamingException {
065            if (session == null) {
066                session = createSession();
067            }
068            return session;
069        }
070    
071        public void setSession(Session session) {
072            this.session = session;
073        }
074    
075        public MessageProducer getProducer() throws JMSException, NamingException {
076            if (producer == null) {
077                producer = createProducer();
078            }
079            return producer;
080        }
081    
082        public void setProducer(MessageProducer producer) {
083            this.producer = producer;
084        }
085    
086        public void close() {
087            List errors = new ArrayList();
088            if (producer != null) {
089                try {
090                    producer.close();
091                }
092                catch (JMSException e) {
093                    errors.add(e);
094                }
095            }
096            if (session != null) {
097                try {
098                    session.close();
099                }
100                catch (JMSException e) {
101                    errors.add(e);
102                }
103            }
104            if (connection != null) {
105                try {
106                    connection.close();
107                }
108                catch (JMSException e) {
109                    errors.add(e);
110                }
111            }
112            for (Iterator iter = errors.iterator(); iter.hasNext();) {
113                JMSException e = (JMSException) iter.next();
114                getErrorHandler().error("Error closing JMS resources: " + e, e, JMS_PUBLISH_ERROR_CODE);
115            }
116        }
117    
118        public boolean requiresLayout() {
119            return false;
120        }
121    
122        public void activateOptions() {
123            try {
124                // lets ensure we're all created
125                getProducer();
126            }
127            catch (Exception e) {
128                getErrorHandler().error("Could not create JMS resources: " + e, e, JMS_PUBLISH_ERROR_CODE);
129            }
130        }
131    
132    
133        // Implementation methods
134        //-------------------------------------------------------------------------
135        protected abstract Connection createConnection() throws JMSException, NamingException;
136    
137        protected Session createSession() throws JMSException, NamingException {
138            return getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
139        }
140    
141        protected MessageProducer createProducer() throws JMSException, NamingException {
142            return getSession().createProducer(null);
143        }
144    
145        protected void append(LoggingEvent event) {
146            System.out.println("#### Calling append with event: " + event);
147            try {
148                Message message = createMessage(event);
149                Destination destination = getDestination(event);
150                getProducer().send(destination, message);
151            }
152            catch (Exception e) {
153                getErrorHandler().error("Could not send message due to: " + e, e, JMS_PUBLISH_ERROR_CODE, event);
154            }
155        }
156    
157        protected Message createMessage(LoggingEvent event) throws JMSException, NamingException {
158            Message answer = null;
159            Object value = event.getMessage();
160            if (allowTextMessages && value instanceof String) {
161                answer = getSession().createTextMessage((String) value);
162            }
163            else {
164                answer = getSession().createObjectMessage((Serializable) value);
165            }
166            answer.setStringProperty("level", event.getLevel().toString());
167            answer.setIntProperty("levelInt", event.getLevel().toInt());
168            answer.setStringProperty("threadName", event.getThreadName());
169            return answer;
170        }
171    
172        protected Destination getDestination(LoggingEvent event) throws JMSException, NamingException {
173            String name = subjectPrefix + event.getLoggerName();
174            return getSession().createTopic(name);
175        }
176    }