/** * Calculate the ver attribute. * * @param info The discover info to calculate the ver. * @param hashMethod the hash algorithm to use. * @return the value of the ver attribute * @throws NoSuchAlgorithmException if the hash algorithm is not supported. */ private String calculateVer(DiscoverInfo info, String hashMethod) throws NoSuchAlgorithmException { StringBuilder s = new StringBuilder(); for (DiscoverInfo.Identity identity : getSortedIdentity(info)) { String c = identity.getCategory(); if (c != null) s.append(c); s.append('/'); c = identity.getType(); if (c != null) s.append(c); s.append('/'); // Should add lang but it is not available // c = identity.getType(); // if (c != null) // S.append(c); s.append('/'); c = identity.getName(); if (c != null) s.append(c); s.append('<'); } for (String f : getSortedFeature(info)) { s.append(f); s.append('<'); } // Should add data form (XEP 0128) but it is not available byte[] hash = getHash(hashMethod, s.toString().getBytes()); return StringUtils.encodeBase64(hash); }
/** * Calculates the <tt>String</tt> for a specific <tt>DiscoverInfo</tt> which is to be hashed in * order to compute the ver string for that <tt>DiscoverInfo</tt>. * * @param discoverInfo the <tt>DiscoverInfo</tt> for which the <tt>String</tt> to be hashed in * order to compute its ver string is to be calculated * @return the <tt>String</tt> for <tt>discoverInfo</tt> which is to be hashed in order to compute * its ver string */ private static String calculateEntityCapsString(DiscoverInfo discoverInfo) { StringBuilder bldr = new StringBuilder(); // Add identities { Iterator<DiscoverInfo.Identity> identities = discoverInfo.getIdentities(); SortedSet<DiscoverInfo.Identity> is = new TreeSet<DiscoverInfo.Identity>( new Comparator<DiscoverInfo.Identity>() { public int compare(DiscoverInfo.Identity i1, DiscoverInfo.Identity i2) { int category = i1.getCategory().compareTo(i2.getCategory()); if (category != 0) return category; int type = i1.getType().compareTo(i2.getType()); if (type != 0) return type; /* * TODO Sort by xml:lang. * * Since sort by xml:lang is currently missing, * use the last supported sort criterion i.e. * type. */ return type; } }); if (identities != null) while (identities.hasNext()) is.add(identities.next()); for (DiscoverInfo.Identity i : is) { bldr.append(i.getCategory()) .append('/') .append(i.getType()) .append("//") .append(i.getName()) .append('<'); } } // Add features { Iterator<DiscoverInfo.Feature> features = getDiscoverInfoFeatures(discoverInfo); SortedSet<String> fs = new TreeSet<String>(); if (features != null) while (features.hasNext()) fs.add(features.next().getVar()); for (String f : fs) bldr.append(f).append('<'); } DataForm extendedInfo = (DataForm) discoverInfo.getExtension("x", "jabber:x:data"); if (extendedInfo != null) { synchronized (extendedInfo) { SortedSet<FormField> fs = new TreeSet<FormField>( new Comparator<FormField>() { public int compare(FormField f1, FormField f2) { return f1.getVariable().compareTo(f2.getVariable()); } }); FormField formType = null; for (Iterator<FormField> fieldsIter = extendedInfo.getFields(); fieldsIter.hasNext(); ) { FormField f = fieldsIter.next(); if (!f.getVariable().equals("FORM_TYPE")) fs.add(f); else formType = f; } // Add FORM_TYPE values if (formType != null) formFieldValuesToCaps(formType.getValues(), bldr); // Add the other values for (FormField f : fs) { bldr.append(f.getVariable()).append('<'); formFieldValuesToCaps(f.getValues(), bldr); } } } return bldr.toString(); }