Search in sources :

Example 1 with ServiceEvent

use of javax.jmdns.ServiceEvent in project JAirPort by froks.

the class JmDNSImpl method handleServiceResolved.

void handleServiceResolved(ServiceEvent event) {
    List<ServiceListenerStatus> list = _serviceListeners.get(event.getType().toLowerCase());
    final List<ServiceListenerStatus> listCopy;
    if ((list != null) && (!list.isEmpty())) {
        if ((event.getInfo() != null) && event.getInfo().hasData()) {
            final ServiceEvent localEvent = event;
            synchronized (list) {
                listCopy = new ArrayList<ServiceListenerStatus>(list);
            }
            for (final ServiceListenerStatus listener : listCopy) {
                _executor.submit(new Runnable() {

                    /** {@inheritDoc} */
                    @Override
                    public void run() {
                        listener.serviceResolved(localEvent);
                    }
                });
            }
        }
    }
}
Also used : ServiceListenerStatus(javax.jmdns.impl.ListenerStatus.ServiceListenerStatus) ServiceEvent(javax.jmdns.ServiceEvent)

Example 2 with ServiceEvent

use of javax.jmdns.ServiceEvent in project JAirPort by froks.

the class ServiceInfoImpl method updateRecord.

/**
     * JmDNS callback to update a DNS record.
     *
     * @param dnsCache
     * @param now
     * @param rec
     */
@Override
public void updateRecord(DNSCache dnsCache, long now, DNSEntry rec) {
    if ((rec instanceof DNSRecord) && !rec.isExpired(now)) {
        boolean serviceUpdated = false;
        switch(rec.getRecordType()) {
            case // IPv4
            TYPE_A:
                if (rec.getName().equalsIgnoreCase(this.getServer())) {
                    _ipv4Addresses.add((Inet4Address) ((DNSRecord.Address) rec).getAddress());
                    serviceUpdated = true;
                }
                break;
            case // IPv6
            TYPE_AAAA:
                if (rec.getName().equalsIgnoreCase(this.getServer())) {
                    _ipv6Addresses.add((Inet6Address) ((DNSRecord.Address) rec).getAddress());
                    serviceUpdated = true;
                }
                break;
            case TYPE_SRV:
                if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) {
                    DNSRecord.Service srv = (DNSRecord.Service) rec;
                    boolean serverChanged = (_server == null) || !_server.equalsIgnoreCase(srv.getServer());
                    _server = srv.getServer();
                    _port = srv.getPort();
                    _weight = srv.getWeight();
                    _priority = srv.getPriority();
                    if (serverChanged) {
                        _ipv4Addresses.clear();
                        _ipv6Addresses.clear();
                        for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN)) {
                            this.updateRecord(dnsCache, now, entry);
                        }
                        for (DNSEntry entry : dnsCache.getDNSEntryList(_server, DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN)) {
                            this.updateRecord(dnsCache, now, entry);
                        }
                    // We do not want to trigger the listener in this case as it will be triggered if the address resolves.
                    } else {
                        serviceUpdated = true;
                    }
                }
                break;
            case TYPE_TXT:
                if (rec.getName().equalsIgnoreCase(this.getQualifiedName())) {
                    DNSRecord.Text txt = (DNSRecord.Text) rec;
                    _text = txt.getText();
                    serviceUpdated = true;
                }
                break;
            case TYPE_PTR:
                if ((this.getSubtype().length() == 0) && (rec.getSubtype().length() != 0)) {
                    _subtype = rec.getSubtype();
                    serviceUpdated = true;
                }
                break;
            default:
                break;
        }
        if (serviceUpdated && this.hasData()) {
            JmDNSImpl dns = this.getDns();
            if (dns != null) {
                ServiceEvent event = ((DNSRecord) rec).getServiceEvent(dns);
                event = new ServiceEventImpl(dns, event.getType(), event.getName(), this);
                dns.handleServiceResolved(event);
            }
        }
        // This is done, to notify the wait loop in method JmDNS.waitForInfoData(ServiceInfo info, int timeout);
        synchronized (this) {
            this.notifyAll();
        }
    }
}
Also used : InetAddress(java.net.InetAddress) Inet4Address(java.net.Inet4Address) Inet6Address(java.net.Inet6Address) ServiceEvent(javax.jmdns.ServiceEvent) Service(javax.jmdns.impl.DNSRecord.Service) Text(javax.jmdns.impl.DNSRecord.Text) Text(javax.jmdns.impl.DNSRecord.Text) Service(javax.jmdns.impl.DNSRecord.Service)

Example 3 with ServiceEvent

use of javax.jmdns.ServiceEvent in project JAirPort by froks.

the class JmDNSImpl method registerServiceType.

/**
     * {@inheritDoc}
     */
@Override
public boolean registerServiceType(String type) {
    boolean typeAdded = false;
    Map<Fields, String> map = ServiceInfoImpl.decodeQualifiedNameMapForType(type);
    String domain = map.get(Fields.Domain);
    String protocol = map.get(Fields.Protocol);
    String application = map.get(Fields.Application);
    String subtype = map.get(Fields.Subtype);
    final String name = (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + ".";
    final String loname = name.toLowerCase();
    if (logger.isLoggable(Level.FINE)) {
        logger.fine(this.getName() + ".registering service type: " + type + " as: " + name + (subtype.length() > 0 ? " subtype: " + subtype : ""));
    }
    if (!_serviceTypes.containsKey(loname) && !application.toLowerCase().equals("dns-sd") && !domain.toLowerCase().endsWith("in-addr.arpa") && !domain.toLowerCase().endsWith("ip6.arpa")) {
        typeAdded = _serviceTypes.putIfAbsent(loname, new ServiceTypeEntry(name)) == null;
        if (typeAdded) {
            final ServiceTypeListenerStatus[] list = _typeListeners.toArray(new ServiceTypeListenerStatus[_typeListeners.size()]);
            final ServiceEvent event = new ServiceEventImpl(this, name, "", null);
            for (final ServiceTypeListenerStatus status : list) {
                _executor.submit(new Runnable() {

                    /** {@inheritDoc} */
                    @Override
                    public void run() {
                        status.serviceTypeAdded(event);
                    }
                });
            }
        }
    }
    if (subtype.length() > 0) {
        ServiceTypeEntry subtypes = _serviceTypes.get(loname);
        if ((subtypes != null) && (!subtypes.contains(subtype))) {
            synchronized (subtypes) {
                if (!subtypes.contains(subtype)) {
                    typeAdded = true;
                    subtypes.add(subtype);
                    final ServiceTypeListenerStatus[] list = _typeListeners.toArray(new ServiceTypeListenerStatus[_typeListeners.size()]);
                    final ServiceEvent event = new ServiceEventImpl(this, "_" + subtype + "._sub." + name, "", null);
                    for (final ServiceTypeListenerStatus status : list) {
                        _executor.submit(new Runnable() {

                            /** {@inheritDoc} */
                            @Override
                            public void run() {
                                status.subTypeForServiceTypeAdded(event);
                            }
                        });
                    }
                }
            }
        }
    }
    return typeAdded;
}
Also used : Fields(javax.jmdns.ServiceInfo.Fields) ServiceEvent(javax.jmdns.ServiceEvent) ServiceTypeListenerStatus(javax.jmdns.impl.ListenerStatus.ServiceTypeListenerStatus)

Example 4 with ServiceEvent

use of javax.jmdns.ServiceEvent in project JAirPort by froks.

the class JmDNSImpl method updateRecord.

// Remind: Method updateRecord should receive a better name.
/**
     * Notify all listeners that a record was updated.
     *
     * @param now
     *            update date
     * @param rec
     *            DNS record
     * @param operation
     *            DNS cache operation
     */
public void updateRecord(long now, DNSRecord rec, Operation operation) {
    // We do not want to block the entire DNS while we are updating the record for each listener (service info)
    {
        List<DNSListener> listenerList = null;
        synchronized (_listeners) {
            listenerList = new ArrayList<DNSListener>(_listeners);
        }
        for (DNSListener listener : listenerList) {
            listener.updateRecord(this.getCache(), now, rec);
        }
    }
    if (DNSRecordType.TYPE_PTR.equals(rec.getRecordType())) // if (DNSRecordType.TYPE_PTR.equals(rec.getRecordType()) || DNSRecordType.TYPE_SRV.equals(rec.getRecordType()))
    {
        ServiceEvent event = rec.getServiceEvent(this);
        if ((event.getInfo() == null) || !event.getInfo().hasData()) {
            // We do not care about the subtype because the info is only used if complete and the subtype will then be included.
            ServiceInfo info = this.getServiceInfoFromCache(event.getType(), event.getName(), "", false);
            if (info.hasData()) {
                event = new ServiceEventImpl(this, event.getType(), event.getName(), info);
            }
        }
        List<ServiceListenerStatus> list = _serviceListeners.get(event.getType().toLowerCase());
        final List<ServiceListenerStatus> serviceListenerList;
        if (list != null) {
            synchronized (list) {
                serviceListenerList = new ArrayList<ServiceListenerStatus>(list);
            }
        } else {
            serviceListenerList = Collections.emptyList();
        }
        if (logger.isLoggable(Level.FINEST)) {
            logger.finest(this.getName() + ".updating record for event: " + event + " list " + serviceListenerList + " operation: " + operation);
        }
        if (!serviceListenerList.isEmpty()) {
            final ServiceEvent localEvent = event;
            switch(operation) {
                case Add:
                    for (final ServiceListenerStatus listener : serviceListenerList) {
                        if (listener.isSynchronous()) {
                            listener.serviceAdded(localEvent);
                        } else {
                            _executor.submit(new Runnable() {

                                /** {@inheritDoc} */
                                @Override
                                public void run() {
                                    listener.serviceAdded(localEvent);
                                }
                            });
                        }
                    }
                    break;
                case Remove:
                    for (final ServiceListenerStatus listener : serviceListenerList) {
                        if (listener.isSynchronous()) {
                            listener.serviceRemoved(localEvent);
                        } else {
                            _executor.submit(new Runnable() {

                                /** {@inheritDoc} */
                                @Override
                                public void run() {
                                    listener.serviceRemoved(localEvent);
                                }
                            });
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
Also used : ServiceInfo(javax.jmdns.ServiceInfo) ServiceListenerStatus(javax.jmdns.impl.ListenerStatus.ServiceListenerStatus) ServiceEvent(javax.jmdns.ServiceEvent) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 5 with ServiceEvent

use of javax.jmdns.ServiceEvent in project JAirPort by froks.

the class JmDNSImpl method addServiceListener.

private void addServiceListener(String type, ServiceListener listener, boolean synch) {
    ServiceListenerStatus status = new ServiceListenerStatus(listener, synch);
    final String loType = type.toLowerCase();
    List<ServiceListenerStatus> list = _serviceListeners.get(loType);
    if (list == null) {
        if (_serviceListeners.putIfAbsent(loType, new LinkedList<ServiceListenerStatus>()) == null) {
            if (_serviceCollectors.putIfAbsent(loType, new ServiceCollector(type)) == null) {
                // We have a problem here. The service collectors must be called synchronously so that their cache get cleaned up immediately or we will report .
                this.addServiceListener(loType, _serviceCollectors.get(loType), ListenerStatus.SYNCHONEOUS);
            }
        }
        list = _serviceListeners.get(loType);
    }
    if (list != null) {
        synchronized (list) {
            if (!list.contains(listener)) {
                list.add(status);
            }
        }
    }
    // report cached service types
    final List<ServiceEvent> serviceEvents = new ArrayList<ServiceEvent>();
    Collection<DNSEntry> dnsEntryLits = this.getCache().allValues();
    for (DNSEntry entry : dnsEntryLits) {
        final DNSRecord record = (DNSRecord) entry;
        if (record.getRecordType() == DNSRecordType.TYPE_SRV) {
            if (record.getKey().endsWith(loType)) {
                // Do not used the record embedded method for generating event this will not work.
                // serviceEvents.add(record.getServiceEvent(this));
                serviceEvents.add(new ServiceEventImpl(this, record.getType(), toUnqualifiedName(record.getType(), record.getName()), record.getServiceInfo()));
            }
        }
    }
    // Actually call listener with all service events added above
    for (ServiceEvent serviceEvent : serviceEvents) {
        status.serviceAdded(serviceEvent);
    }
    // Create/start ServiceResolver
    this.startServiceResolver(type);
}
Also used : ServiceListenerStatus(javax.jmdns.impl.ListenerStatus.ServiceListenerStatus) ServiceEvent(javax.jmdns.ServiceEvent) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList)

Aggregations

ServiceEvent (javax.jmdns.ServiceEvent)5 ServiceListenerStatus (javax.jmdns.impl.ListenerStatus.ServiceListenerStatus)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 Inet4Address (java.net.Inet4Address)1 Inet6Address (java.net.Inet6Address)1 InetAddress (java.net.InetAddress)1 List (java.util.List)1 ServiceInfo (javax.jmdns.ServiceInfo)1 Fields (javax.jmdns.ServiceInfo.Fields)1 Service (javax.jmdns.impl.DNSRecord.Service)1 Text (javax.jmdns.impl.DNSRecord.Text)1 ServiceTypeListenerStatus (javax.jmdns.impl.ListenerStatus.ServiceTypeListenerStatus)1