Home | History | Annotate | Download | only in jmdns
      1 // Copyright 2003-2005 Arthur van Hoff, Rick Blair
      2 // Licensed under Apache License version 2.0
      3 // Original license LGPL
      4 package javax.jmdns;
      5 
      6 import java.net.Inet4Address;
      7 import java.net.Inet6Address;
      8 import java.net.InetAddress;
      9 import java.util.Enumeration;
     10 import java.util.Map;
     11 
     12 import javax.jmdns.impl.ServiceInfoImpl;
     13 
     14 /**
     15  * <p>
     16  * The fully qualified service name is build using up to 5 components with the following structure:
     17  *
     18  * <pre>
     19  *            &lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.<br/>
     20  * &lt;Instance&gt;.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.<br/>
     21  * &lt;sub&gt;._sub.&lt;app&gt;.&lt;protocol&gt;.&lt;servicedomain&gt;.&lt;parentdomain&gt;.
     22  * </pre>
     23  *
     24  * <ol>
     25  * <li>&lt;servicedomain&gt;.&lt;parentdomain&gt;: This is the domain scope of the service typically "local.", but this can also be something similar to "in-addr.arpa." or "ip6.arpa."</li>
     26  * <li>&lt;protocol&gt;: This is either "_tcp" or "_udp"</li>
     27  * <li>&lt;app&gt;: This define the application protocol. Typical example are "_http", "_ftp", etc.</li>
     28  * <li>&lt;Instance&gt;: This is the service name</li>
     29  * <li>&lt;sub&gt;: This is the subtype for the application protocol</li>
     30  * </ol>
     31  * </p>
     32  */
     33 public abstract class ServiceInfo implements Cloneable {
     34 
     35     /**
     36      * This is the no value text byte. According top the specification it is one byte with 0 value.
     37      */
     38     public static final byte[] NO_VALUE = new byte[0];
     39 
     40     /**
     41      * Fields for the fully qualified map.
     42      */
     43     public enum Fields {
     44         /**
     45          * Domain Field.
     46          */
     47         Domain,
     48         /**
     49          * Protocol Field.
     50          */
     51         Protocol,
     52         /**
     53          * Application Field.
     54          */
     55         Application,
     56         /**
     57          * Instance Field.
     58          */
     59         Instance,
     60         /**
     61          * Subtype Field.
     62          */
     63         Subtype
     64     }
     65 
     66     /**
     67      * Construct a service description for registering with JmDNS.
     68      *
     69      * @param type
     70      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
     71      * @param name
     72      *            unqualified service instance name, such as <code>foobar</code>
     73      * @param port
     74      *            the local port on which the service runs
     75      * @param text
     76      *            string describing the service
     77      * @return new service info
     78      */
     79     public static ServiceInfo create(final String type, final String name, final int port, final String text) {
     80         return new ServiceInfoImpl(type, name, "", port, 0, 0, false, text);
     81     }
     82 
     83     /**
     84      * Construct a service description for registering with JmDNS.
     85      *
     86      * @param type
     87      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
     88      * @param name
     89      *            unqualified service instance name, such as <code>foobar</code>
     90      * @param subtype
     91      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
     92      * @param port
     93      *            the local port on which the service runs
     94      * @param text
     95      *            string describing the service
     96      * @return new service info
     97      */
     98     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final String text) {
     99         return new ServiceInfoImpl(type, name, subtype, port, 0, 0, false, text);
    100     }
    101 
    102     /**
    103      * Construct a service description for registering with JmDNS.
    104      *
    105      * @param type
    106      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    107      * @param name
    108      *            unqualified service instance name, such as <code>foobar</code>
    109      * @param port
    110      *            the local port on which the service runs
    111      * @param weight
    112      *            weight of the service
    113      * @param priority
    114      *            priority of the service
    115      * @param text
    116      *            string describing the service
    117      * @return new service info
    118      */
    119     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final String text) {
    120         return new ServiceInfoImpl(type, name, "", port, weight, priority, false, text);
    121     }
    122 
    123     /**
    124      * Construct a service description for registering with JmDNS.
    125      *
    126      * @param type
    127      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    128      * @param name
    129      *            unqualified service instance name, such as <code>foobar</code>
    130      * @param subtype
    131      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    132      * @param port
    133      *            the local port on which the service runs
    134      * @param weight
    135      *            weight of the service
    136      * @param priority
    137      *            priority of the service
    138      * @param text
    139      *            string describing the service
    140      * @return new service info
    141      */
    142     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final String text) {
    143         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, text);
    144     }
    145 
    146     /**
    147      * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
    148      *
    149      * @param type
    150      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    151      * @param name
    152      *            unqualified service instance name, such as <code>foobar</code>
    153      * @param port
    154      *            the local port on which the service runs
    155      * @param weight
    156      *            weight of the service
    157      * @param priority
    158      *            priority of the service
    159      * @param props
    160      *            properties describing the service
    161      * @return new service info
    162      */
    163     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final Map<String, ?> props) {
    164         return new ServiceInfoImpl(type, name, "", port, weight, priority, false, props);
    165     }
    166 
    167     /**
    168      * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
    169      *
    170      * @param type
    171      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    172      * @param name
    173      *            unqualified service instance name, such as <code>foobar</code>
    174      * @param subtype
    175      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    176      * @param port
    177      *            the local port on which the service runs
    178      * @param weight
    179      *            weight of the service
    180      * @param priority
    181      *            priority of the service
    182      * @param props
    183      *            properties describing the service
    184      * @return new service info
    185      */
    186     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final Map<String, ?> props) {
    187         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, props);
    188     }
    189 
    190     /**
    191      * Construct a service description for registering with JmDNS.
    192      *
    193      * @param type
    194      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    195      * @param name
    196      *            unqualified service instance name, such as <code>foobar</code>
    197      * @param port
    198      *            the local port on which the service runs
    199      * @param weight
    200      *            weight of the service
    201      * @param priority
    202      *            priority of the service
    203      * @param text
    204      *            bytes describing the service
    205      * @return new service info
    206      */
    207     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final byte[] text) {
    208         return new ServiceInfoImpl(type, name, "", port, weight, priority, false, text);
    209     }
    210 
    211     /**
    212      * Construct a service description for registering with JmDNS.
    213      *
    214      * @param type
    215      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    216      * @param name
    217      *            unqualified service instance name, such as <code>foobar</code>
    218      * @param subtype
    219      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    220      * @param port
    221      *            the local port on which the service runs
    222      * @param weight
    223      *            weight of the service
    224      * @param priority
    225      *            priority of the service
    226      * @param text
    227      *            bytes describing the service
    228      * @return new service info
    229      */
    230     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final byte[] text) {
    231         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, false, text);
    232     }
    233 
    234     /**
    235      * Construct a service description for registering with JmDNS.
    236      *
    237      * @param type
    238      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    239      * @param name
    240      *            unqualified service instance name, such as <code>foobar</code>
    241      * @param port
    242      *            the local port on which the service runs
    243      * @param weight
    244      *            weight of the service
    245      * @param priority
    246      *            priority of the service
    247      * @param persistent
    248      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    249      * @param text
    250      *            string describing the service
    251      * @return new service info
    252      */
    253     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final String text) {
    254         return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, text);
    255     }
    256 
    257     /**
    258      * Construct a service description for registering with JmDNS.
    259      *
    260      * @param type
    261      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    262      * @param name
    263      *            unqualified service instance name, such as <code>foobar</code>
    264      * @param subtype
    265      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    266      * @param port
    267      *            the local port on which the service runs
    268      * @param weight
    269      *            weight of the service
    270      * @param priority
    271      *            priority of the service
    272      * @param persistent
    273      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    274      * @param text
    275      *            string describing the service
    276      * @return new service info
    277      */
    278     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final String text) {
    279         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, text);
    280     }
    281 
    282     /**
    283      * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
    284      *
    285      * @param type
    286      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    287      * @param name
    288      *            unqualified service instance name, such as <code>foobar</code>
    289      * @param port
    290      *            the local port on which the service runs
    291      * @param weight
    292      *            weight of the service
    293      * @param priority
    294      *            priority of the service
    295      * @param persistent
    296      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    297      * @param props
    298      *            properties describing the service
    299      * @return new service info
    300      */
    301     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
    302         return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, props);
    303     }
    304 
    305     /**
    306      * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
    307      *
    308      * @param type
    309      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    310      * @param name
    311      *            unqualified service instance name, such as <code>foobar</code>
    312      * @param subtype
    313      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    314      * @param port
    315      *            the local port on which the service runs
    316      * @param weight
    317      *            weight of the service
    318      * @param priority
    319      *            priority of the service
    320      * @param persistent
    321      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    322      * @param props
    323      *            properties describing the service
    324      * @return new service info
    325      */
    326     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
    327         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, props);
    328     }
    329 
    330     /**
    331      * Construct a service description for registering with JmDNS.
    332      *
    333      * @param type
    334      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    335      * @param name
    336      *            unqualified service instance name, such as <code>foobar</code>
    337      * @param port
    338      *            the local port on which the service runs
    339      * @param weight
    340      *            weight of the service
    341      * @param priority
    342      *            priority of the service
    343      * @param persistent
    344      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    345      * @param text
    346      *            bytes describing the service
    347      * @return new service info
    348      */
    349     public static ServiceInfo create(final String type, final String name, final int port, final int weight, final int priority, final boolean persistent, final byte[] text) {
    350         return new ServiceInfoImpl(type, name, "", port, weight, priority, persistent, text);
    351     }
    352 
    353     /**
    354      * Construct a service description for registering with JmDNS.
    355      *
    356      * @param type
    357      *            fully qualified service type name, such as <code>_http._tcp.local.</code>.
    358      * @param name
    359      *            unqualified service instance name, such as <code>foobar</code>
    360      * @param subtype
    361      *            service subtype see draft-cheshire-dnsext-dns-sd-06.txt chapter 7.1 Selective Instance Enumeration
    362      * @param port
    363      *            the local port on which the service runs
    364      * @param weight
    365      *            weight of the service
    366      * @param priority
    367      *            priority of the service
    368      * @param persistent
    369      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    370      * @param text
    371      *            bytes describing the service
    372      * @return new service info
    373      */
    374     public static ServiceInfo create(final String type, final String name, final String subtype, final int port, final int weight, final int priority, final boolean persistent, final byte[] text) {
    375         return new ServiceInfoImpl(type, name, subtype, port, weight, priority, persistent, text);
    376     }
    377 
    378     /**
    379      * Construct a service description for registering with JmDNS. The properties hashtable must map property names to either Strings or byte arrays describing the property values.
    380      *
    381      * @param qualifiedNameMap
    382      *            dictionary of values to build the fully qualified service name. Mandatory keys are Application and Instance. The Domain default is local, the Protocol default is tcp and the subtype default is none.
    383      * @param port
    384      *            the local port on which the service runs
    385      * @param weight
    386      *            weight of the service
    387      * @param priority
    388      *            priority of the service
    389      * @param persistent
    390      *            if <code>true</code> ServiceListener.resolveService will be called whenever new new information is received.
    391      * @param props
    392      *            properties describing the service
    393      * @return new service info
    394      */
    395     public static ServiceInfo create(final Map<Fields, String> qualifiedNameMap, final int port, final int weight, final int priority, final boolean persistent, final Map<String, ?> props) {
    396         return new ServiceInfoImpl(qualifiedNameMap, port, weight, priority, persistent, props);
    397     }
    398 
    399     /**
    400      * Returns true if the service info is filled with data.
    401      *
    402      * @return <code>true</code> if the service info has data, <code>false</code> otherwise.
    403      */
    404     public abstract boolean hasData();
    405 
    406     /**
    407      * Fully qualified service type name, such as <code>_http._tcp.local.</code>
    408      *
    409      * @return service type name
    410      */
    411     public abstract String getType();
    412 
    413     /**
    414      * Fully qualified service type name with the subtype if appropriate, such as <code>_printer._sub._http._tcp.local.</code>
    415      *
    416      * @return service type name
    417      */
    418     public abstract String getTypeWithSubtype();
    419 
    420     /**
    421      * Unqualified service instance name, such as <code>foobar</code> .
    422      *
    423      * @return service name
    424      */
    425     public abstract String getName();
    426 
    427     /**
    428      * The key is used to retrieve service info in hash tables.<br/>
    429      * The key is the lower case qualified name.
    430      *
    431      * @return the key
    432      */
    433     public abstract String getKey();
    434 
    435     /**
    436      * Fully qualified service name, such as <code>foobar._http._tcp.local.</code> .
    437      *
    438      * @return qualified service name
    439      */
    440     public abstract String getQualifiedName();
    441 
    442     /**
    443      * Get the name of the server.
    444      *
    445      * @return server name
    446      */
    447     public abstract String getServer();
    448 
    449     /**
    450      * Returns the host IP address string in textual presentation.<br/>
    451      * <b>Note:</b> This can be either an IPv4 or an IPv6 representation.
    452      *
    453      * @return the host raw IP address in a string format.
    454      * @deprecated since 3.2.3
    455      * @see #getHostAddresses()
    456      */
    457     @Deprecated
    458     public abstract String getHostAddress();
    459 
    460     /**
    461      * Returns the host IP addresses string in textual presentation.
    462      *
    463      * @return list of host raw IP address in a string format.
    464      */
    465     public abstract String[] getHostAddresses();
    466 
    467     /**
    468      * Get the host address of the service.<br/>
    469      *
    470      * @return host Internet address
    471      * @deprecated since 3.1.8
    472      * @see #getInetAddresses()
    473      */
    474     @Deprecated
    475     public abstract InetAddress getAddress();
    476 
    477     /**
    478      * Get the InetAddress of the service. This will return the IPv4 if it exist, otherwise it return the IPv6 if set.<br/>
    479      * <b>Note:</b> This return null if the service IP address cannot be resolved.
    480      *
    481      * @return Internet address
    482      * @deprecated since 3.2.3
    483      * @see #getInetAddresses()
    484      */
    485     @Deprecated
    486     public abstract InetAddress getInetAddress();
    487 
    488     /**
    489      * Get the IPv4 InetAddress of the service.<br/>
    490      * <b>Note:</b> This return null if the service IPv4 address cannot be resolved.
    491      *
    492      * @return Internet address
    493      * @deprecated since 3.2.3
    494      * @see #getInet4Addresses()
    495      */
    496     @Deprecated
    497     public abstract Inet4Address getInet4Address();
    498 
    499     /**
    500      * Get the IPv6 InetAddress of the service.<br/>
    501      * <b>Note:</b> This return null if the service IPv6 address cannot be resolved.
    502      *
    503      * @return Internet address
    504      * @deprecated since 3.2.3
    505      * @see #getInet6Addresses()
    506      */
    507     @Deprecated
    508     public abstract Inet6Address getInet6Address();
    509 
    510     /**
    511      * Returns a list of all InetAddresses that can be used for this service.
    512      * <p>
    513      * In a multi-homed environment service info can be associated with more than one address.
    514      * </p>
    515      *
    516      * @return list of InetAddress objects
    517      */
    518     public abstract InetAddress[] getInetAddresses();
    519 
    520     /**
    521      * Returns a list of all IPv4 InetAddresses that can be used for this service.
    522      * <p>
    523      * In a multi-homed environment service info can be associated with more than one address.
    524      * </p>
    525      *
    526      * @return list of InetAddress objects
    527      */
    528     public abstract Inet4Address[] getInet4Addresses();
    529 
    530     /**
    531      * Returns a list of all IPv6 InetAddresses that can be used for this service.
    532      * <p>
    533      * In a multi-homed environment service info can be associated with more than one address.
    534      * </p>
    535      *
    536      * @return list of InetAddress objects
    537      */
    538     public abstract Inet6Address[] getInet6Addresses();
    539 
    540     /**
    541      * Get the port for the service.
    542      *
    543      * @return service port
    544      */
    545     public abstract int getPort();
    546 
    547     /**
    548      * Get the priority of the service.
    549      *
    550      * @return service priority
    551      */
    552     public abstract int getPriority();
    553 
    554     /**
    555      * Get the weight of the service.
    556      *
    557      * @return service weight
    558      */
    559     public abstract int getWeight();
    560 
    561     /**
    562      * Get the text for the service as raw bytes.
    563      *
    564      * @return raw service text
    565      */
    566     public abstract byte[] getTextBytes();
    567 
    568     /**
    569      * Get the text for the service. This will interpret the text bytes as a UTF8 encoded string. Will return null if the bytes are not a valid UTF8 encoded string.<br/>
    570      * <b>Note:</b> Do not use. This method make the assumption that the TXT record is one string. This is false. The TXT record is a series of key value pairs.
    571      *
    572      * @return service text
    573      * @see #getPropertyNames()
    574      * @see #getPropertyBytes(String)
    575      * @see #getPropertyString(String)
    576      * @deprecated since 3.1.7
    577      */
    578     @Deprecated
    579     public abstract String getTextString();
    580 
    581     /**
    582      * Get the URL for this service. An http URL is created by combining the address, port, and path properties.
    583      *
    584      * @return service URL
    585      * @deprecated since 3.2.3
    586      * @see #getURLs()
    587      */
    588     @Deprecated
    589     public abstract String getURL();
    590 
    591     /**
    592      * Get the list of URL for this service. An http URL is created by combining the address, port, and path properties.
    593      *
    594      * @return list of service URL
    595      */
    596     public abstract String[] getURLs();
    597 
    598     /**
    599      * Get the URL for this service. An URL is created by combining the protocol, address, port, and path properties.
    600      *
    601      * @param protocol
    602      *            requested protocol
    603      * @return service URL
    604      * @deprecated since 3.2.3
    605      * @see #getURLs()
    606      */
    607     @Deprecated
    608     public abstract String getURL(String protocol);
    609 
    610     /**
    611      * Get the list of URL for this service. An URL is created by combining the protocol, address, port, and path properties.
    612      *
    613      * @param protocol
    614      *            requested protocol
    615      * @return list of service URL
    616      */
    617     public abstract String[] getURLs(String protocol);
    618 
    619     /**
    620      * Get a property of the service. This involves decoding the text bytes into a property list. Returns null if the property is not found or the text data could not be decoded correctly.
    621      *
    622      * @param name
    623      *            property name
    624      * @return raw property text
    625      */
    626     public abstract byte[] getPropertyBytes(final String name);
    627 
    628     /**
    629      * Get a property of the service. This involves decoding the text bytes into a property list. Returns null if the property is not found, the text data could not be decoded correctly, or the resulting bytes are not a valid UTF8 string.
    630      *
    631      * @param name
    632      *            property name
    633      * @return property text
    634      */
    635     public abstract String getPropertyString(final String name);
    636 
    637     /**
    638      * Enumeration of the property names.
    639      *
    640      * @return property name enumeration
    641      */
    642     public abstract Enumeration<String> getPropertyNames();
    643 
    644     /**
    645      * Returns a description of the service info suitable for printing.
    646      *
    647      * @return service info description
    648      */
    649     public abstract String getNiceTextString();
    650 
    651     /**
    652      * Set the text for the service. Setting the text will fore a re-announce of the service.
    653      *
    654      * @param text
    655      *            the raw byte representation of the text field.
    656      * @exception IllegalStateException
    657      *                if attempting to set the text for a non persistent service info.
    658      */
    659     public abstract void setText(final byte[] text) throws IllegalStateException;
    660 
    661     /**
    662      * Set the text for the service. Setting the text will fore a re-announce of the service.
    663      *
    664      * @param props
    665      *            a key=value map that will be encoded into raw bytes.
    666      * @exception IllegalStateException
    667      *                if attempting to set the text for a non persistent service info.
    668      */
    669     public abstract void setText(final Map<String, ?> props) throws IllegalStateException;
    670 
    671     /**
    672      * Returns <code>true</code> if ServiceListener.resolveService will be called whenever new new information is received.
    673      *
    674      * @return the persistent
    675      */
    676     public abstract boolean isPersistent();
    677 
    678     /**
    679      * Returns the domain of the service info suitable for printing.
    680      *
    681      * @return service domain
    682      */
    683     public abstract String getDomain();
    684 
    685     /**
    686      * Returns the protocol of the service info suitable for printing.
    687      *
    688      * @return service protocol
    689      */
    690     public abstract String getProtocol();
    691 
    692     /**
    693      * Returns the application of the service info suitable for printing.
    694      *
    695      * @return service application
    696      */
    697     public abstract String getApplication();
    698 
    699     /**
    700      * Returns the sub type of the service info suitable for printing.
    701      *
    702      * @return service sub type
    703      */
    704     public abstract String getSubtype();
    705 
    706     /**
    707      * Returns a dictionary of the fully qualified name component of this service.
    708      *
    709      * @return dictionary of the fully qualified name components
    710      */
    711     public abstract Map<Fields, String> getQualifiedNameMap();
    712 
    713     /*
    714      * (non-Javadoc)
    715      * @see java.lang.Object#clone()
    716      */
    717     @Override
    718     public ServiceInfo clone() {
    719         try {
    720             return (ServiceInfo) super.clone();
    721         } catch (CloneNotSupportedException exception) {
    722             // clone is supported
    723             return null;
    724         }
    725     }
    726 
    727 }
    728