com.mtgi.jmx.export.naming.AppendNamingStrategy.java Source code

Java tutorial

Introduction

Here is the source code for com.mtgi.jmx.export.naming.AppendNamingStrategy.java

Source

/* 
 * Copyright 2008-2009 the original author or authors.
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 */

package com.mtgi.jmx.export.naming;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.jmx.export.naming.ObjectNamingStrategy;

/**
 * <p>A delegating naming strategy, which can be used to change the domain name
 * and/or append an additional property to the name generated by the delegate.  
 * The original domain name is converted into the 'package' property, which is set at
 * the beginning of the property list.</p>
 * 
 * <p>For example, <code>com.mtgi:group=analytics,name=BeetLog</code>
 * would become <code>myapp:package=com.mtgi,group=analytics,name=BeetLog</code>
 * if the new domain name is "myapp".</p>
 * 
 * <p>Useful primarily for using annotations-based object names in complex deployments, 
 * where many applications might use the same framework classes (therefore increasing 
 * the risk of a naming collision).</p>
 */
public class AppendNamingStrategy implements ObjectNamingStrategy {

    /**
     * While the order of key properties in the objectname doesn't affect the identity of
     * the object, it does affect presentation in jconsole.  So we construct our name
     * in a particular order to produce folder groupings that make sense.
     */
    private static final String[] PROPERTY_ORDER = { "package", "group", "name" };
    private static final Pattern QUOTE_NEEDED = Pattern.compile("[\\\\*?\n\",:=\\s]");

    private ObjectNamingStrategy delegate;
    private String domain;
    private String key = "name";
    private String renameKey = "group";
    private String value;

    @Required
    public void setDelegate(ObjectNamingStrategy delegate) {
        this.delegate = delegate;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void setRenameKey(String renameKey) {
        this.renameKey = renameKey;
    }

    public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
        ObjectName base = delegate.getObjectName(managedBean, beanKey);

        @SuppressWarnings("unchecked")
        HashMap<String, String> properties = new HashMap<String, String>(base.getKeyPropertyList());
        //change the domain if required
        String domain = this.domain;
        if (domain == null)
            domain = base.getDomain();
        else {
            String oldDomain = base.getDomain();
            if (oldDomain != null) {
                //append the prior domain name onto the package property.
                String pkg = properties.get("package");
                pkg = (pkg == null) ? oldDomain : pkg + "." + oldDomain;
                properties.put("package", pkg);
            }
        }

        //append extra key if required
        if (key != null && value != null) {
            //append the extra key to the object name
            String oldValue = properties.remove(key);
            properties.put(key, value);

            //move the displaced prior value to a different property
            if (oldValue != null && renameKey != null) {
                String prefix = properties.remove(renameKey);
                if (prefix != null)
                    oldValue = prefix + "." + oldValue;
                properties.put(renameKey, oldValue);
            }
        }

        StringBuffer buf = new StringBuffer();
        buf.append(quote(domain));
        char sep = ':';
        //enforce a canonical order on all specified properties
        for (String prop : PROPERTY_ORDER) {
            String value = properties.remove(prop);
            if (value != null) {
                buf.append(sep).append(prop).append('=').append(quote(value));
                sep = ',';
            }
        }
        //all remaining properties get appended in unspecified order
        for (Iterator<Map.Entry<String, String>> it = properties.entrySet().iterator(); it.hasNext();) {
            Map.Entry<String, String> prop = it.next();
            it.remove();
            buf.append(sep).append(prop.getKey()).append('=').append(quote(prop.getValue()));
            sep = ',';
        }

        return ObjectName.getInstance(buf.toString());
    }

    /** reluctantly quote the given input string (quoting only applied if the string contains control characters) */
    public static final String quote(String input) {
        if (QUOTE_NEEDED.matcher(input).find())
            return ObjectName.quote(input);
        return input;
    }
}