blob: 8d5d9311f420cc872985e31ef37491b6a20571fd [file] [log] [blame]
/****************************************************************************
* Copyright (c) 2005, 2010 Jan S. Rellermeyer, Systems Group,
* Department of Computer Science, ETH Zurich 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:
* Jan S. Rellermeyer - initial API and implementation
* Markus Alexander Kuppe - enhancements and bug fixes
* Md.Jamal MohiUddin (Ubiquitous Computing, C-DAC Hyderabad) - IPv6 support
* P Sowjanya (Ubiquitous Computing, C-DAC Hyderabad) - IPv6 support
*
*****************************************************************************/
package ch.ethz.iks.slp.impl;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ch.ethz.iks.slp.ServiceType;
import ch.ethz.iks.slp.ServiceURL;
/**
* Utility class.
*
* @author Jan S. Rellermeyer, ETH Z�rich
* @since 0.1
*/
final class SLPUtils {
/**
* hidden constructor.
*/
private SLPUtils() {
}
/**
* get a <code>List</code> of attribute/value pairs in String
* representation from a <code>Dictionary</code>.
*
* @param attributes
* the <code>Dictionary</code>
* @return the <code>List</code>.
*/
static List dictToAttrList(final Dictionary attributes) {
List attList = new ArrayList();
if (attributes != null) {
for (Enumeration keys = attributes.keys(); keys.hasMoreElements();) {
Object key = keys.nextElement();
StringBuffer buffer = new StringBuffer();
buffer.append("(");
buffer.append(key);
buffer.append("=");
buffer.append(attributes.get(key));
buffer.append(")");
attList.add(buffer.toString());
}
}
return attList;
}
/**
* get a <code>Dictionary</code> of attributes and their values from an
* attribute <code>List</code>.
*
* @since 0.6
* @param attrList
* the attribute list.
* @return the <code>Dictionary</code>.
*/
static Dictionary attrListToDict(final List attrList) {
Dictionary dict = new Hashtable();
for (Iterator iter = attrList.iterator(); iter.hasNext();) {
String attrStr = (String) iter.next();
attrStr = attrStr.substring(1, attrStr.length() - 1);
int pos = attrStr.indexOf("=");
if (pos > -1) {
String key = attrStr.substring(0, pos).trim();
String value = attrStr.substring(pos + 1).trim();
dict.put(key, value);
}
}
return dict;
}
/**
* add a value to a value list in a Map.
*
* @param map
* the map.
* @param key
* the key.
* @param value
* the value to be added to the list.
*/
static void addValue(final Map map, final Object key, final Object value) {
List values;
if ((values = (List) map.get(key)) == null) {
values = new ArrayList();
}
if (values.contains(value)) {
return;
}
values.add(value);
map.put(key, values);
}
/**
* remove a value from a value list in a Map.
*
* @param map
* the map.
* @param key
* the key.
* @param value
* the value to be removed from the list.
*/
static void removeValue(final Map map, final Object key, final Object value) {
List values;
if ((values = (List) map.get(key)) == null) {
return;
}
values.remove(value);
if (!values.isEmpty()) {
map.put(key, values);
} else {
map.remove(key);
}
}
/**
* remove a value from all keys where it occurs.
*
* @param map
* the map.
* @param value
* the value.
*/
static void removeValueFromAll(final Map map, final Object value) {
final Object[] keys = map.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
List list = (List) map.get(keys[i]);
list.remove(value);
if (list.isEmpty()) {
map.remove(keys[i]);
}
}
}
/**
* get the current timestamp as defined in RFC 2608.
*
* @return the current timestamp.
*/
static int getTimestamp() {
long systemTime = System.currentTimeMillis();
systemTime /= 1000;
return (int) systemTime;
}
/**
* find case insensitive matching between a key List and a Dictionary of
* attributes.
*
* @param keyList
* the key List.
* @param attributes
* the attribute Dictionary.
* @return a List of matches.
*/
static List findMatches(final List keyList, final Dictionary attributes) {
List results = new ArrayList();
Set caseInsensitiveKeyList = new HashSet();
List wildcards = new ArrayList();
if (!keyList.isEmpty()) {
for (Iterator keys = keyList.iterator(); keys.hasNext();) {
String key = (String) keys.next();
if (key.indexOf("*") == -1) {
caseInsensitiveKeyList.add(key.toLowerCase());
} else {
wildcards.add(key);
}
}
}
for (Enumeration keys = attributes.keys(); keys.hasMoreElements();) {
String key = (String) keys.nextElement();
if (keyList.isEmpty()
|| caseInsensitiveKeyList.contains(key.toLowerCase())) {
results.add("(" + key + "=" + attributes.get(key).toString()
+ ")");
continue;
}
for (Iterator iter = wildcards.iterator(); iter.hasNext();) {
String wildcard = (String) iter.next();
if (equalsWithWildcard(wildcard.toCharArray(), 0, key
.toCharArray(), 0)) {
results.add("(" + key + "="
+ attributes.get(key).toString() + ")");
continue;
}
}
}
return results;
}
/**
* equality check with wildcards
*
* @param val
* the value
* @param valIndex
* the current position within the value
* @param attr
* the attribute
* @param attrIndex
* the current position within the attribute.
* @return true if equals.
*/
private static boolean equalsWithWildcard(char[] val, int valIndex,
char[] attr, int attrIndex) {
if (val.length == valIndex) {
return attr.length == attrIndex;
}
if (val[valIndex] == '*') {
valIndex++;
do {
if (equalsWithWildcard(val, valIndex, attr, attrIndex)) {
return true;
}
attrIndex++;
} while (attr.length - attrIndex > -1);
return false;
} else {
return (attr.length == attrIndex || attr[attrIndex] != val[valIndex]) ? false
: equalsWithWildcard(val, ++valIndex, attr, ++attrIndex);
}
}
static String hash(ServiceURL aURL) {
String service = extractService(aURL.toString());
return hash(service);
}
static String hash(ServiceType aType) {
String service = extractService(aType.toString());
return hash(service);
}
/* Hash Algorithm for SLP Service Type String(RFC 3111) */
private static String hash(String pc) {
String ip = "FF02::1:1";
/*
* An unsigned 32-bit value v is initialized to 0.Each byte of the
* character is considered consecutively
*/
int h = 0;
for (int i = 0; i < pc.length(); i++) {
/*
* The current value v is multiplied by 33.then the value of the
* current string byte is added ,Each byte in the service type
* string is processed in this manner
*/
h *= 33;
h += pc.charAt(i);
}
/* The result is contained in the low order 10 bits of v */
int j = (0x3ff & h);
// Concatenating the value with the IP
return ip + Integer.toHexString(j);
}
private static String extractService(String url) {
int position = url.indexOf(':', 0);
if (position == -1) {
return url;
}
position = url.indexOf(':', position + 1);
if (position == -1) {
return url;
}
return url.substring(0, position);
}
}