com.jkoolcloud.tnt4j.streams.parsers.ActivityNameValueParser.java Source code

Java tutorial

Introduction

Here is the source code for com.jkoolcloud.tnt4j.streams.parsers.ActivityNameValueParser.java

Source

/*
 * Copyright 2014-2017 JKOOL, LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jkoolcloud.tnt4j.streams.parsers;

import java.text.ParseException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrMatcher;
import org.apache.commons.lang3.text.StrTokenizer;

import com.jkoolcloud.tnt4j.core.OpLevel;
import com.jkoolcloud.tnt4j.sink.DefaultEventSinkFactory;
import com.jkoolcloud.tnt4j.sink.EventSink;
import com.jkoolcloud.tnt4j.streams.configure.ParserProperties;
import com.jkoolcloud.tnt4j.streams.fields.ActivityFieldLocator;
import com.jkoolcloud.tnt4j.streams.fields.ActivityInfo;
import com.jkoolcloud.tnt4j.streams.inputs.TNTInputStream;
import com.jkoolcloud.tnt4j.streams.utils.StreamsResources;

/**
 * Implements an activity data parser that assumes each activity data item is a token-separated string of fields, where
 * each field is represented by a name/value pair and the name is used to map each field into its corresponding activity
 * field. The field-separator and the name/value separator can both be customized.
 * <p>
 * This parser supports the following properties (in addition to those supported by {@link GenericActivityParser}):
 * <ul>
 * <li>FieldDelim - fields separator. (Optional)</li>
 * <li>ValueDelim - value delimiter. (Optional)</li>
 * <li>Pattern - pattern used to determine which types of activity data string this parser supports. When {@code null},
 * all strings are assumed to match the format supported by this parser. (Optional)</li>
 * <li>StripQuotes - whether surrounding double quotes should be stripped from extracted data values. (Optional)</li>
 * </ul>
 *
 * @version $Revision: 1 $
 */
public class ActivityNameValueParser extends GenericActivityParser<Map<String, String>> {
    private static final EventSink LOGGER = DefaultEventSinkFactory.defaultEventSink(ActivityNameValueParser.class);

    /**
     * Contains the field separator (set by {@code FieldDelim} property) - Default:
     * "{@value com.jkoolcloud.tnt4j.streams.parsers.GenericActivityParser#DEFAULT_DELIM}"
     */
    protected StrMatcher fieldDelim = StrMatcher.charSetMatcher(DEFAULT_DELIM);

    /**
     * Contains the name/value separator (set by {@code ValueDelim} property) - Default: "="
     */
    protected String valueDelim = "="; // NON-NLS

    /**
     * Contains the pattern used to determine which types of activity data string this parser supports (set by
     * {@code Pattern} property). When {@code null}, all strings are assumed to match the format supported by this
     * parser.
     */
    protected Pattern pattern = null;

    /**
     * Indicates whether surrounding double quotes should be stripped from extracted data values (set by
     * {@code StripQuotes} property) - default: {@code true}
     */
    protected boolean stripQuotes = true;

    /**
     * Constructs a new ActivityNameValueParser.
     */
    public ActivityNameValueParser() {
        super();
    }

    @Override
    protected EventSink logger() {
        return LOGGER;
    }

    @Override
    public void setProperties(Collection<Map.Entry<String, String>> props) throws Exception {
        if (props == null) {
            return;
        }

        super.setProperties(props);

        for (Map.Entry<String, String> prop : props) {
            String name = prop.getKey();
            String value = prop.getValue();
            if (ParserProperties.PROP_FLD_DELIM.equals(name)) {
                fieldDelim = StringUtils.isEmpty(value) ? null : StrMatcher.charSetMatcher(value);
                logger().log(OpLevel.DEBUG,
                        StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME, "ActivityParser.setting"),
                        name, value);
            } else if (ParserProperties.PROP_VAL_DELIM.equals(name)) {
                valueDelim = value;
                logger().log(OpLevel.DEBUG,
                        StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME, "ActivityParser.setting"),
                        name, value);
            } else if (ParserProperties.PROP_PATTERN.equals(name)) {
                if (StringUtils.isNotEmpty(value)) {
                    pattern = Pattern.compile(value);
                    logger().log(OpLevel.DEBUG, StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                            "ActivityParser.setting"), name, value);
                }
            } else if (ParserProperties.PROP_STRIP_QUOTES.equals(name)) {
                stripQuotes = Boolean.parseBoolean(value);
                logger().log(OpLevel.DEBUG,
                        StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME, "ActivityParser.setting"),
                        name, value);
            }
        }
    }

    @Override
    public ActivityInfo parse(TNTInputStream<?, ?> stream, Object data)
            throws IllegalStateException, ParseException {
        if (fieldDelim == null) {
            throw new IllegalStateException(StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                    "ActivityNameValueParser.no.field.delimiter"));
        }
        if (valueDelim == null) {
            throw new IllegalStateException(StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                    "ActivityNameValueParser.no.value.delimiter"));
        }

        return super.parse(stream, data);
    }

    @Override
    protected ActivityContext prepareItem(TNTInputStream<?, ?> stream, Object data) throws ParseException {
        String dataStr = getNextActivityString(data);
        if (StringUtils.isEmpty(dataStr)) {
            return null;
        }
        logger().log(OpLevel.DEBUG, StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                "ActivityParser.splitting.string"), dataStr);
        if (pattern != null) {
            Matcher matcher = pattern.matcher(dataStr);
            if (matcher == null || !matcher.matches()) {
                logger().log(OpLevel.DEBUG, StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                        "ActivityParser.input.not.match"), getName(), pattern.pattern());
                return null;
            }
        }
        StrTokenizer tk = stripQuotes ? new StrTokenizer(dataStr, fieldDelim, StrMatcher.doubleQuoteMatcher())
                : new StrTokenizer(dataStr, fieldDelim);
        tk.setIgnoreEmptyTokens(false);
        String[] fields = tk.getTokenArray();
        if (ArrayUtils.isEmpty(fields)) {
            logger().log(OpLevel.DEBUG,
                    StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME, "ActivityParser.no.fields"));
            return null;
        }
        logger().log(OpLevel.DEBUG,
                StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME, "ActivityParser.split"),
                fields.length);
        Map<String, String> nameValues = new HashMap<>(fields.length);
        for (String field : fields) {
            if (field != null) {
                String[] nv = field.split(Pattern.quote(valueDelim));
                if (ArrayUtils.isNotEmpty(nv)) {
                    nameValues.put(nv[0], nv.length > 1 ? nv[1].trim() : "");
                }
                logger().log(OpLevel.TRACE, StreamsResources.getString(StreamsResources.RESOURCE_BUNDLE_NAME,
                        "ActivityNameValueParser.found"), field);
            }
        }

        ActivityContext cData = new ActivityContext(stream, data, nameValues);
        cData.setMessage(getRawDataAsMessage(nameValues));

        return cData;
    }

    /**
     * Gets field raw data value resolved by locator.
     *
     * @param locator
     *            activity field locator
     * @param cData
     *            activity object name/value pairs map
     * @param formattingNeeded
     *            flag to set if value formatting is not needed
     * @return raw value resolved by locator, or {@code null} if value is not resolved
     */
    @Override
    protected Object resolveLocatorValue(ActivityFieldLocator locator, ActivityContext cData,
            AtomicBoolean formattingNeeded) {
        Object val = null;
        String locStr = locator.getLocator();
        val = cData.getData().get(locStr); // NOTE: locStr == null?

        return val;
    }
}