4b22b9337f359bfd063322244f5336cc7c6ffcfars/* -*- Mode: Java; tab-width: 4 -*-
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * ("Apple") in consideration of your agreement to the following terms, and your
4b22b9337f359bfd063322244f5336cc7c6ffcfars * use, installation, modification or redistribution of this Apple software
4b22b9337f359bfd063322244f5336cc7c6ffcfars * constitutes acceptance of these terms. If you do not agree with these terms,
4b22b9337f359bfd063322244f5336cc7c6ffcfars * please do not use, install, modify or redistribute this Apple software.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * In consideration of your agreement to abide by the following terms, and subject
4b22b9337f359bfd063322244f5336cc7c6ffcfars * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
4b22b9337f359bfd063322244f5336cc7c6ffcfars * copyrights in this original Apple software (the "Apple Software"), to use,
4b22b9337f359bfd063322244f5336cc7c6ffcfars * reproduce, modify and redistribute the Apple Software, with or without
4b22b9337f359bfd063322244f5336cc7c6ffcfars * modifications, in source and/or binary forms; provided that if you redistribute
4b22b9337f359bfd063322244f5336cc7c6ffcfars * the Apple Software in its entirety and without modifications, you must retain
4b22b9337f359bfd063322244f5336cc7c6ffcfars * this notice and the following text and disclaimers in all such redistributions of
4b22b9337f359bfd063322244f5336cc7c6ffcfars * the Apple Software. Neither the name, trademarks, service marks or logos of
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Apple Computer, Inc. may be used to endorse or promote products derived from the
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Apple Software without specific prior written permission from Apple. Except as
4b22b9337f359bfd063322244f5336cc7c6ffcfars * expressly stated in this notice, no other rights or licenses, express or implied,
4b22b9337f359bfd063322244f5336cc7c6ffcfars * are granted by Apple herein, including but not limited to any patent rights that
4b22b9337f359bfd063322244f5336cc7c6ffcfars * may be infringed by your derivative works or by other works in which the Apple
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Software may be incorporated.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
4b22b9337f359bfd063322244f5336cc7c6ffcfars * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
4b22b9337f359bfd063322244f5336cc7c6ffcfars * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4b22b9337f359bfd063322244f5336cc7c6ffcfars * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
4b22b9337f359bfd063322244f5336cc7c6ffcfars * COMBINATION WITH YOUR PRODUCTS.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
4b22b9337f359bfd063322244f5336cc7c6ffcfars * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4b22b9337f359bfd063322244f5336cc7c6ffcfars * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4b22b9337f359bfd063322244f5336cc7c6ffcfars * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
4b22b9337f359bfd063322244f5336cc7c6ffcfars * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
4b22b9337f359bfd063322244f5336cc7c6ffcfars * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
4b22b9337f359bfd063322244f5336cc7c6ffcfars * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4b22b9337f359bfd063322244f5336cc7c6ffcfars BrowserApp demonstrates how to use DNS-SD to browse for and resolve services.
4b22b9337f359bfd063322244f5336cc7c6ffcfars - display resolved TXTRecord
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soomeclass BrowserApp implements ListSelectionListener, ResolveListener, Runnable
4b22b9337f359bfd063322244f5336cc7c6ffcfars DNSSDService servicesBrowser, serviceBrowser, domainBrowser;
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void windowClosing(WindowEvent e) {System.exit(0);}
4b22b9337f359bfd063322244f5336cc7c6ffcfars domainBrowser = DNSSD.enumerateDomains( DNSSD.BROWSE_DOMAINS, 0, domainList);
4b22b9337f359bfd063322244f5336cc7c6ffcfars servicesBrowser = DNSSD.browse( 0, 0, "_services._dns-sd._udp.", "", servicesList);
4b22b9337f359bfd063322244f5336cc7c6ffcfars parent.setLayout( new BoxLayout( parent, BoxLayout.Y_AXIS));
4b22b9337f359bfd063322244f5336cc7c6ffcfars browserRow.setLayout( new BoxLayout( browserRow, BoxLayout.X_AXIS));
4b22b9337f359bfd063322244f5336cc7c6ffcfars JScrollPane domainScroller = new JScrollPane( domainPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
4b22b9337f359bfd063322244f5336cc7c6ffcfars JScrollPane servicesScroller = new JScrollPane( servicesPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
4b22b9337f359bfd063322244f5336cc7c6ffcfars JScrollPane serviceScroller = new JScrollPane( servicePane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
4b22b9337f359bfd063322244f5336cc7c6ffcfars JPanel buttonRow = new JPanel();
4b22b9337f359bfd063322244f5336cc7c6ffcfars buttonRow.setLayout( new BoxLayout( buttonRow, BoxLayout.X_AXIS));
4b22b9337f359bfd063322244f5336cc7c6ffcfars buttonRow.add( Box.createHorizontalGlue());
4b22b9337f359bfd063322244f5336cc7c6ffcfars JButton connectButton = new JButton( "Don't Connect");
4b22b9337f359bfd063322244f5336cc7c6ffcfars buttonRow.add( connectButton);
4b22b9337f359bfd063322244f5336cc7c6ffcfars buttonRow.add( Box.createRigidArea( new Dimension( 16, 0)));
4b22b9337f359bfd063322244f5336cc7c6ffcfars labelRow.setLayout( new BoxLayout( labelRow, BoxLayout.X_AXIS));
4b22b9337f359bfd063322244f5336cc7c6ffcfars labelRow.add( Box.createRigidArea( new Dimension( 32, 0)));
4b22b9337f359bfd063322244f5336cc7c6ffcfars// parent.add( buttonRow);
4b22b9337f359bfd063322244f5336cc7c6ffcfars parent.add( Box.createRigidArea( new Dimension( 0, 16)));
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( e.getSource() == domainPane && !e.getValueIsAdjusting())
4b22b9337f359bfd063322244f5336cc7c6ffcfars servicesBrowser = DNSSD.browse( 0, 0, "_services._dns-sd._udp.", "", servicesList);
4b22b9337f359bfd063322244f5336cc7c6ffcfars else if ( e.getSource() == servicesPane && !e.getValueIsAdjusting())
4b22b9337f359bfd063322244f5336cc7c6ffcfars serviceBrowser = DNSSD.browse( 0, 0, servicesList.getNthRegType( newSel), "", serviceList);
4b22b9337f359bfd063322244f5336cc7c6ffcfars else if ( e.getSource() == servicePane && !e.getValueIsAdjusting())
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome portLabel.setText( String.valueOf( portForUpdate));
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome // We want to update GUI on the AWT event dispatching thread, but we can't stop
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome // the resolve from that thread, since stop() is synchronized with this callback.
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome // So, we stop the resolve on this thread, then invokeAndWait on the AWT event thread.
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void operationFailed( DNSSDService service, int errorCode)
4b22b9337f359bfd063322244f5336cc7c6ffcfars // handle failure here
4b22b9337f359bfd063322244f5336cc7c6ffcfars protected static void terminateWithException( Exception e)
4b22b9337f359bfd063322244f5336cc7c6ffcfarsclass BrowserListModel extends DefaultListModel implements BrowseListener, Runnable
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* The Browser invokes this callback when a service is discovered. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void serviceFound( DNSSDService browser, int flags, int ifIndex,
4b22b9337f359bfd063322244f5336cc7c6ffcfars addCache.add( new BrowserListElem( serviceName, domain, regType, ifIndex));
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void serviceLost( DNSSDService browser, int flags, int ifIndex,
4b22b9337f359bfd063322244f5336cc7c6ffcfars String serviceName = (String) removeCache.remove( removeCache.size() - 1);
4b22b9337f359bfd063322244f5336cc7c6ffcfars int matchInd = this.findMatching( serviceName); // probably doesn't handle near-duplicates well.
4b22b9337f359bfd063322244f5336cc7c6ffcfars BrowserListElem elem = (BrowserListElem) addCache.remove( addCache.size() - 1);
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( -1 == this.findMatching( elem.fServiceName)) // probably doesn't handle near-duplicates well.
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void operationFailed( DNSSDService service, int errorCode)
4b22b9337f359bfd063322244f5336cc7c6ffcfars // handle failure here
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* The list contains BrowserListElem's */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public BrowserListElem( String serviceName, String domain, String type, int ifIndex)
4b22b9337f359bfd063322244f5336cc7c6ffcfars { fServiceName = serviceName; fDomain = domain; fType = type; fInt = ifIndex; }
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( sCollator.compare( obj.toString(), this.getElementAt( i).toString()) < 0)
4b22b9337f359bfd063322244f5336cc7c6ffcfars return -1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars protected Vector removeCache; // list of serviceNames to remove
4b22b9337f359bfd063322244f5336cc7c6ffcfars protected Vector addCache; // list of BrowserListElem's to add
4b22b9337f359bfd063322244f5336cc7c6ffcfars static // Initialize our static variables
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* The Browser invokes this callback when a service is discovered. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void serviceFound( DNSSDService browser, int flags, int ifIndex,
4b22b9337f359bfd063322244f5336cc7c6ffcfars // Overridden to stuff serviceName into regType and make serviceName human-readable.
4b22b9337f359bfd063322244f5336cc7c6ffcfars regType = serviceName + ( regType.startsWith( "_udp.") ? "._udp." : "._tcp.");
4b22b9337f359bfd063322244f5336cc7c6ffcfars super.serviceFound( browser, flags, ifIndex, this.mapTypeToName( serviceName), regType, domain);
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void serviceLost( DNSSDService browser, int flags, int ifIndex,
4b22b9337f359bfd063322244f5336cc7c6ffcfars // Overridden to make serviceName human-readable.
4b22b9337f359bfd063322244f5336cc7c6ffcfars super.serviceLost( browser, flags, ifIndex, this.mapTypeToName( serviceName), regType, domain);
4b22b9337f359bfd063322244f5336cc7c6ffcfars // Convert a registration type into a human-readable string. Returns original string on no-match.
4b22b9337f359bfd063322244f5336cc7c6ffcfarsclass DomainListModel extends DefaultListModel implements DomainListener
4b22b9337f359bfd063322244f5336cc7c6ffcfars /* Called when a domain is discovered. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void domainFound( DNSSDService domainEnum, int flags, int ifIndex, String domain)
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void domainLost( DNSSDService domainEnum, int flags, int ifIndex, String domain)
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void operationFailed( DNSSDService service, int errorCode)
4b22b9337f359bfd063322244f5336cc7c6ffcfars // handle failure here