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