com.addc.commons.slp.SLPAttributeHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of addc-slp Show documentation
Show all versions of addc-slp Show documentation
The addc-slp library supplies client classes for registering objects with a Service Location Protocol Daemon and
for looking theses objects up later.
package com.addc.commons.slp;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.addc.commons.Constants;
import com.addc.commons.string.ByteArrayFormatter;
/**
* The SLPAttributeHelper provides staic helper methods for handling
* {@link ServiceLocationAttribute}s
*/
public final class SLPAttributeHelper {
private static final Logger LOGGER= LoggerFactory.getLogger(SLPAttributeHelper.class);
private static final SLPAttributeHelper INSTANCE= new SLPAttributeHelper();
private static final String ESCAPE_CHARS= "(),\\!<=>-";
/**
* Get the singleton instance
*
* @return the singleton instance
*/
public static SLPAttributeHelper getInstance() {
return INSTANCE;
}
/**
* Returns a List of ServiceLocationAttributes from an attribute list
* string.
*
* @param list
* The list String.
* @return a List of ServiceLocationAttributes.
*/
public List readFromList(final String list) {
int pos= 0;
List attrs= new ArrayList<>();
String attrList= list;
while (attrList.length() > 0) {
if (attrList.charAt(0) == '(') {
pos= attrList.indexOf("),") + 1;
} else {
pos= attrList.indexOf(',');
}
if (pos <= 0) {
pos= attrList.length();
}
attrs.add(new ServiceLocationAttribute(attrList.substring(0, pos)));
if (pos < attrList.length()) {
attrList= attrList.substring(pos + 1);
} else {
attrList= "";
}
}
return attrs;
}
/**
* Check whether the string contains any of the bad-tags defined in RFC 2608
*
* @param str
* The string to verify
* @return true
if the string contains a bad-tag
*/
public boolean containsBadTag(String str) throws IllegalArgumentException {
return (str.indexOf('\n') >= 0 || str.indexOf('\r') >= 0 || str.indexOf('\t') >= 0 || str.indexOf('_') >= 0
|| str.indexOf('*') >= 0);
}
/**
* Escape a String.
*
* @param s
* The String.
* @return The escaped String.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public String escapeString(final String s) {
StringBuilder sb= new StringBuilder();
sb.append(s);
// If string can be interpreted as an integer or
// boolean, append a space to the end per RFC 2614
// Section 5.7.3
if (s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false")) {
sb.append(' ');
} else {
try {
Integer.parseInt(s);
sb.append(' ');
} catch (@SuppressWarnings("unused") NumberFormatException e) {
// So it's not a number, just carry on
}
}
return encode(sb.toString());
}
/**
* Create an Attribute from an escaped string.
*
* @param s
* The String
* @return an Attribute from an escaped string.
*/
@SuppressWarnings({ "PMD.EmptyCatchBlock", "unused" })
public AttributeValue> unEscape(final String s) {
if (s.startsWith("\\ff")) {
String[] parts= StringUtils.split(s.substring(4), '\\');
byte[] bArr= new byte[parts.length];
int i= 0;
for (String token : parts) {
byte b;
try {
b= (byte) Integer.parseInt(token, 16);
} catch (NumberFormatException e) {
b= -1;
}
bArr[i++]= b;
}
return new OpaqueAttributeValue(bArr);
}
if (s.equalsIgnoreCase("true ")) {
return new BooleanAttributeValue(Boolean.valueOf(s.trim()));
}
if (s.equalsIgnoreCase("false ")) {
return new BooleanAttributeValue(Boolean.valueOf(s.trim()));
}
if (StringUtils.isNumericSpace(s) && s.endsWith(" ")) {
try {
return new IntegerAttributeValue(Integer.valueOf(s.trim()));
} catch (NumberFormatException e) {
// well it's not a number carry on...
}
}
// If we get here, it must be just a string
return new StringAttributeValue(decode(s));
}
/**
* Get the string for a list of attributes
*
* @param attributes
* a list of attributes
* @return the string for a list of attributes
*/
public String getAttributesString(List attributes) {
StringBuilder sb= new StringBuilder();
for (Iterator iterator= attributes.iterator(); iterator.hasNext();) {
sb.append(iterator.next().getEscapedString());
if (iterator.hasNext()) {
sb.append(',');
}
}
return sb.toString();
}
/**
* Verify the list.
*
* @param securityEnabled
* If true extract the suth block(s)
* @param list
* The list to verify
* @param blocks
* The authentication blocks to use.
* @return true if valid.
*/
public boolean verifyList(boolean securityEnabled, String list, AuthenticationBlock[] blocks) {
if (securityEnabled) {
for (AuthenticationBlock block : blocks) {
try {
byte[] data= getAuthData(list, block.getSPI(), block.getTimestamp());
if (block.verify(data)) {
return true;
}
} catch (ServiceLocationException | IOException e) {
LOGGER.warn(e.getMessage());
}
}
return false;
}
return true;
}
/**
* Encode the string escaping any invalid characters
*
* @param str
* The string to encode
* @return The encoded string
*/
public String encode(String str) {
StringBuilder sb= new StringBuilder();
char[] string= str.toCharArray();
for (char ch : string) {
if (Character.isISOControl(ch) || ESCAPE_CHARS.indexOf(ch) != -1) {
sb.append('\\').append(ByteArrayFormatter.getByteHex((byte) ch));
} else {
sb.append(ch);
}
}
return sb.toString();
}
/**
* Decode the string replacing escape sequences with the original charaxters
*
* @param str
* The string to decode
* @return The decoded string
*/
public String decode(String str) {
StringBuilder sb= new StringBuilder();
StringBuilder buf;
char[] string= str.toCharArray();
for (int i= 0; i < string.length; i++) {
if (string[i] == '\\') {
buf= new StringBuilder();
buf.append(string[++i]);
buf.append(string[++i]);
char ch= (char) Integer.parseInt(buf.toString(), 16);
sb.append(ch);
} else {
sb.append(string[i]);
}
}
return sb.toString();
}
/**
* Check whether the string contains any of the bad-tags defined in RFC 2608
*
* @param str
* The string to verify
* @throws IllegalArgumentException
* If the string contains a bad-tag
*/
public void stringContainsBadTags(String str) throws IllegalArgumentException {
if (str.indexOf('\n') >= 0 || str.indexOf('\r') >= 0 || str.indexOf('\t') >= 0 || str.indexOf('_') >= 0
|| str.indexOf('*') >= 0) {
throw new IllegalArgumentException("The string contains a bad tag \\r, \\n, \\t, _ or *");
}
}
private byte[] getAuthData(String list, String spi, int timestamp) throws IOException {
ByteArrayOutputStream bos= new ByteArrayOutputStream();
DataOutputStream dos= new DataOutputStream(bos);
byte[] temp= spi.getBytes(Constants.UTF8);
dos.writeShort(temp.length);
dos.write(temp);
temp= list.getBytes(Constants.UTF8);
dos.writeShort(temp.length);
dos.write(temp);
dos.writeInt(timestamp);
return bos.toByteArray();
}
private SLPAttributeHelper() {
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy