/******************************************************************************* * 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; } }