Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Alexander Kuppe2010-10-13 14:09:10 +0000
committerMarkus Alexander Kuppe2010-10-13 14:09:10 +0000
commit9efde0b32d8922911341da288ffba71742d6dc16 (patch)
tree5d31f5a09a61e822f0b91df1324e45a31cee26a6 /providers
parent6094f1ea9738fdf91f5b20ea7fbb94dd06315c57 (diff)
parent80652b6a7389c54a0f77df9c94f78d8fe433c67c (diff)
downloadorg.eclipse.ecf-9efde0b32d8922911341da288ffba71742d6dc16.tar.gz
org.eclipse.ecf-9efde0b32d8922911341da288ffba71742d6dc16.tar.xz
org.eclipse.ecf-9efde0b32d8922911341da288ffba71742d6dc16.zip
Merge branch 'master' of ../org.eclipse.ecf.discovery.dnssd/org.eclipse.ecf.provider.dnssd
Diffstat (limited to 'providers')
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.classpath7
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.gitignore1
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.options19
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.project34
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/.api_filters56
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.pde.core.prefs5
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/META-INF/MANIFEST.MF25
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/build.properties5
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/plugin.xml28
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Activator.java229
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/BnRDnsSdServiceTypeID.java92
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/ContainerInstantiator.java62
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDebugOptions.java27
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryAdvertiser.java269
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryContainerAdapter.java294
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryException.java40
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryLocator.java219
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdNamespace.java59
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceID.java77
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceTypeID.java139
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/IDnsSdDiscoveryConstants.java30
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Messages.java27
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/messages.properties11
24 files changed, 1763 insertions, 0 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.classpath b/providers/bundles/org.eclipse.ecf.provider.dnssd/.classpath
new file mode 100644
index 000000000..2fbb7a23e
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.gitignore b/providers/bundles/org.eclipse.ecf.provider.dnssd/.gitignore
new file mode 100644
index 000000000..6dd29b7f8
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.gitignore
@@ -0,0 +1 @@
+bin/ \ No newline at end of file
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.options b/providers/bundles/org.eclipse.ecf.provider.dnssd/.options
new file mode 100644
index 000000000..c82ad693a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.options
@@ -0,0 +1,19 @@
+# Debugging options for the org.eclipse.ecf.provider.dnssd plug-in
+
+# Turn on general debugging for the org.eclipse.ecf.provider.dnssd plug-in
+org.eclipse.ecf.provider.dnssd/debug=false
+org.eclipse.ecf.provider.dnssd/debug/filter = *
+org.eclipse.ecf.provider.dnssd/debug/flag = false
+
+# Trace when exceptions are caught
+org.eclipse.ecf.provider.dnssd/debug/exceptions/catching=false
+# Trace when exceptions are thrown
+org.eclipse.ecf.provider.dnssd/debug/exceptions/throwing=false
+
+# Trace when methods are entered
+org.eclipse.ecf.provider.dnssd/debug/methods/entering=false
+# Trace when methods are exited
+org.eclipse.ecf.provider.dnssd/debug/methods/exiting=false
+
+org.eclipse.ecf.provider.dnssd/debug/methods/tracing=false
+org.eclipse.ecf.provider.dnssd/debug/methods/changing=false
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.project b/providers/bundles/org.eclipse.ecf.provider.dnssd/.project
new file mode 100644
index 000000000..01a021275
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ecf.provider.dnssd</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/.api_filters b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/.api_filters
new file mode 100644
index 000000000..0144a9db1
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/.api_filters
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.ecf.provider.dnssd" version="2">
+ <resource path="src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryAdvertiser.java" type="org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryAdvertiser">
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="Name"/>
+ <message_argument value="DnsSdDiscoveryAdvertiser"/>
+ <message_argument value="getAuthoritativeNameServer(Name)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="Name"/>
+ <message_argument value="DnsSdDiscoveryAdvertiser"/>
+ <message_argument value="getUpdateDomain(Name)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryContainerAdapter.java" type="org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryContainerAdapter">
+ <filter id="627060751">
+ <message_arguments>
+ <message_argument value="Resolver"/>
+ <message_argument value="DnsSdDiscoveryContainerAdapter"/>
+ <message_argument value="resolver"/>
+ </message_arguments>
+ </filter>
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="Record"/>
+ <message_argument value="DnsSdDiscoveryContainerAdapter"/>
+ <message_argument value="getRecords(DnsSdServiceTypeID)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="Lookup"/>
+ <message_argument value="DnsSdDiscoveryContainerAdapter"/>
+ <message_argument value="getSRVRecord(Lookup, Comparator)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="Lookup"/>
+ <message_argument value="DnsSdDiscoveryContainerAdapter"/>
+ <message_argument value="getSRVRecords(Lookup[])"/>
+ </message_arguments>
+ </filter>
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="Lookup"/>
+ <message_argument value="DnsSdDiscoveryContainerAdapter"/>
+ <message_argument value="getSRVRecords(Lookup[], Comparator)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.jdt.core.prefs b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..daf80488d
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Mar 12 07:29:50 CET 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.pde.core.prefs b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..b38f9ad0a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,5 @@
+#Thu Mar 12 07:23:18 CET 2009
+eclipse.preferences.version=1
+pluginProject.equinox=false
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/META-INF/MANIFEST.MF b/providers/bundles/org.eclipse.ecf.provider.dnssd/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..c9ebb7eca
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: ECF discovery provider based on DNS-SD
+Bundle-SymbolicName: org.eclipse.ecf.provider.dnssd;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.ecf.provider.dnssd.Activator
+Bundle-Vendor: Eclipse.org
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Import-Package: org.eclipse.core.runtime;version="3.4.0",
+ org.eclipse.ecf.core;version="3.0.0",
+ org.eclipse.ecf.core.events,
+ org.eclipse.ecf.core.identity;version="3.0.0",
+ org.eclipse.ecf.core.provider,
+ org.eclipse.ecf.core.security,
+ org.eclipse.ecf.core.util;version="3.0.0",
+ org.eclipse.ecf.discovery;version="4.0.0",
+ org.eclipse.ecf.discovery.identity;version="3.0.0",
+ org.eclipse.osgi.util;version="1.0.0",
+ org.osgi.framework;version="1.5.0",
+ org.osgi.service.cm;version="1.2.0";resolution:=optional,
+ org.osgi.service.log;version="1.3",
+ org.osgi.util.tracker;version="1.3.1"
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.ecf.provider.dnssd;version="1.0.0"
+Require-Bundle: org.xbill.dns;bundle-version="2.0.8"
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/build.properties b/providers/bundles/org.eclipse.ecf.provider.dnssd/build.properties
new file mode 100644
index 000000000..e9863e281
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/plugin.xml b/providers/bundles/org.eclipse.ecf.provider.dnssd/plugin.xml
new file mode 100644
index 000000000..a93033e6b
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/plugin.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.3"?>
+<plugin>
+ <extension
+ point="org.eclipse.ecf.containerFactory">
+ <containerFactory
+ class="org.eclipse.ecf.provider.dnssd.ContainerInstantiator"
+ description="Discovery Locator Container "
+ name="ecf.discovery.dnssd.locator">
+ </containerFactory>
+ </extension>
+ <extension
+ point="org.eclipse.ecf.containerFactory">
+ <containerFactory
+ class="org.eclipse.ecf.provider.dnssd.ContainerInstantiator"
+ description="Discovery Advertiser Container "
+ name="ecf.discovery.dnssd.advertiser">
+ </containerFactory>
+ </extension>
+ <extension
+ point="org.eclipse.ecf.identity.namespace">
+ <namespace
+ class="org.eclipse.ecf.provider.dnssd.DnsSdNamespace"
+ description="Dns SD Namespace"
+ name="ecf.namespace.dnssd"/>
+ </extension>
+
+</plugin>
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Activator.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Activator.java
new file mode 100644
index 000000000..b60c52fbb
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Activator.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.IContainer;
+import org.eclipse.ecf.discovery.IDiscoveryAdvertiser;
+import org.eclipse.ecf.discovery.IDiscoveryLocator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+public class Activator implements BundleActivator {
+
+ public static final String PLUGIN_ID = "org.eclipse.ecf.provider.dnssd"; //$NON-NLS-1$
+ public static final String DISCOVERY_CONTAINER_NAME_VALUE = "ecf.discovery.dnssd"; //$NON-NLS-1$
+ public static final String LOCATOR = ".locator"; //$NON-NLS-1$
+ public static final String ADVERTISER = ".advertiser"; //$NON-NLS-1$
+
+ private static final String DISCOVERY_CONTAINER_NAME_KEY = "org.eclipse.ecf.discovery.containerName"; //$NON-NLS-1$
+
+ private final Map serviceRegistrations = new HashMap();
+ private volatile BundleContext context;
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ this.context = context;
+
+ // register a managed factory for the locator service
+ final Properties locCmProps = new Properties();
+ locCmProps.put(Constants.SERVICE_PID, DISCOVERY_CONTAINER_NAME_VALUE + LOCATOR);
+ context.registerService(ManagedServiceFactory.class.getName(), new DnsSdManagedServiceFactory(DnsSdDiscoveryLocator.class), locCmProps);
+
+ // register the locator service
+ final Properties locProps = new Properties();
+ locProps.put(DISCOVERY_CONTAINER_NAME_KEY, DISCOVERY_CONTAINER_NAME_VALUE + LOCATOR);
+ locProps.put(Constants.SERVICE_RANKING, new Integer(750));
+ serviceRegistrations.put(null, context.registerService(IDiscoveryLocator.class.getName(), new DnsSdServiceFactory(DnsSdDiscoveryLocator.class), locProps));
+
+ // register a managed factory for the advertiser service
+ final Properties advCmProps = new Properties();
+ advCmProps.put(Constants.SERVICE_PID, DISCOVERY_CONTAINER_NAME_VALUE + ADVERTISER);
+ context.registerService(ManagedServiceFactory.class.getName(), new DnsSdManagedServiceFactory(DnsSdDiscoveryAdvertiser.class), advCmProps);
+
+ // register the advertiser service
+ final Properties advProps = new Properties();
+ advProps.put(DISCOVERY_CONTAINER_NAME_KEY, DISCOVERY_CONTAINER_NAME_VALUE + ADVERTISER);
+ advProps.put(Constants.SERVICE_RANKING, new Integer(750));
+ serviceRegistrations.put(null, context.registerService(IDiscoveryAdvertiser.class.getName(), new DnsSdServiceFactory(DnsSdDiscoveryAdvertiser.class), advProps));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ if (serviceRegistrations != null) {
+ for (final Iterator itr = serviceRegistrations.values().iterator(); itr.hasNext();) {
+ final ServiceRegistration serviceRegistration = (ServiceRegistration) itr.next();
+ disposeServiceRegistration(serviceRegistration);
+ }
+ }
+ this.context = null;
+ }
+
+ /**
+ * @param serviceRegistration disconnects the underlying IContainer and unregisters the service
+ */
+ private void disposeServiceRegistration(ServiceRegistration serviceRegistration) {
+ final ServiceReference reference = serviceRegistration.getReference();
+ final IContainer aContainer = (DnsSdDiscoveryContainerAdapter) context.getService(reference);
+
+ serviceRegistration.unregister();
+ final IContainer container = (IContainer) aContainer.getAdapter(IContainer.class);
+ container.dispose();
+ container.disconnect();
+ }
+
+ /**
+ * A ManagedServiceFactory capable to handle DnsSdDiscoveryContainerAdapters
+ */
+ private class DnsSdManagedServiceFactory implements ManagedServiceFactory {
+ private final Class containerClass;
+
+ public DnsSdManagedServiceFactory(Class aContainerClass) {
+ containerClass = aContainerClass;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.cm.ManagedServiceFactory#getName()
+ */
+ public String getName() {
+ return this.getClass().getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)
+ */
+ public void updated(String pid, Dictionary properties)
+ throws ConfigurationException {
+ if(properties != null) {
+ DnsSdDiscoveryContainerAdapter adapter = null;
+ DnsSdServiceTypeID targetID = null;
+ try {
+ // get existing or create new discoverycontainer
+ final ServiceRegistration serviceRegistration = (ServiceRegistration) serviceRegistrations.get(pid);
+ if(serviceRegistration != null) {
+ adapter = (DnsSdDiscoveryContainerAdapter) context.getService(serviceRegistration.getReference());
+ targetID = (DnsSdServiceTypeID) adapter.getConnectedID();
+ } else {
+ adapter = (DnsSdDiscoveryContainerAdapter) containerClass.newInstance();
+ targetID = new DnsSdServiceTypeID();
+ }
+
+ // apply configuration
+ final String[] searchPaths = (String[]) properties.get(IDnsSdDiscoveryConstants.CA_SEARCH_PATH);
+ if(searchPaths != null) {
+ targetID.setSearchPath(searchPaths);
+ }
+
+ final String resolver = (String) properties.get(IDnsSdDiscoveryConstants.CA_RESOLVER);
+ if(resolver != null) {
+ adapter.setResolver(resolver);
+ }
+
+ final String tsigKey = (String) properties.get(IDnsSdDiscoveryConstants.CA_TSIG_KEY);
+ if(tsigKey != null) {
+ final String tsigKeyName = (String) properties.get(IDnsSdDiscoveryConstants.CA_TSIG_KEY_NAME);
+ adapter.setTsigKey(tsigKeyName, tsigKey);
+ }
+
+ // finally connect container and keep ser reg for later updates/deletes
+ if(serviceRegistration == null) {
+ final Properties props = new Properties();
+ props.put(Constants.SERVICE_PID, pid);
+ adapter.connect(targetID, null);
+ serviceRegistrations.put(pid, context.registerService(IDiscoveryLocator.class.getName(), adapter, props));
+ }
+ } catch (ContainerConnectException e) {
+ throw new ConfigurationException("IDnsSdDiscoveryConstants properties", e.getLocalizedMessage(), e); //$NON-NLS-1$
+ } catch (ClassCastException cce) {
+ throw new ConfigurationException("IDnsSdDiscoveryConstants properties", cce.getLocalizedMessage(), cce); //$NON-NLS-1$
+ } catch (InstantiationException e) {
+ // may never happen
+ throw new ConfigurationException("InstantiationException", e.getLocalizedMessage(), e); //$NON-NLS-1$
+ } catch (IllegalAccessException e) {
+ // may never happen
+ throw new ConfigurationException("IllegalAccessException", e.getLocalizedMessage(), e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+ */
+ public void deleted(String pid) {
+ final ServiceRegistration serviceRegistration = (ServiceRegistration) serviceRegistrations.get(pid);
+ disposeServiceRegistration(serviceRegistration);
+ }
+ }
+
+ /**
+ * A ServiceFactory capable to handle DnsSdDiscoveryContainerAdapters
+ */
+ public class DnsSdServiceFactory implements ServiceFactory {
+ private volatile DnsSdDiscoveryContainerAdapter container;
+ private final Class containerClass;
+
+ public DnsSdServiceFactory(Class aDiscoveryContainerClass) {
+ containerClass = aDiscoveryContainerClass;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+ */
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ if (container == null) {
+ try {
+ container = (DnsSdDiscoveryContainerAdapter) containerClass.newInstance();
+ container.connect(null, null);
+ } catch (final ContainerConnectException e) {
+ // may never happen
+ e.printStackTrace();
+ container = null;
+ } catch (InstantiationException e) {
+ // may never happen
+ e.printStackTrace();
+ container = null;
+ } catch (IllegalAccessException e) {
+ // may never happen
+ e.printStackTrace();
+ container = null;
+ }
+ }
+ return container;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+ */
+ public void ungetService(Bundle bundle,
+ ServiceRegistration registration, Object service) {
+ // nop
+ }
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/BnRDnsSdServiceTypeID.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/BnRDnsSdServiceTypeID.java
new file mode 100644
index 000000000..f187660be
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/BnRDnsSdServiceTypeID.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.xbill.DNS.Lookup;
+import org.xbill.DNS.TextParseException;
+import org.xbill.DNS.Type;
+
+/**
+ * This ServiceType represents the special RRs defined in
+ * chapter 12. Discovery of Browsing and Registration Domains
+ *
+ * @see http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ */
+public class BnRDnsSdServiceTypeID extends DnsSdServiceTypeID {
+ private static final long serialVersionUID = -466458565598238072L;
+
+ /**
+ * A list of domains recommended for browsing
+ */
+ static final String BROWSE_DOMAINS = "b._dns-sd"; //$NON-NLS-1$
+ /**
+ * A single recommended default domain for browsing
+ */
+ static final String DEFAULT_BROWSE_DOMAIN = "db._dns-sd"; //$NON-NLS-1$
+ /**
+ * A list of domains recommended for registering services using Dynamic Update
+ */
+ static final String REG_DOMAINS = "r._dns-sd"; //$NON-NLS-1$
+ /**
+ * A single recommended default domain for registering services.
+ */
+ static final String DEFAULT_REG_DOMAIN = "dr._dns-sd"; //$NON-NLS-1$
+
+ BnRDnsSdServiceTypeID(IServiceTypeID aServiceType, String aService) {
+ super(aServiceType.getNamespace(), aServiceType);
+ services = new String[] {aService};
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdServiceTypeID#getInternalQueries()
+ */
+ Lookup[] getInternalQueries() {
+ List result = new ArrayList();
+ for (int i = 0; i < scopes.length; i++) {
+ String scope = scopes[i];
+ // remove dangling "."
+ if(scope.endsWith(".")) { //$NON-NLS-1$
+ scope = scope.substring(0, scope.length() - 1);
+ }
+ Lookup query;
+ try {
+ query = new Lookup(services[0] + "._udp" + "." + scope + ".", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Type.PTR);
+ } catch (TextParseException e) {
+ continue;
+ }
+ result.add(query);
+ }
+ return (Lookup[]) result.toArray(new Lookup[result.size()]);
+ }
+
+ void setScope(String target) {
+ if(target.endsWith(".")) { //$NON-NLS-1$
+ target = target.substring(0, target.length() - 1);
+ }
+ scopes = new String[]{target};
+ createType();
+ }
+
+ Collection getScopesAsZones() {
+ final List res = new ArrayList(scopes.length);
+ for (int i = 0; i < scopes.length; i++) {
+ String scope = scopes[i];
+ res.add(scope + "."); //$NON-NLS-1$
+ }
+ return res;
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/ContainerInstantiator.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/ContainerInstantiator.java
new file mode 100644
index 000000000..bcb32f85c
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/ContainerInstantiator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import org.eclipse.ecf.core.ContainerCreateException;
+import org.eclipse.ecf.core.ContainerTypeDescription;
+import org.eclipse.ecf.core.IContainer;
+import org.eclipse.ecf.core.provider.IContainerInstantiator;
+
+public class ContainerInstantiator implements IContainerInstantiator {
+
+ private static final String ADVERTISER = Activator.DISCOVERY_CONTAINER_NAME_VALUE + Activator.ADVERTISER;
+ private static final String LOCATOR = Activator.DISCOVERY_CONTAINER_NAME_VALUE + Activator.LOCATOR;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.provider.IContainerInstantiator#createInstance(org.eclipse.ecf.core.ContainerTypeDescription, java.lang.Object[])
+ */
+ public IContainer createInstance(ContainerTypeDescription description,
+ Object[] parameters) throws ContainerCreateException {
+ if(description != null && ADVERTISER.equals(description.getName())) {
+ return new DnsSdDiscoveryAdvertiser();
+ } else if(description != null && LOCATOR.equals(description.getName())) {
+ return new DnsSdDiscoveryLocator();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.provider.IContainerInstantiator#getSupportedAdapterTypes(org.eclipse.ecf.core.ContainerTypeDescription)
+ */
+ public String[] getSupportedAdapterTypes(
+ ContainerTypeDescription description) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.provider.IContainerInstantiator#getSupportedIntents(org.eclipse.ecf.core.ContainerTypeDescription)
+ */
+ public String[] getSupportedIntents(ContainerTypeDescription description) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.provider.IContainerInstantiator#getSupportedParameterTypes(org.eclipse.ecf.core.ContainerTypeDescription)
+ */
+ public Class[][] getSupportedParameterTypes(
+ ContainerTypeDescription description) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDebugOptions.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDebugOptions.java
new file mode 100644
index 000000000..06ad2866b
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDebugOptions.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+public interface DnsSdDebugOptions {
+
+ public static final String DEBUG = Activator.PLUGIN_ID + "/debug"; //$NON-NLS-1$
+
+ public static final String EXCEPTIONS_CATCHING = DEBUG + "/exceptions/catching"; //$NON-NLS-1$
+
+ public static final String EXCEPTIONS_THROWING = DEBUG + "/exceptions/throwing"; //$NON-NLS-1$
+
+ public static final String METHODS_ENTERING = DEBUG + "/methods/entering"; //$NON-NLS-1$
+
+ public static final String METHODS_EXITING = DEBUG + "/methods/exiting"; //$NON-NLS-1$
+
+ public static final String METHODS_TRACING = DEBUG + "/methods/tracing"; //$NON-NLS-1$
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryAdvertiser.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryAdvertiser.java
new file mode 100644
index 000000000..889416f1e
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryAdvertiser.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.io.EOFException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.events.ContainerConnectedEvent;
+import org.eclipse.ecf.core.events.ContainerConnectingEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.Trace;
+import org.eclipse.ecf.discovery.DiscoveryContainerConfig;
+import org.eclipse.ecf.discovery.IServiceInfo;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.xbill.DNS.DClass;
+import org.xbill.DNS.Lookup;
+import org.xbill.DNS.Message;
+import org.xbill.DNS.NSRecord;
+import org.xbill.DNS.Name;
+import org.xbill.DNS.Rcode;
+import org.xbill.DNS.Record;
+import org.xbill.DNS.SOARecord;
+import org.xbill.DNS.SRVRecord;
+import org.xbill.DNS.SimpleResolver;
+import org.xbill.DNS.TextParseException;
+import org.xbill.DNS.Type;
+import org.xbill.DNS.Update;
+
+public class DnsSdDiscoveryAdvertiser extends DnsSdDiscoveryContainerAdapter {
+
+ private static final String _DNS_UPDATE = "_dns-update._udp."; //$NON-NLS-1$
+ private static final boolean ADD = true;
+ private static final boolean REMOVE = false;
+
+ public DnsSdDiscoveryAdvertiser() {
+ super(DnsSdNamespace.NAME, new DiscoveryContainerConfig(IDFactory
+ .getDefault().createStringID(
+ DnsSdDiscoveryAdvertiser.class.getName())));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#registerService(org.eclipse.ecf.discovery.IServiceInfo)
+ */
+ public void registerService(final IServiceInfo serviceInfo) {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "registerService(IServiceInfo serviceInfo)", "Registering service"); //$NON-NLS-1$ //$NON-NLS-2$
+ sendToServer(serviceInfo, ADD);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#unregisterService(org.eclipse.ecf.discovery.IServiceInfo)
+ */
+ public void unregisterService(final IServiceInfo serviceInfo) {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "unregisterService(IServiceInfo serviceInfo)", "Unregistering service"); //$NON-NLS-1$ //$NON-NLS-2$
+ sendToServer(serviceInfo, REMOVE);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.discovery.AbstractDiscoveryContainerAdapter#unregisterAllServices()
+ */
+ public void unregisterAllServices() {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "unregisterAllServices()", "Unregistering all services"); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new UnsupportedOperationException("Not yet implemented, see http://bugs.eclipse.org/321959"); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.discovery.AbstractDiscoveryContainerAdapter#purgeCache()
+ */
+ public IServiceInfo[] purgeCache() {
+ // purge cache means renew resolver?
+ throw new UnsupportedOperationException("Not yet implemented, see http://bugs.eclipse.org/"); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#connect(org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.core.security.IConnectContext)
+ */
+ public void connect(final ID aTargetID, final IConnectContext connectContext)
+ throws ContainerConnectException {
+
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "connect(ID aTargetID, IConnectContext connectContext)", "connecting container"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // connect can only be called once
+ if (targetID != null || getConfig() == null) {
+ throw new ContainerConnectException(Messages.DnsSdDiscoveryAdvertiser_Container_Already_Connected);
+ }
+
+ //TODO convert non DnsSdServiceTypeIDs into DSTIDs
+ if(aTargetID == null) {
+ targetID = new DnsSdServiceTypeID();
+ } else {
+ targetID = (DnsSdServiceTypeID) aTargetID;
+ }
+
+ // instantiate a default resolver
+ if(resolver == null) {
+ try {
+ resolver = new SimpleResolver();
+ resolver.setTCP(true);
+ } catch (UnknownHostException e) {
+ throw new ContainerConnectException(e);
+ }
+ }
+
+ // done setting up this provider, send event
+ fireContainerEvent(new ContainerConnectingEvent(this.getID(), targetID,
+ connectContext));
+ fireContainerEvent(new ContainerConnectedEvent(this.getID(), targetID));
+ }
+
+ protected void sendToServer(final IServiceInfo serviceInfo, final boolean mode) {
+ Assert.isNotNull(serviceInfo);
+ Assert.isLegal(serviceInfo.getServiceID() instanceof DnsSdServiceID);
+ final DnsSdServiceID serviceID = (DnsSdServiceID) serviceInfo.getServiceID();
+ try {
+ final Record srvRecord = serviceID.toSRVRecord(); // TYPE.SRV
+ final Record[] txtRecords = serviceID.toTXTRecords(srvRecord); // TYPE.TXT
+ final Name name = serviceID.getDnsName();
+
+ final String[] registrationDomains = getRegistrationDomains(serviceID.getServiceTypeID());
+
+ for (int i = 0; i < registrationDomains.length; i++) {
+ final Name zone = new Name(registrationDomains[i]);
+ final Name fqdn = new Name(name.toString() + "." + zone.toString()); //$NON-NLS-1$
+ final Update update = new Update(zone);
+
+ //TYPE.SRV
+ if(mode == ADD) {
+ //TODO add absent/present condition checks
+ update.replace(srvRecord.withName(fqdn));
+ } else {
+ update.delete(srvRecord.withName(fqdn));
+ }
+
+ //TYPE.TXT
+ for (int j = 0; j < txtRecords.length; j++) {
+ if(mode == ADD) {
+ update.add(txtRecords[j].withName(fqdn));
+ } else {
+ update.delete(txtRecords[j].withName(fqdn));
+ }
+ }
+
+ // set up a the resolver for the given domain (a scope might use different domains)
+ final Collection dnsServers = getUpdateDomain(zone);
+ if(dnsServers.size() == 0) {
+ throw new DnsSdDiscoveryException(Messages.DnsSdDiscoveryAdvertiser_No_DynDns_Servers_Found);
+ }
+ for (final Iterator iterator = dnsServers.iterator(); iterator.hasNext();) {
+ final SRVRecord dnsServer = (SRVRecord) iterator.next();
+
+ // try to send msg and fail gracefully if more dns servers are available
+ final Name target = dnsServer.getTarget();
+ final Message response;
+ final InetAddress byName;
+ try {
+ byName = InetAddress.getByName(target.toString());
+
+ ((SimpleResolver) resolver).setAddress(byName);
+ ((SimpleResolver) resolver).setPort(dnsServer.getPort());
+
+ response = resolver.send(update);
+ } catch (UnknownHostException uhe) {
+ if(iterator.hasNext()) {
+ continue;
+ } else {
+ throw new DnsSdDiscoveryException(uhe);
+ }
+ } catch (EOFException eof) {
+ if(iterator.hasNext()) {
+ continue;
+ } else {
+ throw new DnsSdDiscoveryException(eof);
+ }
+ }
+
+ // catch some errors and fall back to the next dnsServer
+ if (response.getRcode() != Rcode.NOERROR) {
+ if(iterator.hasNext()) {
+ continue;
+ } else {
+ throw DnsSdDiscoveryException.getException(response.getRcode());
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new DnsSdDiscoveryException(e);
+ }
+ }
+
+ protected Collection getUpdateDomain(final Name zone) throws TextParseException {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "getUpdateDomain(Name zone)", "Getting update domain"); //$NON-NLS-1$ //$NON-NLS-2$
+ // query for special "_dns-update" SRV records which mark the server to use for dyndns
+ final Lookup query = new Lookup(_DNS_UPDATE + zone, Type.SRV);
+ // use the SRV record with the lowest priority/weight first
+ final SortedSet srvRecords = getSRVRecord(query, new SRVRecordComparator());
+
+ // if no dedicated "_dns-update" server is configured, fall back to regular authoritative server
+ if(srvRecords.size() == 0) {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "getUpdateDomain(Name zone)", "Found no _dns-update SRV records in zone"); //$NON-NLS-1$ //$NON-NLS-2$
+ return getAuthoritativeNameServer(zone);
+ }
+ return srvRecords;
+ }
+
+ protected Collection getAuthoritativeNameServer(final Name zone) throws TextParseException {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "getAuthoritativeNameServer(Name zone)", "Trying to find authoritative name server"); //$NON-NLS-1$ //$NON-NLS-2$
+ final Set result = new HashSet();
+ final Name name = new Name(_DNS_UPDATE + zone);
+
+ //query for NS records
+ Lookup query = new Lookup(zone, Type.NS);
+ query.setResolver(resolver);
+ Record[] queryResult = query.run();
+ //TODO file bug upstream that queryResult may never be null
+ int length = queryResult == null ? 0 : queryResult.length;
+ for (int j = 0; j < length; j++) {
+ final Record record = queryResult[j];
+ if(record instanceof NSRecord) {
+ final NSRecord nsRecord = (NSRecord) record;
+ final Name target = nsRecord.getTarget();
+ result.add(new SRVRecord(name, DClass.IN, nsRecord.getTTL(), 0, 0, SimpleResolver.DEFAULT_PORT, target));
+ }
+ }
+
+ //query for primary ns in SOA record (may overwrite/be equal to one of the ns records)
+ query = new Lookup(zone, Type.SOA);
+ query.setResolver(resolver);
+ queryResult = query.run();
+ //TODO file bug upstream that queryResult may never be null
+ length = queryResult == null ? 0 : queryResult.length;
+ for (int j = 0; j < length; j++) {
+ final Record record = queryResult[j];
+ if(record instanceof SOARecord) {
+ final SOARecord soaRecord = (SOARecord) record;
+ result.add(new SRVRecord(name, DClass.IN, soaRecord.getTTL(), 0, 0, SimpleResolver.DEFAULT_PORT, soaRecord.getHost()));
+ }
+ }
+ return result;
+ }
+
+ protected String[] getRegistrationDomains(final IServiceTypeID aServiceTypeId) {
+ Trace.trace(Activator.PLUGIN_ID, DnsSdDebugOptions.METHODS_TRACING, this.getClass(), "getRegistrationDomains(IServiceTypeID aServiceTypeId)", "Getting registration domains"); //$NON-NLS-1$ //$NON-NLS-2$
+ final String[] rrs = new String[] {BnRDnsSdServiceTypeID.REG_DOMAINS, BnRDnsSdServiceTypeID.DEFAULT_REG_DOMAIN};
+ final Collection registrationDomains = getBrowsingOrRegistrationDomains(aServiceTypeId, rrs);
+ final String[] scopes = aServiceTypeId.getScopes();
+ for (int i = 0; i < scopes.length; i++) {
+ scopes[i] = scopes[i].concat("."); //$NON-NLS-1$
+ }
+ return registrationDomains.size() == 0 ? scopes : (String[]) registrationDomains.toArray(new String[registrationDomains.size()]);
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryContainerAdapter.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryContainerAdapter.java
new file mode 100644
index 000000000..a7ff7f77a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryContainerAdapter.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.events.ContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ContainerDisconnectingEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.discovery.AbstractDiscoveryContainerAdapter;
+import org.eclipse.ecf.discovery.DiscoveryContainerConfig;
+import org.eclipse.ecf.discovery.IServiceInfo;
+import org.eclipse.ecf.discovery.identity.IServiceID;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.xbill.DNS.Lookup;
+import org.xbill.DNS.Name;
+import org.xbill.DNS.PTRRecord;
+import org.xbill.DNS.Record;
+import org.xbill.DNS.Resolver;
+import org.xbill.DNS.SRVRecord;
+import org.xbill.DNS.SimpleResolver;
+import org.xbill.DNS.TSIG;
+import org.xbill.DNS.Type;
+
+public abstract class DnsSdDiscoveryContainerAdapter extends
+ AbstractDiscoveryContainerAdapter {
+
+ protected Resolver resolver;
+ protected DnsSdServiceTypeID targetID;
+
+ public DnsSdDiscoveryContainerAdapter(String aNamespaceName,
+ DiscoveryContainerConfig aConfig) {
+ super(aNamespaceName, aConfig);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#getServiceInfo(org.eclipse.ecf.discovery.identity.IServiceID)
+ */
+ public IServiceInfo getServiceInfo(IServiceID aServiceId) {
+ Assert.isNotNull(aServiceId);
+ // nop, we are just an Advertiser but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#getServiceTypes()
+ */
+ public IServiceTypeID[] getServiceTypes() {
+ // nop, we are just an Advertiser but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#getServices()
+ */
+ public IServiceInfo[] getServices() {
+ // nop, we are just an Advertiser but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.provider.dnssd.DnsSdDiscoveryLocator#getServices(org.eclipse.ecf.discovery.identity.IServiceTypeID)
+ */
+ public IServiceInfo[] getServices(IServiceTypeID aServiceTypeId) {
+ Assert.isNotNull(aServiceTypeId);
+ // nop, we are just an Advertiser but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.discovery.IDiscoveryAdvertiser#registerService(org.eclipse.ecf.discovery.IServiceInfo)
+ */
+ public void registerService(IServiceInfo serviceInfo) {
+ Assert.isNotNull(serviceInfo);
+ // nop, we are just a Locator but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Advertiser);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.discovery.IDiscoveryAdvertiser#unregisterService(org.eclipse.ecf.discovery.IServiceInfo)
+ */
+ public void unregisterService(IServiceInfo serviceInfo) {
+ Assert.isNotNull(serviceInfo);
+ // nop, we are just a Locator but AbstractDiscoveryContainerAdapter
+ // doesn't support this yet
+ throw new UnsupportedOperationException(
+ Messages.DnsSdDiscoveryContainerAdapter_No_IDiscovery_Advertiser);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.IContainer#connect(org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.core.security.IConnectContext)
+ */
+ public abstract void connect(ID targetID, IConnectContext connectContext)
+ throws ContainerConnectException;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.IContainer#getConnectedID()
+ */
+ public ID getConnectedID() {
+ return targetID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.IContainer#disconnect()
+ */
+ public void disconnect() {
+ fireContainerEvent(new ContainerDisconnectingEvent(this.getID(),
+ getConnectedID()));
+ targetID = null;
+ fireContainerEvent(new ContainerDisconnectedEvent(this.getID(),
+ getConnectedID()));
+ }
+
+ protected Collection getBrowsingOrRegistrationDomains(final IServiceTypeID aServiceTypeId, final String[] rrs) {
+ final Set res = new HashSet();
+ getBrowsingOrRegistrationDomains(aServiceTypeId, rrs, res);
+ return res;
+ }
+
+ private void getBrowsingOrRegistrationDomains(final IServiceTypeID aServiceTypeId,
+ final String[] rrs, final Set res) {
+ for (int i = 0; i < rrs.length; i++) {
+ final BnRDnsSdServiceTypeID serviceType =
+ new BnRDnsSdServiceTypeID(aServiceTypeId, rrs[i]);
+
+ final Record[] records = getRecords(serviceType);
+ if(records.length == 0) {
+ res.addAll(serviceType.getScopesAsZones());
+ } else {
+ for (int j = 0; j < records.length; j++) {
+ final PTRRecord record = (PTRRecord) records[j];
+ final String target = record.getTarget().toString();
+ if(isFinal(record)) {
+ res.add(target.toString());
+ } else {
+ if(!res.contains(target)) { // guard against cycles
+ final BnRDnsSdServiceTypeID newServiceType =
+ new BnRDnsSdServiceTypeID(serviceType, rrs[i]);
+ newServiceType.setScope(target);
+ getBrowsingOrRegistrationDomains(newServiceType, rrs, res);
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isFinal(PTRRecord record) {
+ Name name = record.getName();
+ Name target = record.getTarget();
+ return name.subdomain(target);
+ }
+
+ protected Record[] getRecords(final DnsSdServiceTypeID serviceTypeId) {
+ final List result = new ArrayList();
+ final Lookup[] queries = serviceTypeId.getInternalQueries();
+ for (int i = 0; i < queries.length; i++) {
+ final Lookup query = queries[i];
+ query.setResolver(resolver);
+ final Record[] queryResult = query.run();
+ if(queryResult != null) {
+ result.addAll(Arrays.asList(queryResult));
+ }
+ }
+ return (Record[]) result.toArray(new Record[result.size()]);
+ }
+
+ protected SortedSet getSRVRecords(Lookup[] queries) {
+ return getSRVRecords(queries, null);
+ }
+
+ protected SortedSet getSRVRecords(Lookup[] queries, Comparator aComparator) {
+ final SortedSet srvRecords = new TreeSet(aComparator);
+ for (int i = 0; i < queries.length; i++) {
+ srvRecords.addAll(getSRVRecord(queries[i], aComparator));
+ }
+ return srvRecords;
+ }
+
+ protected SortedSet getSRVRecord(Lookup query, Comparator aComparator) {
+ final SortedSet srvRecords = new TreeSet(aComparator);
+ query.setResolver(resolver);
+ final Record[] queryResult = query.run();
+ //TODO file bug upstream that queryResult may never be null
+ final int length = queryResult == null ? 0 : queryResult.length;
+ for (int j = 0; j < length; j++) {
+ Record[] srvQueryResult = null;
+ final Record record = queryResult[j];
+ if(record instanceof PTRRecord) {
+ final PTRRecord ptrRecord = (PTRRecord) record;
+ final Name target = ptrRecord.getTarget();
+ final Lookup srvQuery = new Lookup(target, Type.SRV);
+ srvQuery.setResolver(resolver);
+ srvQueryResult = srvQuery.run();
+ } else if (record instanceof SRVRecord) {
+ srvQueryResult = new SRVRecord[]{(SRVRecord) record};
+ }
+ srvRecords.addAll(Arrays.asList(srvQueryResult));
+ }
+ return srvRecords;
+ }
+
+ // compares SRV records based on priority and weight
+ protected class SRVRecordComparator implements Comparator {
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object arg0, Object arg1) {
+ if(arg0 instanceof SRVRecord && arg1 instanceof SRVRecord) {
+ SRVRecord srv1 = (SRVRecord) arg0;
+ SRVRecord srv2 = (SRVRecord) arg1;
+ if(srv1.getPriority() > srv2.getPriority()) {
+ return 1;
+ } else if (srv1.getPriority() == srv2.getPriority()) {
+ if(srv1.getWeight() > srv2.getWeight()) {
+ return 1;
+ }
+ return -1;
+ } else {
+ return -1;
+ }
+ }
+ throw new UnsupportedOperationException(Messages.DnsSdDiscoveryContainerAdapter_Comparator_SRV_Records);
+ }
+
+ }
+
+ /**
+ * @param searchPaths The default search path used for discovery
+ */
+ public void setSearchPath(String[] searchPaths) {
+ targetID.setSearchPath(searchPaths);
+ }
+
+ /**
+ * @return The default search path used by this discovery provider
+ */
+ public String[] getSearchPath() {
+ return targetID.getSearchPath();
+ }
+
+ /**
+ * @param aResolver The resolver to use
+ * @throws DnsSdDiscoveryException if hostname cannot be resolved
+ */
+ public void setResolver(String aResolver) {
+ try {
+ resolver = new SimpleResolver(aResolver);
+ } catch (UnknownHostException e) {
+ throw new DnsSdDiscoveryException(e);
+ }
+ }
+
+ /**
+ * @param tsigKeyName A key name/user name for dns dynamic update
+ * @param tsigKey A string representation of the shared key
+ */
+ public void setTsigKey(String tsigKeyName, String tsigKey) {
+ resolver.setTSIGKey(new TSIG(tsigKeyName, tsigKey));
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryException.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryException.java
new file mode 100644
index 000000000..94fdda16c
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryException.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import org.eclipse.ecf.core.util.ECFRuntimeException;
+import org.eclipse.osgi.util.NLS;
+import org.xbill.DNS.Rcode;
+
+
+public class DnsSdDiscoveryException extends ECFRuntimeException {
+
+ public static DnsSdDiscoveryException getException(int rcode) {
+ switch (rcode) {
+ case Rcode.REFUSED:
+ return new DnsSdDiscoveryException(NLS.bind(Messages.DnsSdDiscoveryException_DynDns_Update_Denied, Integer.toString(rcode)));
+ case Rcode.NOTAUTH:
+ return new DnsSdDiscoveryException(NLS.bind(Messages.DnsSdDiscoveryException_TSIG_Verify_Failed, Integer.toString(rcode)));
+ default:
+ return new DnsSdDiscoveryException(NLS.bind(Messages.DnsSdDiscoveryException_DynDNS_Updated_Failed, Integer.toString(rcode)));
+ }
+ }
+
+ private static final long serialVersionUID = 415901701737755102L;
+
+ public DnsSdDiscoveryException(Throwable e) {
+ super(e);
+ }
+
+ public DnsSdDiscoveryException(String message) {
+ super(message);
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryLocator.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryLocator.java
new file mode 100644
index 000000000..1a17a4407
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdDiscoveryLocator.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.events.ContainerConnectedEvent;
+import org.eclipse.ecf.core.events.ContainerConnectingEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.discovery.DiscoveryContainerConfig;
+import org.eclipse.ecf.discovery.IServiceInfo;
+import org.eclipse.ecf.discovery.ServiceInfo;
+import org.eclipse.ecf.discovery.ServiceProperties;
+import org.eclipse.ecf.discovery.identity.IServiceID;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.xbill.DNS.Lookup;
+import org.xbill.DNS.Name;
+import org.xbill.DNS.PTRRecord;
+import org.xbill.DNS.Record;
+import org.xbill.DNS.ResolverConfig;
+import org.xbill.DNS.SRVRecord;
+import org.xbill.DNS.SimpleResolver;
+import org.xbill.DNS.TXTRecord;
+import org.xbill.DNS.Type;
+
+public class DnsSdDiscoveryLocator extends DnsSdDiscoveryContainerAdapter {
+
+ private static final String DNS_SD_PATH = "path"; //$NON-NLS-1$
+ private static final String DNS_SD_PTCL = "dns-sd.ptcl"; //$NON-NLS-1$
+
+ public DnsSdDiscoveryLocator() {
+ super(DnsSdNamespace.NAME, new DiscoveryContainerConfig(IDFactory
+ .getDefault().createStringID(
+ DnsSdDiscoveryLocator.class.getName())));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ecf.discovery.IDiscoveryLocator#getServiceInfo(org.eclipse
+ * .ecf.discovery.identity.IServiceID)
+ */
+ public IServiceInfo getServiceInfo(IServiceID aServiceId) {
+ Assert.isNotNull(aServiceId);
+ IServiceInfo[] services = getServices(aServiceId.getServiceTypeID());
+ for (int i = 0; i < services.length; i++) {
+ //TODO This can be a lot faster if done directly instead of via org.eclipse.ecf.provider.dnssrv.DnsSrvDisocoveryLocator.getServices(IServiceTypeID)
+ IServiceInfo iServiceInfo = services[i];
+ if(iServiceInfo.getServiceID().equals(aServiceId)) {
+ return iServiceInfo;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This always returns the service type found for our local domain
+ * Use org.eclipse.ecf.provider.dnssrv.DnsSrvDisocoveryLocator.getServices(IServiceTypeID) with a wildcard query instead.
+ *
+ * @see org.eclipse.ecf.discovery.IDiscoveryLocator#getServiceTypes()
+ */
+ public IServiceTypeID[] getServiceTypes() {
+ // technically can't do anything without a scope (domain) -> falling back to local domain (mDNS?)
+ DnsSdServiceTypeID serviceTypeId = (DnsSdServiceTypeID) targetID;
+ return getServiceTypes(serviceTypeId);
+ }
+
+ private IServiceTypeID[] getServiceTypes(final DnsSdServiceTypeID serviceTypeId) {
+ List result = new ArrayList();
+ Record[] queryResult = getRecords(serviceTypeId);
+ for (int j = 0; j < queryResult.length; j++) {
+ Record record = queryResult[j];
+ if(record instanceof PTRRecord) {
+ PTRRecord ptrRecord = (PTRRecord) record;
+ result.add(new DnsSdServiceTypeID(getServicesNamespace(), ptrRecord.getTarget()));
+ } else if (record instanceof SRVRecord) {
+ SRVRecord srvRecord = (SRVRecord) record;
+ result.add(new DnsSdServiceTypeID(getServicesNamespace(), srvRecord.getName()));
+ }
+ }
+ return (IServiceTypeID[]) result.toArray(new IServiceTypeID[result.size()]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.discovery.IDiscoveryLocator#getServices()
+ */
+ public IServiceInfo[] getServices() {
+ // technically can't do anything without a scope (domain) -> falling back to local domain (mDNS?)
+ return getServices(targetID);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ecf.discovery.IDiscoveryLocator#getServices(org.eclipse.ecf
+ * .discovery.identity.IServiceTypeID)
+ */
+ public IServiceInfo[] getServices(IServiceTypeID aServiceTypeId) {
+ Assert.isNotNull(aServiceTypeId);
+ DnsSdServiceTypeID serviceTypeId = (DnsSdServiceTypeID) aServiceTypeId;
+ Collection srvRecords = getSRVRecords(serviceTypeId.getInternalQueries());
+ List serviceInfos = getServiceInfos(srvRecords);
+ return (IServiceInfo[]) serviceInfos.toArray(new IServiceInfo[serviceInfos.size()]);
+ }
+
+ private List getServiceInfos(Collection srvQueryResult) {
+ List infos = new ArrayList();
+ for (Iterator iterator = srvQueryResult.iterator(); iterator.hasNext();) {
+ SRVRecord srvRecord = (SRVRecord) iterator.next();
+ long ttl = srvRecord.getTTL();
+ int priority = srvRecord.getPriority();
+ int weight = srvRecord.getWeight();
+ int port = srvRecord.getPort();
+ Name target = srvRecord.getTarget();
+ String host = target.toString();
+ host = host.substring(0, host.length() - 1);
+
+ IServiceTypeID aServiceTypeID = new DnsSdServiceTypeID(getConnectNamespace(), srvRecord.getName());
+
+ // query for txt records (attributes)
+ Properties props = new Properties();
+ Lookup txtQuery = new Lookup(srvRecord.getName(), Type.TXT);
+ txtQuery.setResolver(resolver);
+ Record[] txtQueryResults = txtQuery.run();
+ int length = txtQueryResults == null ? 0 : txtQueryResults.length;
+ for (int l = 0; l < length; l++) {
+ TXTRecord txtResult = (TXTRecord) txtQueryResults[l];
+ List strings = txtResult.getStrings();
+ for (Iterator itr = strings.iterator(); itr.hasNext();) {
+ String str = (String) itr.next();
+ String[] split = str.split("="); //$NON-NLS-1$
+ props.put(split[0], split[1]);
+ }
+ }
+ String path = props.getProperty(DNS_SD_PATH);
+ String proto = props.getProperty(DNS_SD_PTCL) == null ? aServiceTypeID.getProtocols()[0] : props.getProperty(DNS_SD_PTCL);
+
+ URI uri = URI.create(proto + "://" + host + ":" + port + (path == null ? "" : path)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ IServiceInfo info =new ServiceInfo(uri, host, aServiceTypeID, priority, weight, new ServiceProperties(props), ttl);
+ infos.add(info);
+ }
+ return infos;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ecf.core.IContainer#connect(org.eclipse.ecf.core.identity.ID,
+ * org.eclipse.ecf.core.security.IConnectContext)
+ */
+ public void connect(ID aTargetID, IConnectContext connectContext)
+ throws ContainerConnectException {
+
+ // connect can only be called once
+ if (targetID != null || getConfig() == null) {
+ throw new ContainerConnectException(Messages.DnsSdDiscoveryLocator_Container_Already_Connected);
+ }
+
+ // fall back to the search path as last resort
+ if(aTargetID == null || !(aTargetID instanceof DnsSdServiceTypeID)) {
+ ResolverConfig config = new ResolverConfig();
+ Name[] searchPaths = config.searchPath();
+ if(searchPaths != null && searchPaths.length > 0) {
+ targetID = new DnsSdServiceTypeID();
+ targetID.setSearchPath(searchPaths);
+ } else {
+ throw new ContainerConnectException(Messages.DnsSdDiscoveryLocator_No_Target_ID);
+ }
+ } else {
+ targetID = (DnsSdServiceTypeID) aTargetID;
+ }
+
+ // instantiate a default resolver
+ if(resolver == null) {
+ try {
+ resolver = new SimpleResolver();
+ } catch (UnknownHostException e) {
+ throw new ContainerConnectException(e);
+ }
+ }
+
+ // read browsing domains for the given targetID/searchpath and merge with existing
+ targetID.addSearchPath(getBrowsingDomains(targetID));
+
+ // done setting up this provider, send event
+ fireContainerEvent(new ContainerConnectingEvent(this.getID(), targetID,
+ connectContext));
+ fireContainerEvent(new ContainerConnectedEvent(this.getID(), targetID));
+ }
+
+ private String[] getBrowsingDomains(IServiceTypeID aServiceTypeId) {
+ final String[] rrs = new String[] {BnRDnsSdServiceTypeID.BROWSE_DOMAINS, BnRDnsSdServiceTypeID.DEFAULT_BROWSE_DOMAIN};
+ final Collection res = getBrowsingOrRegistrationDomains(aServiceTypeId, rrs);
+ return (String[]) res.toArray(new String[res.size()]);
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdNamespace.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdNamespace.java
new file mode 100644
index 000000000..719f97d23
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdNamespace.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.net.URI;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDCreateException;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+
+public class DnsSdNamespace extends Namespace {
+
+ private static final long serialVersionUID = 7902507535188221743L;
+
+ public static final String SCHEME = "dnssd"; //$NON-NLS-1$
+ public static final String NAME = "ecf.namespace.dnssd"; //$NON-NLS-1$
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.identity.Namespace#createInstance(java.lang.Object[])
+ */
+ public ID createInstance(Object[] parameters) throws IDCreateException {
+ if(parameters != null && parameters.length == 1 && parameters[0] instanceof String) {
+ String str = (String) parameters[0];
+ return new DnsSdServiceTypeID(this, str);
+ } else if (parameters != null && parameters.length == 1 && parameters[0] instanceof IServiceTypeID) {
+ IServiceTypeID serviceTypeID = (IServiceTypeID) parameters[0];
+ return new DnsSdServiceTypeID(this, serviceTypeID);
+ } else if (parameters != null && parameters.length == 2 && parameters[0] instanceof IServiceTypeID && parameters[1] instanceof URI) {
+ IServiceTypeID serviceTypeID = (IServiceTypeID) parameters[0];
+ URI uri = (URI) parameters[1];
+ return new DnsSdServiceID(this, new DnsSdServiceTypeID(this, serviceTypeID), uri);
+ } else {
+ throw new IDCreateException(Messages.DnsSdNamespace_Wrong_Parameters);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.identity.Namespace#getScheme()
+ */
+ public String getScheme() {
+ return SCHEME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.core.identity.Namespace#getSupportedParameterTypes()
+ */
+ public Class[][] getSupportedParameterTypes() {
+ return new Class[][] {{String.class}, {IServiceTypeID.class}, {IServiceTypeID.class, URI.class}};
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceID.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceID.java
new file mode 100644
index 000000000..08f9fc95a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceID.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.discovery.IServiceProperties;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.eclipse.ecf.discovery.identity.ServiceID;
+import org.xbill.DNS.DClass;
+import org.xbill.DNS.Name;
+import org.xbill.DNS.Record;
+import org.xbill.DNS.SRVRecord;
+import org.xbill.DNS.TXTRecord;
+import org.xbill.DNS.TextParseException;
+
+public class DnsSdServiceID extends ServiceID {
+
+ private static final long serialVersionUID = -5265675009221335638L;
+
+ protected DnsSdServiceID(final Namespace namespace, final IServiceTypeID type, final URI anUri) {
+ super(namespace, type, anUri);
+ }
+
+
+ Name getDnsName() throws TextParseException {
+ return new Name("_" + type.getServices()[0] + "._" //$NON-NLS-1$ //$NON-NLS-2$
+ + type.getProtocols()[0]);
+ }
+
+ /**
+ * @return A relative SRV record independent of a given domain/zone
+ * @throws IOException
+ */
+ Record toSRVRecord() throws IOException {
+ final Name name = new Name(getDnsName().toString(), new Name(type.getScopes()[0] + ".")); //$NON-NLS-1$
+ final long ttl = serviceInfo.getTTL();
+ final int priority = serviceInfo.getPriority();
+ final int weight = serviceInfo.getWeight();
+ final int port = serviceInfo.getLocation().getPort();
+ final Name target = Name.fromString(serviceInfo.getLocation().getHost() + "."); //$NON-NLS-1$
+
+ return new SRVRecord(name, DClass.IN, ttl, priority, weight, port, target);
+ }
+
+ /**
+ * @param aRecord The corresponding SRVRecord
+ * @return A relative TXT record independent of a given domain/zone
+ * @throws IOException
+ */
+ Record[] toTXTRecords(final Record aRecord) throws IOException {
+ final List result = new ArrayList();
+ final IServiceProperties properties = serviceInfo.getServiceProperties();
+ final Enumeration enumeration = properties.getPropertyNames();
+ while (enumeration.hasMoreElements()) {
+ final Object property = enumeration.nextElement();
+ final String key = property.toString();
+ final String value = (String) properties.getProperty(key).toString();
+ final long ttl = serviceInfo.getTTL();
+ result.add(new TXTRecord(aRecord.getName(), DClass.IN, ttl, key + "=" + value)); //$NON-NLS-1$
+ }
+ return (Record[]) result.toArray(new Record[result.size()]);
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceTypeID.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceTypeID.java
new file mode 100644
index 000000000..55aab3fac
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/DnsSdServiceTypeID.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.ecf.core.identity.IDCreateException;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.discovery.identity.IServiceTypeID;
+import org.eclipse.ecf.discovery.identity.ServiceTypeID;
+import org.xbill.DNS.Lookup;
+import org.xbill.DNS.Name;
+import org.xbill.DNS.TextParseException;
+import org.xbill.DNS.Type;
+
+public class DnsSdServiceTypeID extends ServiceTypeID implements IServiceTypeID {
+
+ private static final long serialVersionUID = 1247933069737880365L;
+
+ DnsSdServiceTypeID() {
+ super(new DnsSdNamespace());
+ scopes = DEFAULT_SCOPE;
+ protocols = DEFAULT_PROTO;
+ namingAuthority = DEFAULT_NA;
+ services = new String[]{""}; //$NON-NLS-1$
+ }
+
+ public DnsSdServiceTypeID(Namespace ns, IServiceTypeID id) {
+ super(ns, id);
+ }
+
+ public DnsSdServiceTypeID(Namespace namespace, String aType)
+ throws IDCreateException {
+ super(namespace, aType);
+ }
+
+ DnsSdServiceTypeID(Namespace namespace, Name aName) {
+ super(namespace, aName.toString());
+ }
+
+ Lookup[] getInternalQueries() {
+ String[] protos = protocols;
+ int type = Type.SRV;
+
+ String service = null;
+ if (services == null || services.length == 0
+ || (services.length == 1 && services[0].equals(""))) { //$NON-NLS-1$
+ // if no service is set, create a non service specific query
+ service = "_services._dns-sd._"; //$NON-NLS-1$
+
+ // and set proto to "udp" irregardless what has been set
+ protos = new String[] { "udp" }; //$NON-NLS-1$
+
+ // and query for PTR records
+ type = Type.PTR;
+ } else {
+ service = "_"; //$NON-NLS-1$
+ for (int i = 0; i < services.length; i++) {
+ service += services[i];
+ service += "._"; //$NON-NLS-1$
+ }
+ }
+
+ List result = new ArrayList();
+ for (int i = 0; i < scopes.length; i++) {
+ String scope = scopes[i];
+ // remove dangling "."
+ if(scope.endsWith(".")) { //$NON-NLS-1$
+ scope = scope.substring(0, scope.length() - 1);
+ }
+ for (int j = 0; j < protos.length; j++) {
+ Lookup query;
+ try {
+ query = new Lookup(service + protos[j] + "." + scope + ".", //$NON-NLS-1$ //$NON-NLS-2$
+ type);
+ } catch (TextParseException e) {
+ continue;
+ }
+ result.add(query);
+ }
+ }
+ return (Lookup[]) result.toArray(new Lookup[result.size()]);
+ }
+
+ /**
+ * @param searchPaths Sets the default search path
+ */
+ void setSearchPath(Name[] searchPaths) {
+ String[] s = new String[searchPaths.length];
+ for(int i = 0; i < searchPaths.length; i++) {
+ s[i] = searchPaths[i].toString();
+ }
+ setSearchPath(s);
+ }
+
+ /**
+ * @param searchPaths Sets the default search path
+ */
+ void setSearchPath(String[] searchPaths) {
+ scopes = searchPaths;
+ }
+
+ /**
+ * @return Search scopes used during discovery
+ */
+ String[] getSearchPath() {
+ return scopes;
+ }
+
+ /**
+ * @param additionalSearchPaths Adds the given array to the existing search paths
+ */
+ void addSearchPath(String[] additionalSearchPaths) {
+ //convert arrays to collections (lists)
+ Collection coll1 = Arrays.asList(scopes);
+ Collection coll2 = Arrays.asList(additionalSearchPaths);
+
+ // remove dupes
+ Set s = new HashSet();
+ s.addAll(coll1);
+ s.addAll(coll2);
+
+ // convert into new scopes
+ scopes = (String[]) s.toArray(new String[s.size()]);
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/IDnsSdDiscoveryConstants.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/IDnsSdDiscoveryConstants.java
new file mode 100644
index 000000000..445fe3948
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/IDnsSdDiscoveryConstants.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Markus Alexander Kuppe.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe (ecf-dev_eclipse.org <at> lemmster <dot> de) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ecf.provider.dnssd;
+
+public interface IDnsSdDiscoveryConstants {
+
+ /**
+ * Config admin key to define the default search path
+ */
+ public final String CA_SEARCH_PATH = "searchPath"; //$NON-NLS-1$
+ /**
+ * Config admin key to define the default resolver
+ */
+ public final String CA_RESOLVER = "resolver"; //$NON-NLS-1$
+
+ /**
+ * Config admin key to define the TSIG key to be used to sign requests
+ */
+ public final String CA_TSIG_KEY = "tsig-key"; //$NON-NLS-1$
+ public final Object CA_TSIG_KEY_NAME = "tsig-key-name"; //$NON-NLS-1$
+
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Messages.java b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Messages.java
new file mode 100644
index 000000000..9bc75293d
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/Messages.java
@@ -0,0 +1,27 @@
+package org.eclipse.ecf.provider.dnssd;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.ecf.provider.dnssd.messages"; //$NON-NLS-1$
+ public static String DnsSdDiscoveryAdvertiser_Container_Already_Connected;
+ public static String DnsSdDiscoveryAdvertiser_No_DynDns_Servers_Found;
+ public static String DnsSdDiscoveryContainerAdapter_Comparator_SRV_Records;
+ public static String DnsSdDiscoveryContainerAdapter_No_IDiscovery_Advertiser;
+ public static String DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator;
+ public static String DnsSdDiscoveryException_1;
+ public static String DnsSdDiscoveryException_3;
+ public static String DnsSdDiscoveryException_DynDns_Update_Denied;
+ public static String DnsSdDiscoveryException_DynDNS_Updated_Failed;
+ public static String DnsSdDiscoveryException_TSIG_Verify_Failed;
+ public static String DnsSdDiscoveryLocator_Container_Already_Connected;
+ public static String DnsSdDiscoveryLocator_No_Target_ID;
+ public static String DnsSdNamespace_Wrong_Parameters;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/messages.properties b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/messages.properties
new file mode 100644
index 000000000..39797cb1a
--- /dev/null
+++ b/providers/bundles/org.eclipse.ecf.provider.dnssd/src/org/eclipse/ecf/provider/dnssd/messages.properties
@@ -0,0 +1,11 @@
+DnsSdDiscoveryAdvertiser_Container_Already_Connected=Already connected
+DnsSdDiscoveryAdvertiser_No_DynDns_Servers_Found=No server for dnsupdate could be found
+DnsSdDiscoveryContainerAdapter_Comparator_SRV_Records=This appears to be a bug: Comparator can only compare SRVRecords
+DnsSdDiscoveryContainerAdapter_No_IDiscovery_Advertiser=This is not an IDiscoveryAdvertiser
+DnsSdDiscoveryContainerAdapter_No_IDiscovery_Locator=This is not an IDiscoveryLocator
+DnsSdDiscoveryException_DynDns_Update_Denied=DNS update denied by server (return code: {0} )
+DnsSdDiscoveryException_DynDNS_Updated_Failed=DNS update failed with return code: {0}
+DnsSdDiscoveryException_TSIG_Verify_Failed=TSIG verify failed (BADKEY) (return code: {0} )
+DnsSdDiscoveryLocator_Container_Already_Connected=Already connected
+DnsSdDiscoveryLocator_No_Target_ID=No target id given and fallbacks failed
+DnsSdNamespace_Wrong_Parameters=Wrong parameters

Back to the top