All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.addc.commons.slp.SLPAttributeHelper Maven / Gradle / Ivy

Go to download

The addc-slp library supplies client classes for registering objects with a Service Location Protocol Daemon and for looking theses objects up later.

There is a newer version: 2.6
Show newest version
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