Skip to main content
summaryrefslogblamecommitdiffstats
blob: 781705b25203d974219e5f6c17f4bb05812f1b57 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                               








                                                 
                            
                        
 




                                       
 
                                                

                                                      
                                               




                                                               
                                                   
                                        
                                                       
                                               
                                               
                                                     
                                              
                                       





                                                       
                                                     
                                                    
                                                           

                                                                 
                                                        


                                                              
                                                                         
                                                               


                                                                                      
                                      

                                


                                                     
                                                

                                                                                

                           
 
                           



                                              
         
 
                                                                            
                                           
                        
                                                                          

                                                                                          
         
 



                                                                                                                                                     










                                                                       
 


                                                                                                                                           


                                                                           
 







                                                                                     
 


                                                         

                               
                                                                       
         
 
                                                            
                                                                              
                                                 
                                                                                 








                                                                                              
 
                                                              
                                                                              
                                                 
                                                                                 








                                                                                                
 
                                                               
                                                                              
                                                 
                                                                                 








                                                                                                 
 



                                                                                          


                                                                                                


                         
 


                                                                           



                                                 


                                                                                                      

                 
 


                                                                


                                    
 
                        
                                                                                                                                       
           
                                                                             
                                                     





                                                                                    

                                                                                         
                                                    


                                                                                    
         
 



                                                                                                  
                                                         
                                    
                                                              



                                                                                            




                                 
 


                                                                                                                                        

                                                                    




                                                                                      








                                                                                       
                                  
                 
                                                                                       
         
 


                                                            
                                  




                                                                                
                 

                                                                               
         
 

                                                                                       

                                                    
                                                                        




                                                                                  
 
                                                                 


                                                        
                                                                                  




                                                            
                                                    

                                                                      

                                                                           



                                                                           

                                                                                     

                                                                        
                                                                        
                         
 
                                                                      
                                                                             
                         
 
                                                                     
                                                                            
                         
 
                                                                

                                                                            
 


                                                                              
 


                                                                                   
 

                                                                                    





                                                                                      
 
                                                                       

                                    

                                                                                         
                                               
                                              
                                                             

                                                                                               


                          
 
                                                                


                                                   
                                                            


                                                                                 

                                                                           











                                                                                     
 






                                                                                  
 


                                                                                                                            





                                                                                   
         
 


                                                                                                          
                                                             
                                    

                                                                    

                 
 

                                                                         
                                    

                                                                                                         

                 
 



                                                                                                                                                        









                                                                       
 


                                                                                                                                              


                                                                              
 
                        
                                                                                                                                           
           
                                                                         


                                                                                  

                 
 
                                                     



                                                       
                                                                     

                                                                                                       


                         
 
                                                       



                                                         
                                                                     

                                                                                                       


                         
 
                                                        



                                                          
                                                                     

                                                                                                       


                         
 
                                                         



                                                           
                                                                     

                                                                                                       


                         
 


                                                                                                                              
                                                                 
                                    

                                                                                                           

                 
 


                                                                     


                                                                                     
 


                                                                                                    
                                                       



                                          
 


                                                                                                       




                                                          
        
 
/****************************************************************************
 * Copyright (c) 2004 Composent, Inc. and others.
 * 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:
 *    Composent, Inc. - initial API and implementation
 *****************************************************************************/
package org.eclipse.ecf.provider.jmdns.container;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;
import javax.jmdns.ServiceTypeListener;

import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.IContainerListener;
import org.eclipse.ecf.core.events.ContainerConnectedEvent;
import org.eclipse.ecf.core.events.ContainerConnectingEvent;
import org.eclipse.ecf.core.events.ContainerDisconnectedEvent;
import org.eclipse.ecf.core.events.ContainerDisconnectingEvent;
import org.eclipse.ecf.core.events.ContainerDisposeEvent;
import org.eclipse.ecf.core.events.IContainerEvent;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.discovery.IServiceInfo;
import org.eclipse.ecf.discovery.IServiceListener;
import org.eclipse.ecf.discovery.IServiceProperties;
import org.eclipse.ecf.discovery.IServiceTypeListener;
import org.eclipse.ecf.discovery.ServiceContainerEvent;
import org.eclipse.ecf.discovery.ServiceProperties;
import org.eclipse.ecf.discovery.identity.IServiceID;
import org.eclipse.ecf.discovery.identity.ServiceID;
import org.eclipse.ecf.discovery.service.IDiscoveryService;
import org.eclipse.ecf.internal.provider.jmdns.JMDNSDebugOptions;
import org.eclipse.ecf.internal.provider.jmdns.JMDNSPlugin;
import org.eclipse.ecf.internal.provider.jmdns.Messages;
import org.eclipse.ecf.provider.jmdns.identity.JMDNSServiceID;

public class JMDNSDiscoveryContainer implements IContainer,
		IDiscoveryService, ServiceListener, ServiceTypeListener {
	public static final int DEFAULT_REQUEST_TIMEOUT = 3000;
	protected static String JMDNS_NAMESPACE_ID = Messages
			.getString("JMDNSPlugin.namespace.identifier"); //$NON-NLS-1$;

	ContainerConfig config = null;
	InetAddress intf = null;
	JmDNS jmdns = null;
	int requestTimeout = DEFAULT_REQUEST_TIMEOUT;
	Map serviceListeners = new HashMap();
	Vector serviceTypeListeners = new Vector();
	private Vector listeners = new Vector();

	public JMDNSDiscoveryContainer() throws IOException, IDCreateException {
		this(null);
	}

	public ID getID() {
		if (config == null)
			return null;
		else
			return config.getID();
	}

	public JMDNSDiscoveryContainer(InetAddress addr) throws IOException,
			IDCreateException {
		super();
		intf = (addr == null) ? InetAddress.getLocalHost() : addr;
		this.config = new ContainerConfig(IDFactory.getDefault()
				.createStringID(JMDNSDiscoveryContainer.class.getName()));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#addServiceListener(java.lang.String, org.eclipse.ecf.discovery.IServiceListener)
	 */
	public void addServiceListener(String type, IServiceListener listener) {
		if (type == null || listener == null)
			return;
		synchronized (serviceListeners) {
			Vector v = (Vector) serviceListeners.get(type);
			if (v == null) {
				v = new Vector();
				serviceListeners.put(type, v);
			}
			v.add(listener);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#addServiceTypeListener(org.eclipse.ecf.discovery.IServiceTypeListener)
	 */
	public void addServiceTypeListener(IServiceTypeListener listener) {
		serviceTypeListeners.add(listener);
	}

	protected void fireContainerEvent(IContainerEvent event) {
		synchronized (listeners) {
			for (Iterator i = listeners.iterator(); i.hasNext();) {
				IContainerListener l = (IContainerListener) i.next();
				l.handleEvent(event);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#dispose()
	 */
	public void dispose() {
		disconnect();
		fireContainerEvent(new ContainerDisposeEvent(getID()));
	}

	protected void fireServiceAdded(ServiceEvent arg0) {
		IServiceInfo iinfo = createIServiceInfoFromServiceEvent(arg0);
		synchronized (serviceListeners) {
			Vector v = (Vector) serviceListeners.get(arg0.getType());
			if (v != null) {
				for (Iterator i = v.iterator(); i.hasNext();) {
					IServiceListener l = (IServiceListener) i.next();
					l.serviceAdded(new ServiceContainerEvent(iinfo, config
							.getID()));
				}
			}
		}
	}

	protected void fireServiceRemoved(ServiceEvent arg0) {
		IServiceInfo iinfo = createIServiceInfoFromServiceEvent(arg0);
		synchronized (serviceListeners) {
			Vector v = (Vector) serviceListeners.get(arg0.getType());
			if (v != null) {
				for (Iterator i = v.iterator(); i.hasNext();) {
					IServiceListener l = (IServiceListener) i.next();
					l.serviceRemoved(new ServiceContainerEvent(iinfo, config
							.getID()));
				}
			}
		}
	}

	protected void fireServiceResolved(ServiceEvent arg0) {
		IServiceInfo iinfo = createIServiceInfoFromServiceEvent(arg0);
		synchronized (serviceListeners) {
			Vector v = (Vector) serviceListeners.get(arg0.getType());
			if (v != null) {
				for (Iterator i = v.iterator(); i.hasNext();) {
					IServiceListener l = (IServiceListener) i.next();
					l.serviceResolved(new ServiceContainerEvent(iinfo, config
							.getID()));
				}
			}
		}
	}

	protected void fireServiceTypeAdded(ServiceEvent arg0) {
		synchronized (serviceTypeListeners) {
			for (Iterator i = serviceTypeListeners.iterator(); i.hasNext();) {
				IServiceTypeListener l = (IServiceTypeListener) i.next();
				l.serviceTypeAdded(new ServiceContainerEvent(
						createIServiceInfoFromServiceEvent(arg0), config
								.getID()));
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter.isInstance(this)) {
			return this;
		} else {
			IAdapterManager adapterManager = JMDNSPlugin.getDefault().getAdapterManager();
			if (adapterManager == null) return null;
			return adapterManager.getAdapter(this, adapter);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#getConnectedID()
	 */
	public ID getConnectedID() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#getServiceInfo(org.eclipse.ecf.discovery.identity.IServiceID, int)
	 */
	public IServiceInfo getServiceInfo(IServiceID service, int timeout) {
		Trace.entering(JMDNSPlugin.PLUGIN_ID,
				JMDNSDebugOptions.METHODS_ENTERING, this.getClass(),
				"getServiceInfo",
				new Object[] { service, new Integer(timeout) });
		IServiceInfo result = null;
		if (jmdns != null)
			result = createIServiceInfoFromServiceInfo(jmdns
					.getServiceInfo(service.getServiceType(), service
							.getServiceName(), timeout));
		Trace.exiting(JMDNSPlugin.PLUGIN_ID,
				JMDNSDebugOptions.METHODS_ENTERING, this.getClass(),
				"getServiceInfo", result);
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#getServices(java.lang.String)
	 */
	public IServiceInfo[] getServices(String type) {
		IServiceInfo svs[] = new IServiceInfo[0];
		if (jmdns != null) {
			ServiceInfo[] svcs = jmdns.list(type);
			if (svcs != null) {
				svs = new IServiceInfo[svcs.length];
				for (int i = 0; i < svcs.length; i++) {
					svs[i] = createIServiceInfoFromServiceInfo(svcs[i]);
				}
			}
		}
		return svs;
	}

	/* (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 groupID, IConnectContext joinContext)
			throws ContainerConnectException {
		if (this.jmdns != null)
			throw new ContainerConnectException("Already connected");
		fireContainerEvent(new ContainerConnectingEvent(this.getID(), groupID,
				joinContext));
		try {
			this.jmdns = new JmDNS(intf);
			jmdns.addServiceTypeListener(this);
			if (groupID != null && groupID instanceof JMDNSServiceID) {
				ServiceID svcid = (ServiceID) groupID;
				jmdns.addServiceListener(svcid.getServiceType(), this);
			}
		} catch (IOException e) {
			ContainerConnectException soe = new ContainerConnectException(
					"Exception creating JmDNS instance");
			throw soe;
		}
		fireContainerEvent(new ContainerConnectedEvent(this.getID(), groupID));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#disconnect()
	 */
	public void disconnect() {
		fireContainerEvent(new ContainerDisconnectingEvent(this.getID(),
				getConnectedID()));
		if (this.jmdns != null) {
			jmdns.close();
			jmdns = null;
		}
		fireContainerEvent(new ContainerDisconnectedEvent(this.getID(),
				getConnectedID()));
	}

	protected IServiceInfo createIServiceInfoFromServiceEvent(ServiceEvent event) {
		ServiceID sID = createServiceID(event.getType(), event.getName());
		ServiceInfo sinfo = event.getInfo();
		if (sinfo != null) {
			return createIServiceInfoFromServiceInfo(sinfo);
		}
		IServiceInfo newInfo = new JMDNSServiceInfo(null, sID, -1, -1, -1,
				new ServiceProperties());
		return newInfo;
	}

	protected IServiceInfo createIServiceInfoFromServiceInfo(
			final ServiceInfo serviceInfo) {
		if (serviceInfo == null)
			return null;
		ServiceID sID = createServiceID(serviceInfo.getType(), serviceInfo
				.getName());
		InetAddress addr = serviceInfo.getAddress();
		int port = serviceInfo.getPort();
		int priority = serviceInfo.getPriority();
		int weight = serviceInfo.getWeight();
		Properties props = new Properties();
		for (Enumeration e = serviceInfo.getPropertyNames(); e
				.hasMoreElements();) {
			String name = (String) e.nextElement();
			Object value = serviceInfo.getPropertyString(name);
			if (value == null)
				value = serviceInfo.getPropertyBytes(name);
			if (value != null)
				props.put(name, value);
		}
		final ServiceProperties svcProperties = new ServiceProperties(props);
		IServiceProperties newProps = new IServiceProperties() {
			public Enumeration getPropertyNames() {
				return svcProperties.getPropertyNames();
			}

			public String getPropertyString(String name) {
				return svcProperties.getPropertyString(name);
			}

			public byte[] getPropertyBytes(String name) {
				return svcProperties.getPropertyBytes(name);
			}

			public Object getProperty(String name) {
				return svcProperties.getPropertyBytes(name);
			}

			public Object setProperty(String name, Object value) {
				return svcProperties.setProperty(name, value);
			}

			public Object setPropertyBytes(String name, byte[] value) {
				return svcProperties.setPropertyBytes(name, value);
			}

			public Object setPropertyString(String name, String value) {
				return svcProperties.setPropertyString(name, value);
			}
		};
		IServiceInfo newInfo = new JMDNSServiceInfo(addr, sID, port, priority,
				weight, newProps);
		return newInfo;
	}

	protected ServiceID createServiceID(String type, String name) {
		ServiceID id = null;
		try {
			id = (ServiceID) IDFactory.getDefault().createID(
					JMDNS_NAMESPACE_ID, new Object[] { type, name });
		} catch (IDCreateException e) {
			// Should never happen
			Trace.catching(JMDNSPlugin.PLUGIN_ID,
					JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(),
					"createServiceID", e);
		}
		return id;
	}

	protected ServiceInfo createServiceInfoFromIServiceInfo(
			IServiceInfo serviceInfo) {
		if (serviceInfo == null)
			return null;
		IServiceID sID = serviceInfo.getServiceID();
		Hashtable props = new Hashtable();
		IServiceProperties svcProps = serviceInfo.getServiceProperties();
		if (svcProps != null) {
			for (Enumeration e = svcProps.getPropertyNames(); e
					.hasMoreElements();) {
				String key = (String) e.nextElement();
				Object val = svcProps.getProperty(key);
				if (val != null) {
					props.put(key, val);
				}
			}
		}
		ServiceInfo si = new ServiceInfo(sID.getServiceType(), sID
				.getServiceName(), serviceInfo.getPort(), serviceInfo
				.getPriority(), serviceInfo.getWeight(), props);
		return si;
	}

	protected String prepareSvcTypeForBonjour(String svcType) {
		String result = svcType;
		if (svcType.endsWith(".local.")) {
			result = svcType.substring(0, svcType.indexOf(".local."));
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#registerService(org.eclipse.ecf.discovery.IServiceInfo)
	 */
	public void registerService(IServiceInfo serviceInfo) throws ECFException {
		try {
			registerServiceWithJmDNS(serviceInfo);
		} catch (IOException e) {
			throw new ECFException("registerService",e);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#registerServiceType(java.lang.String)
	 */
	public void registerServiceType(String serviceType) {
		if (jmdns != null) {
			jmdns.registerServiceType(serviceType);
			jmdns.addServiceListener(serviceType, this);
		}
	}

	protected void registerServiceWithJmDNS(IServiceInfo serviceInfo)
			throws IOException {
		if (jmdns != null) {
			jmdns
					.registerService(createServiceInfoFromIServiceInfo(serviceInfo));
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#removeServiceListener(java.lang.String, org.eclipse.ecf.discovery.IServiceListener)
	 */
	public void removeServiceListener(String type, IServiceListener listener) {
		if (type == null || listener == null)
			return;
		synchronized (serviceListeners) {
			Vector v = (Vector) serviceListeners.get(type);
			if (v == null) {
				return;
			}
			v.remove(listener);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#removeServiceTypeListener(org.eclipse.ecf.discovery.IServiceTypeListener)
	 */
	public void removeServiceTypeListener(IServiceTypeListener listener) {
		serviceTypeListeners.add(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#requestServiceInfo(org.eclipse.ecf.discovery.identity.IServiceID, int)
	 */
	public void requestServiceInfo(IServiceID service, int timeout) {
		if (jmdns != null) {
			jmdns.requestServiceInfo(service.getServiceType(), service
					.getServiceName(), timeout);
		}
	}

	public void serviceAdded(ServiceEvent arg0) {
		if (jmdns != null) {
			try {
				fireServiceAdded(arg0);
			} catch (Exception e) {
				Trace.catching(JMDNSPlugin.PLUGIN_ID,
						JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(),
						"serviceAdded", e);
			}
		}
	}

	public void serviceRemoved(ServiceEvent arg0) {
		if (jmdns != null) {
			try {
				fireServiceRemoved(arg0);
			} catch (Exception e) {
				Trace.catching(JMDNSPlugin.PLUGIN_ID,
						JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(),
						"serviceRemoved", e);
			}
		}
	}

	public void serviceResolved(ServiceEvent arg0) {
		if (jmdns != null) {
			try {
				fireServiceResolved(arg0);
			} catch (Exception e) {
				Trace.catching(JMDNSPlugin.PLUGIN_ID,
						JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(),
						"serviceResolved", e);
			}
		}
	}

	public void serviceTypeAdded(ServiceEvent arg0) {
		if (jmdns != null) {
			try {
				fireServiceTypeAdded(arg0);
			} catch (Exception e) {
				Trace.catching(JMDNSPlugin.PLUGIN_ID,
						JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(),
						"serviceResolved", e);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#unregisterService(org.eclipse.ecf.discovery.IServiceInfo)
	 */
	public void unregisterService(IServiceInfo serviceInfo) {
		if (jmdns != null) {
			jmdns
					.unregisterService(createServiceInfoFromIServiceInfo(serviceInfo));
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#getConnectNamespace()
	 */
	public Namespace getConnectNamespace() {
		return IDFactory.getDefault().getNamespaceByName(JMDNS_NAMESPACE_ID);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#addListener(org.eclipse.ecf.core.IContainerListener)
	 */
	public void addListener(IContainerListener l) {
		synchronized (listeners) {
			listeners.add(l);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ecf.core.IContainer#removeListener(org.eclipse.ecf.core.IContainerListener)
	 */
	public void removeListener(IContainerListener l) {
		synchronized (listeners) {
			listeners.remove(l);
		}
	}
	
}

Back to the top