/**
 * StringUtils.java    2011-07-19
 *
 * Copyright 2011, Adam Lesperance
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */



package com.lespea.cef.utils;

//~--- non-JDK imports --------------------------------------------------------

import com.lespea.cef.InvalidField;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//~--- JDK imports ------------------------------------------------------------

import java.util.regex.Pattern;


//~--- classes ----------------------------------------------------------------

/**
 * Utility functions that manipulate strings to work correctly with the CEF format
 *
 * @version 1.0, 2011-07-19
 * @author Adam Lesperance
 */
public final class StringUtils {

    /**
     * Logger object
     */
    private static final Logger LOG = LoggerFactory.getLogger( StringUtils.class );

    /**
     * Pattern used to determine if a field has any invalid characters
     */
    private static final Pattern INVALID_FIELD_PATTERN = Pattern.compile( "[\r\n]" );

    /**
     * Pattern used to escape any of the characters that require escaping in the field part of a CEF
     * string
     */
    private static final Pattern ESCAPE_FIELD_PATTERN = Pattern.compile( "([|\\\\])" );


    //~--- constructors -------------------------------------------------------

    /**
     * Null constructor for utility class
     */
    private StringUtils() {}


    //~--- methods ------------------------------------------------------------

    // TODO: Investigate using String.getBytes(“UTF-8″) to coerce the string
    // into UTF-8 (not-super important atm)

    /**
     * Every field in a CEF string (minus the extension) must escape the bar <code>("|")</code>
     * character as well as the backslash <code>("\")</code>
     * <p>
     * Additionally, the field string may not contain a vertical newline character and, if one is
     * found, then an IllegalArgument exception is thrown!
     *
     * @param fieldStr
     *            the text of the field that requires escaping
     * @return the escaped version of the field string
     * @throws InvalidField
     *             if the string to be escaped is invalid according to the CEF spec
     */
    public static String escapeField( final String fieldStr ) throws InvalidField {
        if (fieldStr == null) {
            StringUtils.LOG.warn( "Tried to escape a null CEF field" );

            return null;
        }


        if (StringUtils.INVALID_FIELD_PATTERN.matcher( fieldStr ).find()) {
            StringUtils.LOG.error( "The field string contained an invalid character" );

            throw new InvalidField( "The field string " + fieldStr + " contained an invalid character" );
        }


        final String escapedStr = StringUtils.ESCAPE_FIELD_PATTERN.matcher( fieldStr ).replaceAll( "\\\\$1" );

        StringUtils.LOG.debug( "The CEF field \"{}\" was escaped to \"{}\"", fieldStr, escapedStr );

        return escapedStr;
    }


    //~--- get methods --------------------------------------------------------

    /**
     * Tests if the provided string is a valid field string.
     * <p>
     * A field is not valid if it contains a vertical newline character
     *
     * @param fieldStr
     *            the field string to test
     * @return if the field string contains a vertical newline character
     */
    public static Boolean isValidField( final String fieldStr ) {
        final Boolean isValid;

        if (fieldStr == null) {
            StringUtils.LOG.warn( "Tried to detect if a null string was a valid field string" );

            isValid = false;
        }
        else if (StringUtils.INVALID_FIELD_PATTERN.matcher( fieldStr ).find()) {
            isValid = false;
        }
        else {
            isValid = true;
        }


        StringUtils.LOG.debug( "The field string \"{}\" is {}valid", fieldStr, isValid
                ? ""
                : "not " );

        return isValid;
    }
}

@@ -1599,16 +1599,56 @@
 racters%0A
+     * %3Cp%3E%0A     * %3Ccode%3E/%5B%5Cr%5Cn%5D/%3C/code%3E%0A
      */%0A
@@ -1730,24 +1730,239 @@
 %5B%5Cr%5Cn%5D%22 );%0A%0A
+    /**%0A     * Pattern used to determine if a field has any invalid characters%0A     * %3Cp%3E%0A     * %3Ccode%3E/%5Cs/%3C/code%3E%0A     */%0A    private static final Pattern INVALID_EXTENSION_KEY_PATTERN = Pattern.compile( %22%5C%5Cs%22 );%0A%0A
     /**%0A    
@@ -3975,32 +3975,1027 @@
 --------------%0A%0A
+    /**%0A     * Tests if the provided string is a valid extension key string.%0A     * %3Cp%3E%0A     * A field is not valid if it contains a whitespace character%0A     *%0A     * @param extensionKeyStr%0A     *            the extension key string to test%0A     * @return if the extension key string contains a whitespace character%0A     */%0A    public static Boolean isValidExtensionKey( final String extensionKeyStr ) %7B%0A        final Boolean isValid;%0A%0A        if (extensionKeyStr == null) %7B%0A            StringUtils.LOG.warn( %22Tried to detect if a null string was a valid extension key string%22 );%0A%0A            isValid = false;%0A        %7D%0A        else if (StringUtils.INVALID_EXTENSION_KEY_PATTERN.matcher( extensionKeyStr ).find()) %7B%0A            isValid = false;%0A        %7D%0A        else %7B%0A            isValid = true;%0A        %7D%0A%0A%0A        StringUtils.LOG.debug( %22The extension key string %5C%22%7B%7D%5C%22 is %7B%7Dvalid%22, extensionKeyStr, isValid%0A                ? %22%22%0A                : %22not %22 );%0A%0A        return isValid;%0A    %7D%0A%0A%0A
     /**%0A     * T

Add function to test if a cef extension key is valid or not