IMAppender.java :  » ESB » wso2-esb » org » wso2 » esb » logging » Java Open Source

Java Open Source » ESB » wso2 esb 
wso2 esb » org » wso2 » esb » logging » IMAppender.java
/*
 * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * Licensed 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.
 */

/*
 * $Id: IMAppender.java,v 1.2 2003/07/02 22:00:08 luque Exp $
 *
 * Copyright (c) 2003. Orange Software S.L. All Rights Reserved.
 * Authored by Rafael Luque & Ruth Zamorano
 *
 * You may study, use, modify, and distribute this software for any
 * purpose provided that this copyright notice appears in all copies.
 *
 * This software is provided WITHOUT WARRANTY either expressed or
 * implied.
 *
 */

package org.wso2.esb.logging;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.CyclicBuffer;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.TriggeringEventEvaluator;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.GroupChat;
import org.jivesoftware.smack.SSLXMPPConnection;
import org.jivesoftware.smack.XMPPConnection;


/**
 * IMAppender appends tracing requests through instant
 * messaging network.
 *
 * @author Rafael Luque & Ruth Zamorano
 * @version $Revision: 1.2 $
 */

public class IMAppender extends AppenderSkeleton {

    // ----------------------------------------------- Variables

    private String host;
    private int port = 5222;
    private String username;
    private String password;
    private String recipient;
    private boolean chatroom = false;
    private String nickname;
    private boolean SSL = false;
    private int bufferSize = 16;

    protected TriggeringEventEvaluator evaluator;
    protected CyclicBuffer cb;
    protected XMPPConnection con;
    protected Chat chat;
    protected GroupChat groupchat;

    // -------------------------------------------- Constructors

    /**
     * The default constructor will instantiate the appender with a
     * default TriggeringEventEvaluator that will trigger on events
     * with level ERROR or higher.
     */
    public IMAppender() {
        this(new DefaultEvaluator());
    }

    public IMAppender(TriggeringEventEvaluator evaluator) {
        this.evaluator = evaluator;
    }

    // ------------------------------- Setter and getter methods

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return this.port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRecipient() {
        return this.recipient;
    }

    public void setRecipient(String recipient) {
        this.recipient = recipient;
    }

    public boolean isChatroom() {
        return this.chatroom;
    }

    public void setChatroom(boolean chatroom) {
        this.chatroom = chatroom;
    }

    public String getNickname() {
        return this.nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public boolean isSSL() {
        return this.SSL;
    }

    public void setSSL(boolean SSL) {
        this.SSL = SSL;
    }

    public int getBufferSize() {
        return this.bufferSize;
    }

    public void setBufferSize(int bufferSize) {
        this.bufferSize = bufferSize;
    }

    /**
     * The <b>EvaluatorClass</b> option takes a string value
     * representing the name of the class implementing the {@link
     * TriggeringEventEvaluator} interface. A corresponding object will
     * be instantiated and assigned as the triggering event evaluator
     * for the SMTPAppender.
     */
    public void setEvaluatorClass(String value) {
        evaluator = (TriggeringEventEvaluator)
                OptionConverter.instantiateByClassName(value,
                        TriggeringEventEvaluator.class, evaluator);
    }

    public String getEvaluatorClass() {
        return evaluator == null ? null : evaluator.getClass().getName();
    }

    // ---------------------------------- Log4j callback methods

    /**
     * Options are activated and become effective only after calling
     * this method.
     */
    public void activateOptions() {
        try {
            cb = new CyclicBuffer(bufferSize);

            // Create a connection to the XMPP server
            LogLog.debug("Stablishing connection with XMPP server");
            if (SSL) {
                con = new SSLXMPPConnection(host, port);
            } else {
                con = new XMPPConnection(host, port);
            }

            // Most servers require you to login before performing other tasks
            LogLog.debug("About to login as [" + username + "/" + password + "]");
            con.login(username, password);

            // Start a conversation with IMAddress
            if (chatroom) {
                LogLog.debug("About to create ChatGroup");
                groupchat = con.createGroupChat(recipient);
                LogLog.debug("About to join room");
                groupchat.join(nickname != null ? nickname : username);
            } else {
                chat = con.createChat(recipient);
            }

        } catch (Exception e) {
            errorHandler.error("Error while activating options for appender named [" +
                    name + "]", e, ErrorCode.GENERIC_FAILURE);
        }
    }


    /**
     * Close this IMAppender. Closing all resources used by the
     * appender. A closed appender cannot be re-opened.
     */
    public synchronized void close() {
        if (this.closed)
            return;

        LogLog.debug("Closing appender [" + name + "]");
        this.closed = true;

        // Closes the connection by setting presence to unavailable 
        // then closing the stream to the XMPP server. 
        if (con != null)
            con.close();

        // Help GC
        con = null;
        chat = null;
        groupchat = null;
    }


    /**
     * This method called by {@link AppenderSkeleton#doAppend} method
     * does most of the real appending work. Adds the event to a buffer
     * and checks if the event triggers a message to be sent.
     */
    public void append(LoggingEvent event) {

        // check pre-conditions
        if (!checkEntryConditions()) {
            return;
        }

        cb.add(event);
        if (evaluator.isTriggeringEvent(event)) {
            sendBuffer();
        }
    }


    /**
     * Send the contents of the cyclic buffer as an IM message.
     */
    protected void sendBuffer() {
        try {
            StringBuffer buf = new StringBuffer();

            int len = cb.length();
            for (int i = 0; i < len; i++) {
                LoggingEvent event = cb.get();
                buf.append(layout.format(event));
                // if layout doesn't handle exception, the appender has to do it
                if (layout.ignoresThrowable()) {
                    String[] s = event.getThrowableStrRep();
                    if (s != null) {
                        for (int j = 0; j < s.length; j++) {
                            buf.append(Layout.LINE_SEP);
                            buf.append(s[j]);
                        }
                    }
                }
            }

            if (chatroom) {
                groupchat.sendMessage(buf.toString());
            } else {
                chat.sendMessage(buf.toString());
            }

        } catch (Exception e) {
            errorHandler.error("Could not send message in IMAppender [" +
                    name + "]", e, ErrorCode.GENERIC_FAILURE);
        }
    }


    /**
     * This method determines if there is a sense in attempting to append.
     * <p/>
     * <p>It checks whether there is an output chat available  and also if
     * there is a set layout. If these checks fail, then the boolean
     * value <code>false</code> is returned.
     */
    protected boolean checkEntryConditions() {
        if ((this.chat == null) && (this.groupchat == null)) {
            errorHandler.error("Chat object not configured");
            return false;
        }

        if (this.layout == null) {
            errorHandler.error("No layout set for appender named [" + name + "]");
            return false;
        }
        return true;
    }


    /**
     * The IMAppender requires a layout. Hence, this method returns
     * <code>true</code>.
     */
    public boolean requiresLayout() {
        return true;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.