13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Copyright 2003-2005 Arthur van Hoff, Rick Blair 23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Licensed under Apache License version 2.0 33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Original license LGPL 43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl; 63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.ByteArrayOutputStream; 83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.IOException; 93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.OutputStream; 103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.Inet4Address; 113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.Inet6Address; 123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.net.InetAddress; 133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.ArrayList; 143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collection; 153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collections; 163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Enumeration; 173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.HashMap; 183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Hashtable; 193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.LinkedHashSet; 203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.List; 213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Map; 223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Set; 233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Vector; 243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Level; 253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger; 263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceEvent; 283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceInfo; 293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.DNSRecord.Pointer; 303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.DNSRecord.Service; 313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.DNSRecord.Text; 323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordClass; 333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordType; 343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSState; 353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.tasks.DNSTask; 363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * JmDNS service information. 393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Arthur van Hoff, Jeff Sonstein, Werner Randelshofer 413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic class ServiceInfoImpl extends ServiceInfo implements DNSListener, DNSStatefulObject { 433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger = Logger.getLogger(ServiceInfoImpl.class.getName()); 443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _domain; 463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _protocol; 473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _application; 483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _name; 493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _subtype; 503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private String _server; 513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private int _port; 523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private int _weight; 533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private int _priority; 543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private byte _text[]; 553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private Map<String, byte[]> _props; 563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final Set<Inet4Address> _ipv4Addresses; 573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final Set<Inet6Address> _ipv6Addresses; 583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private transient String _key; 603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private boolean _persistent; 623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private boolean _needTextAnnouncing; 633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ServiceInfoState _state; 653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private Delegate _delegate; 673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static interface Delegate { 693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void textValueUpdated(ServiceInfo target, byte[] value); 713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final static class ServiceInfoState extends DNSStatefulObject.DefaultImplementation { 753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static final long serialVersionUID = 1104131034952196820L; 773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ServiceInfoImpl _info; 793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param info 823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoState(ServiceInfoImpl info) { 843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _info = info; 863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected void setTask(DNSTask task) { 903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super.setTask(task); 913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((this._task == null) && _info.needTextAnnouncing()) { 923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.lock(); 933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((this._task == null) && _info.needTextAnnouncing()) { 953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this._state.isAnnounced()) { 963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.setState(DNSState.ANNOUNCING_1); 973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getDns() != null) { 983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getDns().startAnnouncer(); 993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _info.setNeedTextAnnouncing(false); 1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } finally { 1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.unlock(); 1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void setDns(JmDNSImpl dns) { 1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super.setDns(dns); 1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param type 1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param name 1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param subtype 1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param port 1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param weight 1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param priority 1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param persistent 1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param text 1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, String) 1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, String text) { 1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, (byte[]) null); 1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _server = text; 1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ByteArrayOutputStream out = new ByteArrayOutputStream(text.length()); 1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman writeUTF(out, text); 1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = out.toByteArray(); 1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (IOException e) { 1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new RuntimeException("unexpected exception: " + e); 1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param type 1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param name 1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param subtype 1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param port 1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param weight 1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param priority 1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param persistent 1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param props 1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, Map) 1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, Map<String, ?> props) { 1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, textFromProperties(props)); 1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param type 1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param name 1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param subtype 1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param port 1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param weight 1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param priority 1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param persistent 1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param text 1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#create(String, String, int, int, int, byte[]) 1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoImpl(String type, String name, String subtype, int port, int weight, int priority, boolean persistent, byte text[]) { 1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this(ServiceInfoImpl.decodeQualifiedNameMap(type, name, subtype), port, weight, priority, persistent, text); 1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, Map<String, ?> props) { 1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this(qualifiedNameMap, port, weight, priority, persistent, textFromProperties(props)); 1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, String text) { 1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this(qualifiedNameMap, port, weight, priority, persistent, (byte[]) null); 1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _server = text; 1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ByteArrayOutputStream out = new ByteArrayOutputStream(text.length()); 1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman writeUTF(out, text); 1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = out.toByteArray(); 1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (IOException e) { 1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new RuntimeException("unexpected exception: " + e); 1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfoImpl(Map<Fields, String> qualifiedNameMap, int port, int weight, int priority, boolean persistent, byte text[]) { 1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<Fields, String> map = ServiceInfoImpl.checkQualifiedNameMap(qualifiedNameMap); 1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._domain = map.get(Fields.Domain); 1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._protocol = map.get(Fields.Protocol); 1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._application = map.get(Fields.Application); 1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._name = map.get(Fields.Instance); 1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._subtype = map.get(Fields.Subtype); 1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._port = port; 1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._weight = weight; 1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._priority = priority; 1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = text; 1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.setNeedTextAnnouncing(false); 1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state = new ServiceInfoState(this); 2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._persistent = persistent; 2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet4Address>()); 2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet6Address>()); 2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * During recovery we need to duplicate service info to reregister them 2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param info 2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfoImpl(ServiceInfo info) { 2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv4Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet4Address>()); 2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv6Addresses = Collections.synchronizedSet(new LinkedHashSet<Inet6Address>()); 2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (info != null) { 2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._domain = info.getDomain(); 2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._protocol = info.getProtocol(); 2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._application = info.getApplication(); 2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._name = info.getName(); 2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._subtype = info.getSubtype(); 2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._port = info.getPort(); 2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._weight = info.getWeight(); 2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._priority = info.getPriority(); 2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = info.getTextBytes(); 2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._persistent = info.isPersistent(); 2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet6Address[] ipv6Addresses = info.getInet6Addresses(); 2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (Inet6Address address : ipv6Addresses) { 2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv6Addresses.add(address); 2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet4Address[] ipv4Addresses = info.getInet4Addresses(); 2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (Inet4Address address : ipv4Addresses) { 2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._ipv4Addresses.add(address); 2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state = new ServiceInfoState(this); 2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static Map<Fields, String> decodeQualifiedNameMap(String type, String name, String subtype) { 2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<Fields, String> qualifiedNameMap = decodeQualifiedNameMapForType(type); 2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Instance, name); 2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Subtype, subtype); 2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return checkQualifiedNameMap(qualifiedNameMap); 2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static Map<Fields, String> decodeQualifiedNameMapForType(String type) { 2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int index; 2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String casePreservedType = type; 2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String aType = type.toLowerCase(); 2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String application = aType; 2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String protocol = ""; 2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String subtype = ""; 2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String name = ""; 2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String domain = ""; 2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (aType.contains("in-addr.arpa") || aType.contains("ip6.arpa")) { 2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = (aType.contains("in-addr.arpa") ? aType.indexOf("in-addr.arpa") : aType.indexOf("ip6.arpa")); 2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman name = removeSeparators(casePreservedType.substring(0, index)); 2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman domain = casePreservedType.substring(index); 2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = ""; 2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else if ((!aType.contains("_")) && aType.contains(".")) { 2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = aType.indexOf('.'); 2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman name = removeSeparators(casePreservedType.substring(0, index)); 2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman domain = removeSeparators(casePreservedType.substring(index)); 2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = ""; 2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // First remove the name if it there. 2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!aType.startsWith("_") || aType.startsWith("_services")) { 2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = aType.indexOf('.'); 2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (index > 0) { 2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We need to preserve the case for the user readable name. 2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman name = casePreservedType.substring(0, index); 2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (index + 1 < aType.length()) { 2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aType = aType.substring(index + 1); 2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman casePreservedType = casePreservedType.substring(index + 1); 2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = aType.lastIndexOf("._"); 2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (index > 0) { 2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int start = index + 2; 2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int end = aType.indexOf('.', start); 2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protocol = casePreservedType.substring(start, end); 2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (protocol.length() > 0) { 2883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = aType.indexOf("_" + protocol.toLowerCase() + "."); 2893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int start = index + protocol.length() + 2; 2903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int end = aType.length() - (aType.endsWith(".") ? 1 : 0); 2913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman domain = casePreservedType.substring(start, end); 2923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = casePreservedType.substring(0, index - 1); 2933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman index = application.toLowerCase().indexOf("._sub"); 2953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (index > 0) { 2963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int start = index + 5; 2973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman subtype = removeSeparators(application.substring(0, index)); 2983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = application.substring(start); 2993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final Map<Fields, String> qualifiedNameMap = new HashMap<Fields, String>(5); 3033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Domain, removeSeparators(domain)); 3043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Protocol, protocol); 3053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Application, removeSeparators(application)); 3063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Instance, name); 3073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman qualifiedNameMap.put(Fields.Subtype, subtype); 3083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return qualifiedNameMap; 3103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected static Map<Fields, String> checkQualifiedNameMap(Map<Fields, String> qualifiedNameMap) { 3133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<Fields, String> checkedQualifiedNameMap = new HashMap<Fields, String>(5); 3143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Optional domain 3163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String domain = (qualifiedNameMap.containsKey(Fields.Domain) ? qualifiedNameMap.get(Fields.Domain) : "local"); 3173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((domain == null) || (domain.length() == 0)) { 3183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman domain = "local"; 3193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman domain = removeSeparators(domain); 3213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman checkedQualifiedNameMap.put(Fields.Domain, domain); 3223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Optional protocol 3233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String protocol = (qualifiedNameMap.containsKey(Fields.Protocol) ? qualifiedNameMap.get(Fields.Protocol) : "tcp"); 3243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((protocol == null) || (protocol.length() == 0)) { 3253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protocol = "tcp"; 3263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protocol = removeSeparators(protocol); 3283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman checkedQualifiedNameMap.put(Fields.Protocol, protocol); 3293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Application 3303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String application = (qualifiedNameMap.containsKey(Fields.Application) ? qualifiedNameMap.get(Fields.Application) : ""); 3313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((application == null) || (application.length() == 0)) { 3323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = ""; 3333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman application = removeSeparators(application); 3353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman checkedQualifiedNameMap.put(Fields.Application, application); 3363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Instance 3373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String instance = (qualifiedNameMap.containsKey(Fields.Instance) ? qualifiedNameMap.get(Fields.Instance) : ""); 3383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((instance == null) || (instance.length() == 0)) { 3393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman instance = ""; 3403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // throw new IllegalArgumentException("The instance name component of a fully qualified service cannot be empty."); 3413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman instance = removeSeparators(instance); 3433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman checkedQualifiedNameMap.put(Fields.Instance, instance); 3443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Optional Subtype 3453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String subtype = (qualifiedNameMap.containsKey(Fields.Subtype) ? qualifiedNameMap.get(Fields.Subtype) : ""); 3463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((subtype == null) || (subtype.length() == 0)) { 3473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman subtype = ""; 3483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman subtype = removeSeparators(subtype); 3503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman checkedQualifiedNameMap.put(Fields.Subtype, subtype); 3513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return checkedQualifiedNameMap; 3533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static String removeSeparators(String name) { 3563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (name == null) { 3573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return ""; 3583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String newName = name.trim(); 3603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (newName.startsWith(".")) { 3613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman newName = newName.substring(1); 3623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (newName.startsWith("_")) { 3643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman newName = newName.substring(1); 3653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (newName.endsWith(".")) { 3673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman newName = newName.substring(0, newName.length() - 1); 3683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return newName; 3703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getType() { 3773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String domain = this.getDomain(); 3783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String protocol = this.getProtocol(); 3793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String application = this.getApplication(); 3803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + "."; 3813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getTypeWithSubtype() { 3883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String subtype = this.getSubtype(); 3893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (subtype.length() > 0 ? "_" + subtype.toLowerCase() + "._sub." : "") + this.getType(); 3903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 3923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 3933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 3943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 3953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 3963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getName() { 3973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_name != null ? _name : ""); 3983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 3993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getKey() { 4053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this._key == null) { 4063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._key = this.getQualifiedName().toLowerCase(); 4073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._key; 4093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Sets the service instance name. 4133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 4143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param name 4153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * unqualified service instance name, such as <code>foobar</code> 4163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void setName(String name) { 4183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._name = name; 4193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._key = null; 4203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getQualifiedName() { 4273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String domain = this.getDomain(); 4283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String protocol = this.getProtocol(); 4293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String application = this.getApplication(); 4303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String instance = this.getName(); 4313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // String subtype = this.getSubtype(); 4323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // return (instance.length() > 0 ? instance + "." : "") + (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + (subtype.length() > 0 ? ",_" + subtype.toLowerCase() + "." : ".") : "") + domain 4333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // + "."; 4343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (instance.length() > 0 ? instance + "." : "") + (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + "."; 4353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getServer() 4393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getServer() { 4423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_server != null ? _server : ""); 4433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param server 4473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * the server to set 4483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void setServer(String server) { 4503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._server = server; 4513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 4573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getHostAddress() { 4593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String[] names = this.getHostAddresses(); 4603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (names.length > 0 ? names[0] : ""); 4613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 4673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String[] getHostAddresses() { 4683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet4Address[] ip4Aaddresses = this.getInet4Addresses(); 4693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet6Address[] ip6Aaddresses = this.getInet6Addresses(); 4703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String[] names = new String[ip4Aaddresses.length + ip6Aaddresses.length]; 4713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0; i < ip4Aaddresses.length; i++) { 4723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman names[i] = ip4Aaddresses[i].getHostAddress(); 4733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0; i < ip6Aaddresses.length; i++) { 4753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman names[i + ip4Aaddresses.length] = "[" + ip6Aaddresses[i].getHostAddress() + "]"; 4763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return names; 4783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param addr 4823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * the addr to add 4833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void addAddress(Inet4Address addr) { 4853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv4Addresses.add(addr); 4863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param addr 4903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * the addr to add 4913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void addAddress(Inet6Address addr) { 4933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv6Addresses.add(addr); 4943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 4953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 4963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 4973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 4983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 4993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 5003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress getAddress() { 5023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getInetAddress(); 5033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 5093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress getInetAddress() { 5113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress[] addresses = this.getInetAddresses(); 5123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (addresses.length > 0 ? addresses[0] : null); 5133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 5193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Inet4Address getInet4Address() { 5213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet4Address[] addresses = this.getInet4Addresses(); 5223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (addresses.length > 0 ? addresses[0] : null); 5233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 5293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Inet6Address getInet6Address() { 5313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet6Address[] addresses = this.getInet6Addresses(); 5323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (addresses.length > 0 ? addresses[0] : null); 5333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 5363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 5373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getInetAddresses() 5383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public InetAddress[] getInetAddresses() { 5413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman List<InetAddress> aList = new ArrayList<InetAddress>(_ipv4Addresses.size() + _ipv6Addresses.size()); 5423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aList.addAll(_ipv4Addresses); 5433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aList.addAll(_ipv6Addresses); 5443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return aList.toArray(new InetAddress[aList.size()]); 5453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 5483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 5493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getInet4Addresses() 5503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Inet4Address[] getInet4Addresses() { 5533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _ipv4Addresses.toArray(new Inet4Address[_ipv4Addresses.size()]); 5543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 5573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 5583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getInet6Addresses() 5593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Inet6Address[] getInet6Addresses() { 5623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _ipv6Addresses.toArray(new Inet6Address[_ipv6Addresses.size()]); 5633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getPort() 5673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int getPort() { 5703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _port; 5713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getPriority() 5753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int getPriority() { 5783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _priority; 5793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getWeight() 5833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int getWeight() { 5863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _weight; 5873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getTextBytes() 5913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 5923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 5933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public byte[] getTextBytes() { 5943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (this._text != null && this._text.length > 0 ? this._text : DNSRecord.EMPTY_TXT); 5953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 5963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 5973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 5983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 5993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 6013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getTextString() { 6033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<String, byte[]> properties = this.getProperties(); 6043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String key : properties.keySet()) { 6053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] value = properties.get(key); 6063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((value != null) && (value.length > 0)) { 6073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return key + "=" + new String(value); 6083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return key; 6103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return ""; 6123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 6153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 6163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getURL() 6173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 6193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getURL() { 6213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getURL("http"); 6223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 6253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 6263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getURLs() 6273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String[] getURLs() { 6303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getURLs("http"); 6313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 6343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 6353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getURL(java.lang.String) 6363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Deprecated 6383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getURL(String protocol) { 6403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String[] urls = this.getURLs(protocol); 6413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (urls.length > 0 ? urls[0] : protocol + "://null:" + getPort()); 6423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 6453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 6463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#getURLs(java.lang.String) 6473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String[] getURLs(String protocol) { 6503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress[] addresses = this.getInetAddresses(); 6513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String[] urls = new String[addresses.length]; 6523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0; i < addresses.length; i++) { 6533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String url = protocol + "://" + addresses[i].getHostAddress() + ":" + getPort(); 6543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String path = getPropertyString("path"); 6553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (path != null) { 6563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (path.indexOf("://") >= 0) { 6573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman url = path; 6583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 6593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman url += path.startsWith("/") ? path : "/" + path; 6603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman urls[i] = url; 6633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return urls; 6653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 6683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 6693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public synchronized byte[] getPropertyBytes(String name) { 6723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getProperties().get(name); 6733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 6763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 6773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public synchronized String getPropertyString(String name) { 6803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte data[] = this.getProperties().get(name); 6813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (data == null) { 6823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 6833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (data == NO_VALUE) { 6853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return "true"; 6863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return readUTF(data, 0, data.length); 6883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 6903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 6913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 6923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 6933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 6943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Enumeration<String> getPropertyNames() { 6953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<String, byte[]> properties = this.getProperties(); 6963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Collection<String> names = (properties != null ? properties.keySet() : Collections.<String> emptySet()); 6973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return new Vector<String>(names).elements(); 6983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 6993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 7023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 7043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getApplication() { 7053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_application != null ? _application : ""); 7063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 7103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 7123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getDomain() { 7133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_domain != null ? _domain : "local"); 7143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 7183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 7203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getProtocol() { 7213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_protocol != null ? _protocol : "tcp"); 7223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 7263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 7283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getSubtype() { 7293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_subtype != null ? _subtype : ""); 7303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 7343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 7363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Map<Fields, String> getQualifiedNameMap() { 7373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<Fields, String> map = new HashMap<Fields, String>(5); 7383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(Fields.Domain, this.getDomain()); 7403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(Fields.Protocol, this.getProtocol()); 7413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(Fields.Application, this.getApplication()); 7423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(Fields.Instance, this.getName()); 7433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman map.put(Fields.Subtype, this.getSubtype()); 7443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return map; 7453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Write a UTF string with a length to a stream. 7493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman static void writeUTF(OutputStream out, String str) throws IOException { 7513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0, len = str.length(); i < len; i++) { 7523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int c = str.charAt(i); 7533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((c >= 0x0001) && (c <= 0x007F)) { 7543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(c); 7553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 7563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (c > 0x07FF) { 7573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(0xE0 | ((c >> 12) & 0x0F)); 7583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(0x80 | ((c >> 6) & 0x3F)); 7593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(0x80 | ((c >> 0) & 0x3F)); 7603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 7613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(0xC0 | ((c >> 6) & 0x1F)); 7623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(0x80 | ((c >> 0) & 0x3F)); 7633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 7683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 7693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Read data bytes as a UTF stream. 7703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 7713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String readUTF(byte data[], int off, int len) { 7723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int offset = off; 7733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuffer buf = new StringBuffer(); 7743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int end = offset + len; offset < end;) { 7753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int ch = data[offset++] & 0xFF; 7763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman switch (ch >> 4) { 7773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 0: 7783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 1: 7793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 2: 7803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 3: 7813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 4: 7823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 5: 7833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 6: 7843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 7: 7853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // 0xxxxxxx 7863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 7873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 12: 7883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 13: 7893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (offset >= len) { 7903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 7913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // 110x xxxx 10xx xxxx 7933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ch = ((ch & 0x1F) << 6) | (data[offset++] & 0x3F); 7943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 7953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case 14: 7963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (offset + 2 >= len) { 7973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 7983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 7993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // 1110 xxxx 10xx xxxx 10xx xxxx 8003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ch = ((ch & 0x0f) << 12) | ((data[offset++] & 0x3F) << 6) | (data[offset++] & 0x3F); 8013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman default: 8033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (offset + 1 >= len) { 8043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return null; 8053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // 10xx xxxx, 1111 xxxx 8073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ch = ((ch & 0x3F) << 4) | (data[offset++] & 0x0f); 8083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append((char) ch); 8113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return buf.toString(); 8133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 8153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized Map<String, byte[]> getProperties() { 8163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((_props == null) && (this.getTextBytes() != null)) { 8173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Hashtable<String, byte[]> properties = new Hashtable<String, byte[]>(); 8183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 8193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int off = 0; 8203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman while (off < getTextBytes().length) { 8213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // length of the next key value pair 8223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int len = getTextBytes()[off++] & 0xFF; 8233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((len == 0) || (off + len > getTextBytes().length)) { 8243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman properties.clear(); 8253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // look for the '=' 8283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int i = 0; 8293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (; (i < len) && (getTextBytes()[off + i] != '='); i++) { 8303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* Stub */ 8313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 8333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // get the property name 8343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String name = readUTF(getTextBytes(), off, i); 8353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (name == null) { 8363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman properties.clear(); 8373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (i == len) { 8403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman properties.put(name, NO_VALUE); 8413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 8423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte value[] = new byte[len - ++i]; 8433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman System.arraycopy(getTextBytes(), off + i, value, 0, len - i); 8443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman properties.put(name, value); 8453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman off += len; 8463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (Exception exception) { 8493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We should get better logging. 8503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.log(Level.WARNING, "Malformed TXT Field ", exception); 8513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._props = properties; 8533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_props != null ? _props : Collections.<String, byte[]> emptyMap()); 8553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 8573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 8583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * JmDNS callback to update a DNS record. 8593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 8603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param dnsCache 8613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param now 8623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param rec 8633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 8643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 8653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void updateRecord(DNSCache dnsCache, long now, DNSEntry rec) { 8663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((rec instanceof DNSRecord) && !rec.isExpired(now)) { 8673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman boolean serviceUpdated = false; 8683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman switch (rec.getRecordType()) { 8693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_A: // IPv4 8703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (rec.getName().equalsIgnoreCase(this.getServer())) { 8713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv4Addresses.add((Inet4Address) ((DNSRecord.Address) rec).getAddress()); 8723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceUpdated = true; 8733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_AAAA: // IPv6 8763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (rec.getName().equalsIgnoreCase(this.getServer())) { 8773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv6Addresses.add((Inet6Address) ((DNSRecord.Address) rec).getAddress()); 8783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceUpdated = true; 8793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 8813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_SRV: 8823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) { 8833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord.Service srv = (DNSRecord.Service) rec; 8843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman boolean serverChanged = (_server == null) || !_server.equalsIgnoreCase(srv.getServer()); 8853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _server = srv.getServer(); 8863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _port = srv.getPort(); 8873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _weight = srv.getWeight(); 8883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _priority = srv.getPriority(); 8893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (serverChanged) { 8903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv4Addresses.clear(); 8913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _ipv6Addresses.clear(); 8923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN)) { 8933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.updateRecord(dnsCache, now, entry); 8943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN)) { 8963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.updateRecord(dnsCache, now, entry); 8973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 8983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // We do not want to trigger the listener in this case as it will be triggered if the address resolves. 8993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 9003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceUpdated = true; 9013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 9043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_TXT: 9053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) { 9063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSRecord.Text txt = (DNSRecord.Text) rec; 9073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _text = txt.getText(); 9083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _props = null; // set it null for apply update text data 9093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceUpdated = true; 9103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 9123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman case TYPE_PTR: 9133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((this.getSubtype().length() == 0) && (rec.getSubtype().length() != 0)) { 9143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _subtype = rec.getSubtype(); 9153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceUpdated = true; 9163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 9183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman default: 9193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 9203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (serviceUpdated && this.hasData()) { 9223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman JmDNSImpl dns = this.getDns(); 9233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (dns != null) { 9243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceEvent event = ((DNSRecord) rec).getServiceEvent(dns); 9253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman event = new ServiceEventImpl(dns, event.getType(), event.getName(), this); 9263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman dns.handleServiceResolved(event); 9273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // This is done, to notify the wait loop in method JmDNS.waitForInfoData(ServiceInfo info, int timeout); 9303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (this) { 9313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.notifyAll(); 9323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Returns true if the service info is filled with data. 9383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 9393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> if the service info has data, <code>false</code> otherwise. 9403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public synchronized boolean hasData() { 9433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getServer() != null && this.hasInetAddress() && this.getTextBytes() != null && this.getTextBytes().length > 0; 9443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // return this.getServer() != null && (this.getAddress() != null || (this.getTextBytes() != null && this.getTextBytes().length > 0)); 9453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final boolean hasInetAddress() { 9483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _ipv4Addresses.size() > 0 || _ipv6Addresses.size() > 0; 9493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // State machine 9523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean advanceState(DNSTask task) { 9583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.advanceState(task); 9593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean revertState() { 9663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.revertState(); 9673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean cancelState() { 9743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.cancelState(); 9753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean closeState() { 9823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.closeState(); 9833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean recoverState() { 9903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.recoverState(); 9913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 9923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 9933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 9943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 9953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 9963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 9973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void removeAssociationWithTask(DNSTask task) { 9983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _state.removeAssociationWithTask(task); 9993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void associateWithTask(DNSTask task, DNSState state) { 10063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _state.associateWithTask(task, state); 10073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAssociatedWithTask(DNSTask task, DNSState state) { 10143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isAssociatedWithTask(task, state); 10153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isProbing() { 10223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isProbing(); 10233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAnnouncing() { 10303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isAnnouncing(); 10313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isAnnounced() { 10383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isAnnounced(); 10393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isCanceling() { 10463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.isCanceling(); 10473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isCanceled() { 10543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isCanceled(); 10553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isClosing() { 10623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isClosing(); 10633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isClosed() { 10703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.isClosed(); 10713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean waitForAnnounced(long timeout) { 10783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.waitForAnnounced(timeout); 10793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean waitForCanceled(long timeout) { 10863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _state.waitForCanceled(timeout); 10873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 10923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 10933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int hashCode() { 10943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return getQualifiedName().hashCode(); 10953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 10963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 10973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 10983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 10993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 11003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 11013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean equals(Object obj) { 11023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (obj instanceof ServiceInfoImpl) && getQualifiedName().equals(((ServiceInfoImpl) obj).getQualifiedName()); 11033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 11053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 11063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 11073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 11083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 11093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getNiceTextString() { 11103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuffer buf = new StringBuffer(); 11113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0, len = this.getTextBytes().length; i < len; i++) { 11123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (i >= 200) { 11133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("..."); 11143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman break; 11153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman int ch = getTextBytes()[i] & 0xFF; 11173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((ch < ' ') || (ch > 127)) { 11183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("\\0"); 11193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(Integer.toString(ch, 8)); 11203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 11213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append((char) ch); 11223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return buf.toString(); 11253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 11273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 11283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 11293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see javax.jmdns.ServiceInfo#clone() 11303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 11313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 11323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceInfoImpl clone() { 11333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfoImpl serviceInfo = new ServiceInfoImpl(this.getQualifiedNameMap(), _port, _weight, _priority, _persistent, _text); 11343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet6Address[] ipv6Addresses = this.getInet6Addresses(); 11353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (Inet6Address address : ipv6Addresses) { 11363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceInfo._ipv6Addresses.add(address); 11373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Inet4Address[] ipv4Addresses = this.getInet4Addresses(); 11393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (Inet4Address address : ipv4Addresses) { 11403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman serviceInfo._ipv4Addresses.add(address); 11413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return serviceInfo; 11433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 11453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 11463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 11473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 11483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 11493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 11503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuilder buf = new StringBuilder(); 11513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this) + " "); 11523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("name: '"); 11533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append((this.getName().length() > 0 ? this.getName() + "." : "") + this.getTypeWithSubtype()); 11543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("' address: '"); 11553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman InetAddress[] addresses = this.getInetAddresses(); 11563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (addresses.length > 0) { 11573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (InetAddress address : addresses) { 11583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(address); 11593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(':'); 11603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(this.getPort()); 11613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(' '); 11623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 11643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("(null):"); 11653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(this.getPort()); 11663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("' status: '"); 11683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(_state.toString()); 11693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(this.isPersistent() ? "' is persistent," : "',"); 11703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(" has "); 11713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(this.hasData() ? "" : "NO "); 11723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("data"); 11733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getTextBytes().length > 0) { 11743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // buf.append("\n"); 11753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // buf.append(this.getNiceTextString()); 11763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Map<String, byte[]> properties = this.getProperties(); 11773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!properties.isEmpty()) { 11783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("\n"); 11793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String key : properties.keySet()) { 11803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append("\t" + key + ": " + new String(properties.get(key)) + "\n"); 11813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 11833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(" empty"); 11843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman buf.append(']'); 11873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return buf.toString(); 11883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 11903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Collection<DNSRecord> answers(boolean unique, int ttl, HostInfo localHost) { 11913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman List<DNSRecord> list = new ArrayList<DNSRecord>(); 11923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this.getSubtype().length() > 0) { 11933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(new Pointer(this.getTypeWithSubtype(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName())); 11943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 11953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(new Pointer(this.getType(), DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, ttl, this.getQualifiedName())); 11963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(new Service(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, _priority, _weight, _port, localHost.getName())); 11973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman list.add(new Text(this.getQualifiedName(), DNSRecordClass.CLASS_IN, unique, ttl, this.getTextBytes())); 11983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return list; 11993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 12033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 12053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void setText(byte[] text) throws IllegalStateException { 12063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized (this) { 12073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = text; 12083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._props = null; 12093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.setNeedTextAnnouncing(true); 12103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 12153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 12173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void setText(Map<String, ?> props) throws IllegalStateException { 12183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.setText(textFromProperties(props)); 12193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This is used internally by the framework 12233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 12243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param text 12253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void _setText(byte[] text) { 12273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._text = text; 12283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._props = null; 12293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static byte[] textFromProperties(Map<String, ?> props) { 12323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] text = null; 12333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (props != null) { 12343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 12353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ByteArrayOutputStream out = new ByteArrayOutputStream(256); 12363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String key : props.keySet()) { 12373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Object val = props.get(key); 12383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ByteArrayOutputStream out2 = new ByteArrayOutputStream(100); 12393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman writeUTF(out2, key); 12403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (val == null) { 12413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Skip 12423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else if (val instanceof String) { 12433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out2.write('='); 12443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman writeUTF(out2, (String) val); 12453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else if (val instanceof byte[]) { 12463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] bval = (byte[]) val; 12473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (bval.length > 0) { 12483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out2.write('='); 12493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out2.write(bval, 0, bval.length); 12503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 12513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman val = null; 12523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 12543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new IllegalArgumentException("invalid property value: " + val); 12553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte data[] = out2.toByteArray(); 12573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (data.length > 255) { 12583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new IOException("Cannot have individual values larger that 255 chars. Offending value: " + key + (val != null ? "" : "=" + val)); 12593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write((byte) data.length); 12613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman out.write(data, 0, data.length); 12623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman text = out.toByteArray(); 12643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (IOException e) { 12653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new RuntimeException("unexpected exception: " + e); 12663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (text != null && text.length > 0 ? text : DNSRecord.EMPTY_TXT); 12693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void setDns(JmDNSImpl dns) { 12723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._state.setDns(dns); 12733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 12773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 12793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public JmDNSImpl getDns() { 12803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._state.getDns(); 12813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * {@inheritDoc} 12853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 12873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isPersistent() { 12883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _persistent; 12893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 12903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 12913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 12923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param needTextAnnouncing 12933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * the needTextAnnouncing to set 12943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 12953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public void setNeedTextAnnouncing(boolean needTextAnnouncing) { 12963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._needTextAnnouncing = needTextAnnouncing; 12973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (this._needTextAnnouncing) { 12983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _state.setTask(null); 12993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 13003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 13013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 13023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 13033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return the needTextAnnouncing 13043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 13053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean needTextAnnouncing() { 13063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _needTextAnnouncing; 13073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 13083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 13093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 13103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return the delegate 13113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 13123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman Delegate getDelegate() { 13133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this._delegate; 13143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 13153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 13163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 13173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param delegate 13183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * the delegate to set 13193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 13203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void setDelegate(Delegate delegate) { 13213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this._delegate = delegate; 13223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 13233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 13243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman} 1325