/* This file is part of JFLICKS. JFLICKS 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, either version 3 of the License, or (at your option) any later version. JFLICKS 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 JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.discovery; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; /** * A job that runs and listens foe multipackets to supply a simple * "service discovery" for this project. * * @author Doug Barnum * @version 1.0 */ public class ServiceResponderJob extends BaseDiscoveryJob { private ServiceDescription serviceDescription; private ArrayList<String> clientList; /** * Constructor with our required argument. * * @param name The name of the service. */ public ServiceResponderJob(String name) { super(name); setClientList(new ArrayList<String>()); } /** * The ServiceDescription object defines the information that will be * returned when answering a query. * * @return The ServiceDescription instance. */ public ServiceDescription getServiceDescription() { return (serviceDescription); } /** * The ServiceDescription object defines the information that will be * returned when answering a query. * * @param sd The ServiceDescription instance. */ public void setServiceDescription(ServiceDescription sd) { serviceDescription = sd; } private ArrayList<String> getClientList() { return (clientList); } private void setClientList(ArrayList<String> l) { clientList = l; } private void add(String s) { ArrayList<String> l = getClientList(); if (l != null) { l.add(s); } } private boolean isInList(String s) { boolean result = false; ArrayList<String> l = getClientList(); if ((l != null) && (l.contains(s))) { result = true; } return (result); } private boolean isPrevious() { boolean result = false; DatagramPacket packet = getReceivedDatagramPacket(); if (packet != null) { String s = new String(packet.getData()); int pos = s.indexOf((char) 0); if (pos > -1) { s = s.substring(0, pos); } String tmp = "SERVICE QUERY " + getEncodedServiceName(); String id = s.substring(tmp.length()).trim(); result = isInList(id); if (!result) { add(id); } } return (result); } private boolean isQueryPacket() { boolean result = false; DatagramPacket packet = getReceivedDatagramPacket(); if (packet != null) { String s = new String(packet.getData()); int pos = s.indexOf((char) 0); if (pos > -1) { s = s.substring(0, pos); } result = s.startsWith("SERVICE QUERY " + getEncodedServiceName()); } return (result); } private DatagramPacket getReplyPacket() { DatagramPacket result = null; ServiceDescription descriptor = getServiceDescription(); if (descriptor != null) { StringBuilder buf = new StringBuilder(); try { buf.append("SERVICE REPLY " + getEncodedServiceName() + " "); buf.append(descriptor.toString()); byte[] bytes = buf.toString().getBytes(); result = new DatagramPacket(bytes, bytes.length); result.setAddress(getMulticastInetAddress()); result.setPort(getMulticastPort()); } catch (NullPointerException npe) { System.err.println("Unexpected exception: " + npe); npe.printStackTrace(); } } return (result); } /** * {@inheritDoc} */ public void start() { setTerminate(false); try { setMulticastInetAddress(InetAddress.getByName( ServiceConstants.MULTICAST_INET_ADDRESS)); setMulticastPort(ServiceConstants.MULTICAST_PORT); MulticastSocket socket = new MulticastSocket(getMulticastPort()); socket.joinGroup(getMulticastInetAddress()); socket.setSoTimeout(ServiceConstants.RESPONDER_SOCKET_TIMEOUT); setMulticastSocket(socket); } catch (UnknownHostException uhe) { System.err.println("Unexpected exception: " + uhe); uhe.printStackTrace(); setTerminate(true); } catch (IOException ex) { System.err.println("Unexpected exception: " + ex); ex.printStackTrace(); setTerminate(true); } } /** * {@inheritDoc} */ public void run() { byte[] buf = new byte[ServiceConstants.DATAGRAM_LENGTH]; DatagramPacket packet = new DatagramPacket(buf, buf.length); setReceivedDatagramPacket(packet); while (!isTerminate()) { try { Arrays.fill(buf, (byte) 0); MulticastSocket socket = getMulticastSocket(); if (socket != null) { socket.receive(packet); if (isQueryPacket()) { if (!isPrevious()) { DatagramPacket replyPacket = getReplyPacket(); setQueuedDatagramPacket(replyPacket); sendQueuedPacket(); } } } } catch (SocketTimeoutException ex) { // Nothing to do. } catch (IOException ex) { System.err.println("Unexpected exception: " + ex); } } } /** * {@inheritDoc} */ public void stop() { setTerminate(true); } }