com.zextras.modules.chat.server.xmpp.netty.StanzaWriterImp.java Source code

Java tutorial

Introduction

Here is the source code for com.zextras.modules.chat.server.xmpp.netty.StanzaWriterImp.java

Source

/*
 * ZAL - The abstraction layer for Zimbra.
 * Copyright (C) 2017 ZeXtras S.r.l.
 *
 * This file is part of ZAL.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, version 2 of
 * the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZAL. If not, see <http://www.gnu.org/licenses/>.
 */

package com.zextras.modules.chat.server.xmpp.netty;

import com.zextras.lib.log.ChatLog;
import com.zextras.lib.log.CurrentLogContext;
import com.zextras.lib.log.LogContext;
import com.zextras.modules.chat.server.events.EventInterceptorFactory;
import com.zextras.modules.chat.server.events.EventManager;
import com.zextras.modules.chat.server.events.EventQueue;
import com.zextras.modules.chat.server.address.SpecificAddress;
import com.zextras.modules.chat.server.events.Event;
import com.zextras.modules.chat.server.interceptors.EventInterceptor;
import com.zextras.modules.chat.server.xmpp.encoders.XmppEncoder;
import com.zextras.modules.chat.server.xmpp.encoders.XmppEncoderFactory;
import org.openzal.zal.Utils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;

import java.io.ByteArrayOutputStream;

public class StanzaWriterImp implements StanzaWriter {
    private final XmppEncoderFactory mEncoderFactory;
    private final StanzaProcessor.XmppConnectionHandler mXmppConnectionHandler;
    private final EventManager mEventManager;
    private final EventInterceptorFactory mXmppEventInterceptorFactory;

    public StanzaWriterImp(XmppEncoderFactory encoderFactory,
            StanzaProcessor.XmppConnectionHandler xmppConnectionHandler, EventManager eventManager,
            EventInterceptorFactory xmppEventInterceptorFactory) {
        mEncoderFactory = encoderFactory;
        mXmppConnectionHandler = xmppConnectionHandler;
        mEventManager = eventManager;
        mXmppEventInterceptorFactory = xmppEventInterceptorFactory;
    }

    @Override
    public void onAttached(EventQueue eventQueue) {
    }

    @Override
    public void onDetached(EventQueue eventQueue) {
    }

    @Override
    public void onEventQueued(EventQueue eventQueue, Event queuedEvent) {
    }

    @Override
    public void onEventQueued(EventQueue eventQueue) {
        try {
            final ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
            for (Event event : eventQueue.popAllEvents()) {
                LogContext logContext = CurrentLogContext.begin();
                if (event.getTarget().getAddresses().size() == 1) {
                    logContext.setAccountName(event.getTarget().toSingleAddress());
                }
                logContext.freeze();
                try {
                    out.reset();
                    XmppEncoder encoder = (XmppEncoder) event.interpret(mEncoderFactory);
                    if (encoder == null) {
                        ChatLog.log.debug("No encoder found for event " + event.getClass().getName());
                        continue;
                    }

                    final SpecificAddress exposedAddress = mXmppConnectionHandler.getSession().getExposedAddress();

                    encoder.encode(out, exposedAddress);

                    String stanzaDebug = new String(out.toByteArray(), "UTF-8");
                    ChatLog.log.debug("writing: " + event.getClass().getName());
                    ChatLog.log.debug("writing stanza(" + stanzaDebug.length() + "): " + stanzaDebug);
                    ByteBuf stanza = Unpooled.copiedBuffer(out.toByteArray());
                    ChannelFuture writeFuture = mXmppConnectionHandler.write(stanza);

                    final Event eventToNotify = event;

                    writeFuture.addListener(new ChannelFutureListener() {
                        @Override
                        public void operationComplete(ChannelFuture future) throws Exception {
                            if (future.isSuccess()) {
                                EventInterceptor interceptor = eventToNotify
                                        .interpret(mXmppEventInterceptorFactory);
                                interceptor.intercept(mEventManager, exposedAddress);
                            }
                        }
                    });
                } finally {
                    CurrentLogContext.end();
                }
            }
        } catch (Throwable ex) {
            ChatLog.log.warn("Exception: " + Utils.exceptionToString(ex));
        }
    }

    @Override
    public void onEventPopped(EventQueue eventQueue, Event poppedEvent) {
    }

    @Override
    public void onQueueFlushed(EventQueue eventQueue) {
    }

    @Override
    public void onEventRemoved(EventQueue eventQueue, Event event) {
    }
}