/*
* 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);
}
}
}
}
}
|