src/main/java/com/fluenda/parcefone/parser/CEFParser.java
public CommonEvent parse(String cefString, final boolean validate, Locale locale)  {

        int cefHeaderSize = 7;
        CommonEvent cefEvent = new CefRev23(locale);

        // Note how split number of splits is cefHeaderSize + 1. This is because the final split
        // should be the body of the CEF message
        // Compiled pattern is equivalent to "(?<!\\\\)" + Pattern.quote("|")
        final String[] extractedMessage = cefString.split("(?<!\\\\)" + Pattern.quote("|"), cefHeaderSize + 1);

        // CEF header misses values
        if (extractedMessage.length < cefHeaderSize) {
            if (logger.isDebugEnabled()) {
                logger.debug("CEF message failed validation");
            }
            return null;
        }

        final HashMap<String, Object> headers = new HashMap<String, Object>();
        headers.put("version", Integer.valueOf(extractedMessage[0].substring(extractedMessage[0].length() - 1)));
        headers.put("deviceVendor", extractedMessage[1]);
        headers.put("deviceProduct", extractedMessage[2]);
        headers.put("deviceVersion", extractedMessage[3]);
        headers.put("deviceEventClassId", extractedMessage[4]);
        headers.put("name", extractedMessage[5]);
        headers.put("severity", extractedMessage[6]);

        final HashMap<String, String> extensions = new HashMap<String, String>();


        final String ext = extractedMessage[7];

        // Compiled pattern is equivalent to String extensionRegex = "(?<!\\\\)" + Pattern.quote("=");
        final Matcher matcher = extensionPattern.matcher(ext);
        final Matcher valueMatcher = extensionPattern.matcher(ext);

        int index = 0;

        while (matcher.find()) {
            String key = ext.substring(index, matcher.end() - 1).replace(" ", "");

            // Capture the start of the value (first char after delimiter match);
            int valueStart = matcher.end();

            // Handle all but last extension
            if (valueMatcher.find(valueStart)) {
                // FInd the next match to determine the maximum length of the value
                int nextMatch = valueMatcher.start();
                // Find the last space prior to next match (i.e. last char before next key)
                int lastSpace = ext.lastIndexOf(" ", nextMatch);

                // Copy the value between the value start (i.e. this match)
                // and the lastSpace (i.e. last char prior to next key)
                String value = ext.substring(valueStart, lastSpace);

                // Put to map.
                extensions.put(key, value);

                // Update index to the last character before the next key
                index = lastSpace + 1;

                // Treat the last KV (if match is true)
            } else if (valueMatcher.find(valueStart - 1)) {
                // We are handling the final character, value end if newline at the
                // end of string
                int valueEnd = ext.length();

                String value = ext.substring(valueStart, valueEnd);
                extensions.put(key, value);
                // Update the index to the end of the string so no matches are possible
                index = valueEnd;
            }
        }

        try {
            cefEvent.setHeader(headers);
            cefEvent.setExtension(extensions);

        } catch (CEFHandlingException e) {
            logger.error(e.toString());
            return null;
        }

        if (validate) {
            if (validator == null) {
                // Since the validator wasn't initiated previously, create a new one;
                this.validator = Validation.buildDefaultValidatorFactory().getValidator();;
            }

            Set<ConstraintViolation<CommonEvent>> validationResult = validator.validate(cefEvent);

            if (validationResult.size() > 0) {
            if (logger.isDebugEnabled()) {
                logger.debug("CEF message failed validation");
            }
                return null;
            } else {
                return cefEvent;
            }
        } else {
            return cefEvent;
        }
    }
public CommonEvent parse(String cefString, final boolean validate, Locale locale)  {

        int cefHeaderSize = 7;
        CommonEvent cefEvent = new CefRev23(locale);

        // Note how split number of splits is cefHeaderSize + 1. This is because the final split
        // should be the body of the CEF message
        // Compiled pattern is equivalent to "(?<!\\\\)" + Pattern.quote("|")
        final String[] extractedMessage = cefString.split("(?<!\\\\)" + Pattern.quote("|"), cefHeaderSize + 1);

        // CEF header misses values
        if (extractedMessage.length < cefHeaderSize) {
            if (logger.isDebugEnabled()) {
                logger.debug("CEF message failed validation");
            }
            return null;
        }

        final HashMap<String, Object> headers = new HashMap<String, Object>();
        headers.put("version", Integer.valueOf(extractedMessage[0].substring(extractedMessage[0].length() - 1)));
        headers.put("deviceVendor", extractedMessage[1]);
        headers.put("deviceProduct", extractedMessage[2]);
        headers.put("deviceVersion", extractedMessage[3]);
        headers.put("deviceEventClassId", extractedMessage[4]);
        headers.put("name", extractedMessage[5]);
        headers.put("severity", extractedMessage[6]);

        final HashMap<String, String> extensions = new HashMap<String, String>();


        final String ext = extractedMessage[7];

        // Compiled pattern is equivalent to String extensionRegex = "(?<!\\\\)" + Pattern.quote("=");
        final Matcher matcher = extensionPattern.matcher(ext);
        final Matcher valueMatcher = extensionPattern.matcher(ext);

        int index = 0;

        while (matcher.find()) {
            String key = ext.substring(index, matcher.end() - 1).replace(" ", "");

            // Capture the start of the value (first char after delimiter match);
            int valueStart = matcher.end();

            // Handle all but last extension
            if (valueMatcher.find(valueStart)) {
                // FInd the next match to determine the maximum length of the value
                int nextMatch = valueMatcher.start();
                // Find the last space prior to next match (i.e. last char before next key)
                int lastSpace = ext.lastIndexOf(" ", nextMatch);

                // Copy the value between the value start (i.e. this match)
                // and the lastSpace (i.e. last char prior to next key)
                String value = ext.substring(valueStart, lastSpace);

                // Put to map.
                extensions.put(key, value);

                // Update index to the last character before the next key
                index = lastSpace + 1;

                // Treat the last KV (if match is true)
            } else if (valueMatcher.find(valueStart - 1)) {
                // We are handling the final character, value end if newline at the
                // end of string
                int valueEnd = ext.length();

                String value = ext.substring(valueStart, valueEnd);
                extensions.put(key, value);
                // Update the index to the end of the string so no matches are possible
                index = valueEnd;
            }
        }

        try {
            cefEvent.setHeader(headers);
            cefEvent.setExtension(extensions);

        } catch (CEFHandlingException e) {
            logger.error(e.toString());
            return null;
        }

        if (validate) {
            if (validator == null) {
                // Since the validator wasn't initiated previously, create a new one;
                this.validator = Validation.buildDefaultValidatorFactory().getValidator();;
            }

            Set<ConstraintViolation<CommonEvent>> validationResult = validator.validate(cefEvent);

            if (validationResult.size() > 0) {
            if (logger.isDebugEnabled()) {
                logger.debug("CEF message failed validation");
            }
                return null;
            } else {
                return cefEvent;
            }
        } else {
            return cefEvent;
        }
    }
Converts a CEF formatted String into a {@link CommonEvent} object with exposed control over validation and the
{@link Locale} used to parse fields containing {@link Date Dates}
@param cefString String containing the CEF message to be parsed
@param validate Boolean if parser should validate values beyond type compatibility (e.g. Values within acceptable lengths, value lists, etc)
@param locale The locale to be used when parsing dates (so that parser can handle both jul (en_US) and juil.(fr_FR)
@return CommonEvent