use of org.jivesoftware.smackx.xdata.FormField in project Smack by igniterealtime.
the class DataValidationHelperTest method testCheckConsistencyFormFieldRangeValidateElement.
@Test
public void testCheckConsistencyFormFieldRangeValidateElement() {
FormField field = new FormField("var");
field.setType(FormField.Type.text_multi);
RangeValidateElement element = new RangeValidateElement("xs:integer", null, "99");
try {
element.checkConsistency(field);
fail("No correct check on consistency");
} catch (ValidationConsistencyException e) {
assertEquals("Field type 'text-multi' is not consistent with validation method 'range'.", e.getMessage());
}
}
use of org.jivesoftware.smackx.xdata.FormField in project Smack by igniterealtime.
the class DataValidationHelperTest method testCheckConsistencyFormFieldBasicValidateElement.
@Test
public void testCheckConsistencyFormFieldBasicValidateElement() {
FormField field = new FormField("var");
field.setType(FormField.Type.jid_single);
BasicValidateElement element = new BasicValidateElement(null);
try {
element.checkConsistency(field);
fail("No correct check on consistency");
} catch (ValidationConsistencyException e) {
assertEquals("Field type 'jid-single' is not consistent with validation method 'basic'.", e.getMessage());
}
try {
new ListRange(-1L, 1L);
fail("No correct check on consistency");
} catch (IllegalArgumentException e) {
assertEquals("unsigned 32-bit integers can't be negative", e.getMessage());
}
element.setListRange(new ListRange(10L, 100L));
try {
element.checkConsistency(field);
fail("No correct check on consistency");
} catch (ValidationConsistencyException e) {
assertEquals("Field type is not of type 'list-multi' while a 'list-range' is defined.", e.getMessage());
}
field.setType(FormField.Type.list_multi);
try {
element.checkConsistency(field);
} catch (ValidationConsistencyException e) {
fail("No correct check on consistency");
}
}
use of org.jivesoftware.smackx.xdata.FormField in project Smack by igniterealtime.
the class EntityCapsManager method generateVerificationString.
/**
* Generates a XEP-115 Verification String
*
* @see <a href="http://xmpp.org/extensions/xep-0115.html#ver">XEP-115
* Verification String</a>
*
* @param discoverInfo
* @param hash
* the used hash function, if null, default hash will be used
* @return The generated verification String or null if the hash is not
* supported
*/
protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo, String hash) {
if (hash == null) {
hash = DEFAULT_HASH;
}
// SUPPORTED_HASHES uses the format of MessageDigest, which is uppercase, e.g. "SHA-1" instead of "sha-1"
MessageDigest md = SUPPORTED_HASHES.get(hash.toUpperCase(Locale.US));
if (md == null)
return null;
// Then transform the hash to lowercase, as this value will be put on the wire within the caps element's hash
// attribute. I'm not sure if the standard is case insensitive here, but let's assume that even it is, there could
// be "broken" implementation in the wild, so we *always* transform to lowercase.
hash = hash.toLowerCase(Locale.US);
DataForm extendedInfo = DataForm.from(discoverInfo);
// 1. Initialize an empty string S ('sb' in this method).
// Use StringBuilder as we don't
StringBuilder sb = new StringBuilder();
// need thread-safe StringBuffer
// 2. Sort the service discovery identities by category and then by
// type and then by xml:lang
// (if it exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
// [NAME]. Note that each slash is included even if the LANG or
// NAME is not included (in accordance with XEP-0030, the category and
// type MUST be included.
SortedSet<DiscoverInfo.Identity> sortedIdentities = new TreeSet<DiscoverInfo.Identity>();
for (DiscoverInfo.Identity i : discoverInfo.getIdentities()) sortedIdentities.add(i);
// followed by the '<' character.
for (DiscoverInfo.Identity identity : sortedIdentities) {
sb.append(identity.getCategory());
sb.append('/');
sb.append(identity.getType());
sb.append('/');
sb.append(identity.getLanguage() == null ? "" : identity.getLanguage());
sb.append('/');
sb.append(identity.getName() == null ? "" : identity.getName());
sb.append('<');
}
// 4. Sort the supported service discovery features.
SortedSet<String> features = new TreeSet<String>();
for (Feature f : discoverInfo.getFeatures()) features.add(f.getVar());
// character
for (String f : features) {
sb.append(f);
sb.append('<');
}
// see XEP-0115 5.4 step 3.6
if (extendedInfo != null && extendedInfo.hasHiddenFormTypeField()) {
synchronized (extendedInfo) {
// 6. If the service discovery information response includes
// XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
// by the XML character data of the <value/> element).
SortedSet<FormField> fs = new TreeSet<FormField>(new Comparator<FormField>() {
@Override
public int compare(FormField f1, FormField f2) {
return f1.getVariable().compareTo(f2.getVariable());
}
});
FormField ft = null;
for (FormField f : extendedInfo.getFields()) {
if (!f.getVariable().equals("FORM_TYPE")) {
fs.add(f);
} else {
ft = f;
}
}
// Add FORM_TYPE values
if (ft != null) {
formFieldValuesToCaps(ft.getValues(), sb);
}
// followed by the '<' character.
for (FormField f : fs) {
sb.append(f.getVariable());
sb.append('<');
formFieldValuesToCaps(f.getValues(), sb);
}
}
}
// 8. Ensure that S is encoded according to the UTF-8 encoding (RFC
// 3269).
// 9. Compute the verification string by hashing S using the algorithm
// specified in the 'hash' attribute (e.g., SHA-1 as defined in RFC
// 3174).
// The hashed data MUST be generated with binary output and
// encoded using Base64 as specified in Section 4 of RFC 4648
// (note: the Base64 output MUST NOT include whitespace and MUST set
// padding bits to zero).
byte[] bytes;
try {
bytes = sb.toString().getBytes(StringUtils.UTF8);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
byte[] digest;
synchronized (md) {
digest = md.digest(bytes);
}
String version = Base64.encodeToString(digest);
return new CapsVersionAndHash(version, hash);
}
use of org.jivesoftware.smackx.xdata.FormField in project Smack by igniterealtime.
the class StreamNegotiator method createInitiationAccept.
/**
* Creates the initiation acceptance stanza(/packet) to forward to the stream
* initiator.
*
* @param streamInitiationOffer The offer from the stream initiator to connect for a stream.
* @param namespaces The namespace that relates to the accepted means of transfer.
* @return The response to be forwarded to the initiator.
*/
protected static StreamInitiation createInitiationAccept(StreamInitiation streamInitiationOffer, String[] namespaces) {
StreamInitiation response = new StreamInitiation();
response.setTo(streamInitiationOffer.getFrom());
response.setFrom(streamInitiationOffer.getTo());
response.setType(IQ.Type.result);
response.setStanzaId(streamInitiationOffer.getStanzaId());
DataForm form = new DataForm(DataForm.Type.submit);
FormField field = new FormField(FileTransferNegotiator.STREAM_DATA_FIELD_NAME);
for (String namespace : namespaces) {
field.addValue(namespace);
}
form.addField(field);
response.setFeatureNegotiationForm(form);
return response;
}
use of org.jivesoftware.smackx.xdata.FormField in project Smack by igniterealtime.
the class MultiUserChat method requestVoice.
/**
* Sends a voice request to the MUC. The room moderators usually need to approve this request.
*
* @throws NotConnectedException
* @throws InterruptedException
* @see <a href="http://xmpp.org/extensions/xep-0045.html#requestvoice">XEP-45 ยง 7.13 Requesting
* Voice</a>
* @since 4.1
*/
public void requestVoice() throws NotConnectedException, InterruptedException {
DataForm form = new DataForm(DataForm.Type.submit);
FormField formTypeField = new FormField(FormField.FORM_TYPE);
formTypeField.addValue(MUCInitialPresence.NAMESPACE + "#request");
form.addField(formTypeField);
FormField requestVoiceField = new FormField("muc#role");
requestVoiceField.setType(FormField.Type.text_single);
requestVoiceField.setLabel("Requested role");
requestVoiceField.addValue("participant");
form.addField(requestVoiceField);
Message message = new Message(room);
message.addExtension(form);
connection.sendStanza(message);
}
Aggregations