/* * Copyright (C) 2007 ETH Zurich * * This file is part of Fosstrak (www.fosstrak.org). * * Fosstrak is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * Fosstrak 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Fosstrak; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ package org.fosstrak.ale.client; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.apache.log4j.Logger; import org.fosstrak.ale.util.DeserializerUtil; import org.fosstrak.ale.wsdl.ale.epcglobal.ImplementationException; import org.fosstrak.ale.wsdl.ale.epcglobal.ImplementationExceptionResponse; import org.fosstrak.ale.xsd.ale.epcglobal.ECReports; import org.fosstrak.reader.rp.proxy.RPProxyException; /** * This class listen to a specified port for ec reports and notifies his subscribers about new ec reports. * * @author regli */ public class ReportHandler implements Runnable { /** the logger */ private static Logger log = Logger.getLogger(ReportHandler.class); /** the thread */ private final Thread thread; /** contains the subscribers of this ReportHandler */ private final List<ReportHandlerListener> listeners = new Vector<ReportHandlerListener>(); /** server socket to communicate with the ALE */ private final ServerSocket ss; /** * Constructor opens the server socket and starts the thread. * * @param port on which the ALE notifies * @throws ImplementationException if server socket could not be created on specified port. */ public ReportHandler(int port) throws ImplementationExceptionResponse { try { ss = new ServerSocket(port); } catch (IOException e) { throw new ImplementationExceptionResponse(e.getMessage()); } thread = new Thread(this); thread.start(); } /** * This mehtod adds a new subscriber to the list of listeners. * * @param listener to add to this ReportHandler */ public void addListener(ReportHandlerListener listener) { listeners.add(listener); } /** * This method removes a subscriber from the list of listeners. * * @param listener to remove from this ReportHandler */ public void removeListener(ReportHandlerListener listener) { listeners.remove(listener); } /** * This method contains the main loop of the thread, in which data is read from the socket * and forwarded to the method notifyListeners(). */ public void run() { while (true) { try { Socket s = ss.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); String data = in.readLine(); // ignore the HTTP header data = in.readLine(); data = in.readLine(); data = in.readLine(); data = in.readLine(); StringBuffer buffer = new StringBuffer(); while (null != data) { buffer.append(data); data = in.readLine(); } log.debug(buffer.toString()); // create a stream from the buffer InputStream parseStream = new ByteArrayInputStream( buffer.toString().getBytes()); // parse the string ECReports reports = DeserializerUtil.deserializeECReports(parseStream); if (null != reports) { notifyListeners(reports); } s.close(); } catch (Exception e) { log.error(String.format("Could not receive report: %s", e.getMessage())); } } } /** * This method stops the thread and closes the socket */ public void stop() { // stop thread if (thread.isAlive()) { thread.interrupt(); } // close socket try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } /** * This method starts the ReportHandler. * * @param args command line arguments, which can contain the port number * @throws RPProxyException if something goes wrong while creating the ReportHandler */ public static void main(String[] args) throws ImplementationExceptionResponse { int port = 9000; if (args.length == 1) { try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) {} } new ReportHandler(port); } // // private // /** * dispatch the reports. * * @param ecReports the reports. * @throws Exception */ private void notifyListeners(ECReports ecReports) throws Exception { Iterator<ReportHandlerListener> listenerIt = listeners.iterator(); while (listenerIt.hasNext()) { listenerIt.next().dataReceived(ecReports); } } }