SocketThread.java :  » Net » jMOS » com » aranova » java » jmos » Java Open Source

Java Open Source » Net » jMOS 
jMOS » com » aranova » java » jmos » SocketThread.java
/*
 * File: SocketThread.java
 * Project: jMOS, com.aranova.java.jmos
 * Revision: 0.9 - Inicial
 * Date: 30-sep-2005 12:16:45
 *
 * Copyright (C) Aragn Innovacin Tecnolgica S.L.L.
 * All rights reserved.
 *
 * This software is distributed under the terms of the Aranova License version 1.0.
 * See the terms of the Aranova License in the documentation provided with this software.
 */

package com.aranova.java.jmos;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Map;
import java.util.Observable;

import javax.xml.parsers.SAXParser;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.aranova.java.jmos.handler.MOSHandler;
import com.aranova.java.jmos.io.XMLInputStream;
import com.aranova.java.jmos.messages.Message;
import com.aranova.java.jmos.util.Common;

/**
 * Clase de uso interno para gestionar las socket del servidor.
 *
 * @author <a href="http://www.aranova.net/contactar/">Daniel Snchez</a>
 * @version     0.9.1
 * @since       0.9
 */
public class SocketThread extends Observable implements Runnable {
  private static final Log _log = LogFactory.getLog(SocketThread.class);

  private boolean _isShutDown;
  private final Socket _socket;
  private final MOSHandler _handler;
  private final SAXParser _reader;
  private final InputStream _inputStream;
  private final OutputStream _outputStream;
  private final XMLStreamWriter _writer;
  private final XMLInputStream _XMLis;
  private final InputSource _inputSource;

  private final Map <IServerMOS, MessageFilter[]> _listeners;
  /**
   * Constructor del socket.
   * @param socket
   * @param listeners
   * @throws Exception
   */
  public SocketThread(final Socket socket, final Map <IServerMOS, MessageFilter[]> listeners) throws Exception {
    super();
    _isShutDown = false;
    _socket = socket;
    try {
      _inputStream = _socket.getInputStream();
      _outputStream = _socket.getOutputStream();
      _writer = Common.getOutputFactory().createXMLStreamWriter(_outputStream, Common.getEncoding());
      _XMLis = new XMLInputStream(_inputStream);
      _inputSource = new InputSource(_XMLis);
      _inputSource.setEncoding(Common.getEncoding());
      _handler = new MOSHandler(_XMLis);
      _reader = Common.getParserFactory().newSAXParser();
      _listeners = listeners;
    } catch (SAXException e) {
      throw e;
    } catch (IOException e) {
      throw e;
    } catch (XMLStreamException e) {
      throw e;
    }
  }

  /**
   * Cierra la conezin con el cliente.
   * @throws IOException
   */
  public final void close() throws IOException {
    try {
      _isShutDown = true;
      _socket.close();
    } catch (IOException e) {
      _log.warn("Error cerrando el socket", e);
      throw e;
    }
  }

  public final void run() {
    Message message;
    boolean error = false;
    try {
      while (true) {
        try {
          _reader.parse(_inputSource, _handler);
        } catch (SAXException e) {
          if (!e.getMessage().equals("createMessage")) {
            throw e;
          }
          error = true;
        }
        if (!error) {
          message = _handler.getMessage();

          //TODO Si el mensaje no es para mi MOSid o NCS id error NOACK o RO ACK.
          notifyListeners(message);
        } else {
          error = false;
          //TODO Write noack o roACk
        }
        _writer.flush();
        _reader.reset();
        if (_log.isTraceEnabled()) {
          long time = System.currentTimeMillis() - _handler.getStart();
          _log.trace("Total time: " + time + "ms - Parse time: " + _handler.getTime() + "ms");
        }
      }
    } catch (XMLStreamException e) {
      _log.error("Error al escribir en el socket.", e);
    } catch (SAXException e) {
      if (_XMLis.getMarcaInicio()) {
        _log.error("Error al parsear el XML.", e);
      }
    } catch (IOException e) {
      if (!_isShutDown) {
        _log.error("Error de IO en el socket.", e);
      }
    } finally {
      try {
        _log.info("Cerrando el socket");
        _socket.close();
      } catch (IOException e) {
        _log.error("Error al cerrar el socket.", e);
      }

      if (!_isShutDown) {
            this.setChanged();
            this.notifyObservers(this);
      }
    }
  }

  private void notifyListeners(final Message message) throws XMLStreamException {
    for (IServerMOS listener : _listeners.keySet()) {
      boolean filtroOK = true;
      for (MessageFilter filter : _listeners.get(listener)) {
        if (!filter.accept(Message.getMessages().get(message.getName()).getMessage())) {
          filtroOK = false;
          break;
        }
      }
      if (filtroOK) {
        if (listener instanceof IServerReplier) {
          ((IServerReplier)listener).message(message, _writer);
        } else if (listener instanceof IServerListener) {
          ((IServerListener)listener).message(message);
        }
      }
    }
  }
}
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.