package org.jmxtrans.agent;

import org.jmxtrans.agent.util.StringUtils2;
import org.jmxtrans.agent.util.logging.Logger;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.management.ObjectName;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Builds names with general rules like JConsole / VisualVM do.
 * i.e. {@code <domain-name>.<property-name><property-name><attribute-name><composite-data-key-name>}
 *
 * E.g. For objectName = "type:name=metric,value=bar" and attribute "count",
 * it will general resultName = "type.metric.bar.count"
 *
 * @author <a href="mailto:maheshkelkar@gmail.com">Mahesh V Kelkar</a>
 * @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a>
 */
public class JConsoleResultNameStrategyImpl implements ResultNameStrategy {
    protected final Logger logger = Logger.getLogger(getClass().getName());
    private ExpressionLanguageEngine expressionLanguageEngine = new ExpressionLanguageEngineImpl();

    @Nonnull
    @Override
    public String getResultName(@Nonnull Query query, @Nonnull ObjectName objectName, @Nullable String attribute, @Nullable String compositeDataKey, @Nullable Integer position) {
        String result;
        if (query.getResultAlias() == null) {
            result = escapeObjectName(objectName);
            if (!StringUtils2.isNullOrEmpty(attribute)) {
                result += "." + attribute;
            }
            if (!StringUtils2.isNullOrEmpty(compositeDataKey)) {
                result += "." + compositeDataKey;
            }
            if (position != null) {
                result += "_" + position;
            }
        } else {
            result = expressionLanguageEngine.resolveExpression(query.getResultAlias(), objectName, attribute, compositeDataKey, position);
        }
        return result;
    }

    /**
     * Transforms an {@linkplain javax.management.ObjectName} into a plain {@linkplain String}
     * only composed of ('a' to 'Z', 'A' to 'Z', '.', '_') similar to JConsole naming
     * <p/>
     * '_' is the escape char for not compliant chars.
     */
    protected String escapeObjectName(@Nonnull ObjectName objectName) {

        /** Add objectName's domain */
        StringBuilder result = new StringBuilder();
        StringUtils2.appendEscapedNonAlphaNumericChars(objectName.getDomain(), false, result);

        /** Walk through (sorted) properties of the ObjectName and add values to the result */
        List<String> keys = Collections.list(objectName.getKeyPropertyList().keys());
        Collections.sort(keys);
        for (Iterator<String> it = keys.iterator(); it.hasNext(); ) {
            String propertyKey = it.next();
            result.append('.');
            StringUtils2.appendEscapedNonAlphaNumericChars(objectName.getKeyProperty(propertyKey), false, result);
        }

        return result.toString();
    }

    public ExpressionLanguageEngine getExpressionLanguageEngine() {
        return expressionLanguageEngine;
    }

    public void setExpressionLanguageEngine(ExpressionLanguageEngine expressionLanguageEngine) {
        this.expressionLanguageEngine = expressionLanguageEngine;
    }

    public void postConstruct(@Nonnull Map<String, String> settings) {

    }
}

@@ -2081,20 +2081,16 @@
 ming
+.
 %0A     *
- %3Cp/%3E
 %0A   

Make javadoc v8 happy