blob: 0b14c51a8684a1de122d09f7600c23abb49c38d1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010-2011 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.osgi.services.remoteserviceadmin;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.ecf.core.identity.IDFactory;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.discovery.IDiscoveryAdvertiser;
import org.eclipse.ecf.discovery.IServiceInfo;
import org.eclipse.ecf.discovery.IServiceProperties;
import org.eclipse.ecf.discovery.ServiceInfo;
import org.eclipse.ecf.discovery.ServiceProperties;
import org.eclipse.ecf.discovery.identity.IServiceTypeID;
import org.eclipse.ecf.discovery.identity.ServiceIDFactory;
import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.PropertiesUtil;
/**
* Default implementation of {@link IServiceInfoFactory}.
*
*/
public class ServiceInfoFactory extends AbstractMetadataFactory implements
IServiceInfoFactory {
protected Map<ServiceInfoKey, IServiceInfo> serviceInfos = new HashMap();
protected class ServiceInfoKey {
private EndpointDescription endpointDescription;
private Namespace discoveryNamespace;
private int hashCode = 7;
public ServiceInfoKey(EndpointDescription endpointDescription,
Namespace discoveryNamespace) {
this.endpointDescription = endpointDescription;
this.discoveryNamespace = discoveryNamespace;
this.hashCode = 31 * this.hashCode + endpointDescription.hashCode();
this.hashCode = 31 * this.hashCode + discoveryNamespace.hashCode();
}
public boolean equals(Object other) {
if (other == null)
return false;
if (!(other instanceof ServiceInfoKey))
return false;
ServiceInfoKey otherKey = (ServiceInfoKey) other;
return (this.endpointDescription
.equals(otherKey.endpointDescription) && this.discoveryNamespace
.equals(otherKey.discoveryNamespace));
}
public int hashCode() {
return hashCode;
}
}
public IServiceInfo createServiceInfo(IDiscoveryAdvertiser advertiser,
EndpointDescription endpointDescription) {
try {
Namespace advertiserNamespace = advertiser.getServicesNamespace();
ServiceInfoKey key = new ServiceInfoKey(endpointDescription,
advertiserNamespace);
IServiceInfo existingServiceInfo = null;
synchronized (serviceInfos) {
existingServiceInfo = serviceInfos.get(key);
// If it's already there, then we return null
if (existingServiceInfo != null)
return null;
IServiceTypeID serviceTypeID = createServiceTypeID(
endpointDescription, advertiser);
String serviceName = createServiceName(endpointDescription,
advertiser, serviceTypeID);
URI uri = createURI(endpointDescription, advertiser,
serviceTypeID, serviceName);
IServiceProperties serviceProperties = createServiceProperties(
endpointDescription, advertiser, serviceTypeID,
serviceName, uri);
IServiceInfo newServiceInfo = createServiceInfo(uri,
serviceName, serviceTypeID, serviceProperties);
// put into map using key
serviceInfos.put(key, newServiceInfo);
return newServiceInfo;
}
} catch (Exception e) {
logError(
"createServiceInfoForDiscovery", //$NON-NLS-1$
"Exception creating service info for endpointDescription=" //$NON-NLS-1$
+ endpointDescription + ",advertiser=" + advertiser, //$NON-NLS-1$
e);
return null;
}
}
protected IServiceInfo createServiceInfo(URI uri, String serviceName,
IServiceTypeID serviceTypeID, IServiceProperties serviceProperties) {
return new ServiceInfo(uri, serviceName, serviceTypeID,
serviceProperties);
}
protected IServiceProperties createServiceProperties(
EndpointDescription endpointDescription,
IDiscoveryAdvertiser advertiser, IServiceTypeID serviceTypeID,
String serviceName, URI uri) {
ServiceProperties result = new ServiceProperties();
encodeServiceProperties(endpointDescription, result);
return result;
}
protected URI createURI(EndpointDescription endpointDescription,
IDiscoveryAdvertiser advertiser, IServiceTypeID serviceTypeID,
String serviceName) throws URISyntaxException {
String path = "/" + serviceName; //$NON-NLS-1$
String str = endpointDescription.getId();
URI uri = null;
while (true) {
try {
uri = new URI(str);
if (uri.getHost() != null) {
break;
} else {
final String rawSchemeSpecificPart = uri
.getRawSchemeSpecificPart();
// make sure we break eventually
if (str.equals(rawSchemeSpecificPart)) {
uri = null;
break;
} else {
str = rawSchemeSpecificPart;
}
}
} catch (URISyntaxException e) {
uri = null;
break;
}
}
String scheme = RemoteConstants.DISCOVERY_SERVICE_TYPE;
int port = 32565;
if (uri != null) {
port = uri.getPort();
if (port == -1)
port = 32565;
}
String host = null;
if (uri != null) {
host = uri.getHost();
} else {
try {
host = InetAddress.getLocalHost().getHostAddress();
} catch (Exception e) {
logWarning(
"createURI", //$NON-NLS-1$
"failed to get local host adress, falling back to \'localhost\'.", e); //$NON-NLS-1$
host = "localhost"; //$NON-NLS-1$
}
}
return new URI(scheme, null, host, port, path, null, null);
}
protected String createServiceName(EndpointDescription endpointDescription,
IDiscoveryAdvertiser advertiser, IServiceTypeID serviceTypeID) {
// First create unique default name
String defaultServiceName = createDefaultServiceName(
endpointDescription, advertiser, serviceTypeID);
// Look for service name that was explicitly set
String serviceName = PropertiesUtil.getStringWithDefault(
endpointDescription.getProperties(),
RemoteConstants.DISCOVERY_SERVICE_NAME, defaultServiceName);
return serviceName;
}
protected String createDefaultServiceName(
EndpointDescription endpointDescription,
IDiscoveryAdvertiser advertiser, IServiceTypeID serviceTypeID) {
return RemoteConstants.DISCOVERY_DEFAULT_SERVICE_NAME_PREFIX
+ IDFactory.getDefault().createGUID().getName();
}
protected IServiceTypeID createServiceTypeID(
EndpointDescription endpointDescription,
IDiscoveryAdvertiser advertiser) {
Map props = endpointDescription.getProperties();
String[] scopes = PropertiesUtil.getStringArrayWithDefault(props,
RemoteConstants.DISCOVERY_SCOPE, IServiceTypeID.DEFAULT_SCOPE);
String[] protocols = PropertiesUtil.getStringArrayWithDefault(props,
RemoteConstants.DISCOVERY_PROTOCOLS,
IServiceTypeID.DEFAULT_SCOPE);
String namingAuthority = PropertiesUtil.getStringWithDefault(props,
RemoteConstants.DISCOVERY_NAMING_AUTHORITY,
IServiceTypeID.DEFAULT_NA);
return ServiceIDFactory.getDefault().createServiceTypeID(
advertiser.getServicesNamespace(),
new String[] { RemoteConstants.DISCOVERY_SERVICE_TYPE },
scopes, protocols, namingAuthority);
}
public IServiceInfo removeServiceInfo(IDiscoveryAdvertiser advertiser,
EndpointDescription endpointDescription) {
Namespace advertiserNamespace = advertiser.getServicesNamespace();
ServiceInfoKey key = new ServiceInfoKey(endpointDescription,
advertiserNamespace);
synchronized (serviceInfos) {
return serviceInfos.remove(key);
}
}
public void close() {
removeAllServiceInfos();
super.close();
}
private void removeAllServiceInfos() {
synchronized (serviceInfos) {
serviceInfos.clear();
}
}
}