blob: c716ba486f690399aef7759c256c6f5beb25bbed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Versant Corp.
* 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 Kuppe (mkuppe <at> versant <dot> com) - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.provider.jslp;
import java.io.UnsupportedEncodingException;
import java.util.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.core.util.Base64;
import org.eclipse.ecf.core.util.StringUtils;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.discovery.*;
import org.eclipse.ecf.discovery.identity.IServiceID;
/**
* Adapts SLP's service properties to ECF's ServiceProperties and vice versa
* @see "http://www.ietf.org/rfc/rfc2608.txt page. 10ff"
*/
public class ServicePropertiesAdapter {
private static final String ENCODING = "ascii"; //$NON-NLS-1$
// http://www.iana.org/assignments/enterprise-numbers
private static final String ECLIPSE_ENTERPRISE_NUMBER = "28392"; //$NON-NLS-1$
/**
* SLP attribute key for org.eclipse.ecf.discovery.identity.IServiceID.getServiceName()
*/
private static final String SERVICE_ID_NAME = "x-" + ECLIPSE_ENTERPRISE_NUMBER + "-SERVICEIDNAME"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* SLP attribute key for org.eclipse.ecf.discovery.IServiceInfo.getPriority()
*/
private static final String PRIORITY = "x-" + ECLIPSE_ENTERPRISE_NUMBER + "-PRIORITY"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* SLP attribute key for org.eclipse.ecf.discovery.IServiceInfo.getWeight()
*/
private static final String WEIGHT = "x-" + ECLIPSE_ENTERPRISE_NUMBER + "-WEIGHT"; //$NON-NLS-1$ //$NON-NLS-2$
private static final String SLP_BYTE_PREFIX = "\\FF"; //$NON-NLS-1$
private final IServiceProperties serviceProperties;
private String serviceName;
private int priority = ServiceInfo.DEFAULT_PRIORITY;
private int weight = ServiceInfo.DEFAULT_WEIGHT;
public ServicePropertiesAdapter(final List aList) {
Assert.isNotNull(aList);
serviceProperties = new ServiceProperties();
for (final Iterator itr = aList.iterator(); itr.hasNext();) {
final String[] str = StringUtils.split((String) itr.next(), "="); //$NON-NLS-1$
if (str.length != 2) {
Trace.trace(Activator.PLUGIN_ID, "/debug/methods/tracing", this.getClass(), "ServicePropertiesAdapter(List)", "Skipped broken service attribute " + str); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
continue;
}
// remove the brackets "( )" from the string value which are added by jSLP for the LDAP style string representation
final String key = str[0].substring(1);
final String value = str[1].substring(0, str[1].length() - 1);
// keep this for wire backward compatibility
if (key.equalsIgnoreCase(SERVICE_ID_NAME) && !value.startsWith(SLP_BYTE_PREFIX)) {
serviceName = value;
} else if (key.equalsIgnoreCase(PRIORITY)) {
priority = Integer.parseInt(value);
} else if (key.equalsIgnoreCase(WEIGHT)) {
weight = Integer.parseInt(value);
} else if (value.startsWith(SLP_BYTE_PREFIX)) {
final String[] strs = StringUtils.split(value.substring(4), "\\"); //$NON-NLS-1$
final byte[] b = new byte[strs.length];
for (int i = 0; i < strs.length; i++) {
final byte parseInt = (byte) Integer.parseInt(strs[i], 16);
b[i] = parseInt;
}
if (key.equalsIgnoreCase(SERVICE_ID_NAME)) {
try {
serviceName = new String(Base64.decodeFromCharArray(b), ENCODING);
} catch (UnsupportedEncodingException e) {
// may never happen
e.printStackTrace();
}
} else {
serviceProperties.setPropertyBytes(key, Base64.decodeFromCharArray(b));
}
} else if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { //$NON-NLS-1$ //$NON-NLS-2$
serviceProperties.setProperty(key, Boolean.valueOf(value));
} else if (isInteger(value)) {
serviceProperties.setProperty(key, Integer.valueOf(value));
} else {
serviceProperties.setProperty(key, value);
}
}
}
public ServicePropertiesAdapter(final IServiceInfo sInfo) {
Assert.isNotNull(sInfo);
final IServiceID sID = sInfo.getServiceID();
Assert.isNotNull(sID);
final IServiceProperties sp = sInfo.getServiceProperties();
Assert.isNotNull(sp);
serviceProperties = new ServiceProperties(sp);
final int sPrio = sInfo.getPriority();
if (sPrio >= 0) {
priority = sPrio;
serviceProperties.setPropertyString(PRIORITY, Integer.toString(sPrio));
}
final int sWeight = sInfo.getWeight();
if (sWeight >= 0) {
weight = sWeight;
serviceProperties.setPropertyString(WEIGHT, Integer.toString(sWeight));
}
final String sName = sID.getServiceName();
if (sName != null) {
serviceName = sName;
//service name might contain reserved characters thus transfer as byte[] on wire
try {
serviceProperties.setPropertyBytes(SERVICE_ID_NAME, sName.getBytes(ENCODING));
} catch (UnsupportedEncodingException e) {
// may never happen
e.printStackTrace();
}
}
}
private boolean isInteger(final String value) {
try {
Integer.parseInt(value);
return true;
} catch (final NumberFormatException e) {
return false;
}
}
public IServiceProperties toServiceProperties() {
return serviceProperties;
}
public Dictionary toProperties() {
final Dictionary dict = new Properties();
final Enumeration propertyNames = serviceProperties.getPropertyNames();
while (propertyNames.hasMoreElements()) {
final String key = (String) propertyNames.nextElement();
final byte[] propertyBytes = serviceProperties.getPropertyBytes(key);
if (propertyBytes != null) {
final byte[] encode = Base64.encodeToCharArray(propertyBytes);
final StringBuffer buf = new StringBuffer();
buf.append(SLP_BYTE_PREFIX);
for (int i = 0; i < encode.length; i++) {
buf.append('\\');
buf.append(Integer.toHexString(encode[i]));
}
dict.put(key, buf.toString());
} else {
dict.put(key, serviceProperties.getProperty(key).toString());
}
}
return dict;
}
/**
* @return weight or -1 for unset
*/
public int getWeight() {
return weight;
}
/**
* @return priority or -1 for unset
*/
public int getPriority() {
return priority;
}
/**
* @return Service name or null
*/
public String getServiceName() {
return serviceName;
}
}