001// Copyright 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.hivemind.management.impl;
016
017import java.beans.PropertyEditorManager;
018
019import javax.management.MalformedObjectNameException;
020import javax.management.ObjectName;
021
022import org.apache.hivemind.ApplicationRuntimeException;
023import org.apache.hivemind.internal.ServicePoint;
024import org.apache.hivemind.management.ObjectNameBuilder;
025import org.apache.hivemind.util.IdUtils;
026
027/**
028 * Implementation of {@link org.apache.hivemind.management.ObjectNameBuilder}. A configurable domain
029 * is prepended to the ObjectNames. The ObjectNames include the module, extensionId and a type as
030 * key properties. Example for a service:
031 * HiveMind:module=hivemind,type=servicePoint,id=hivemind.Startup When using this naming Jconsole
032 * interprets the module key as package name and id as a class name.
033 * 
034 * @author Achim Huegen
035 * @since 1.1
036 */
037public class ObjectNameBuilderImpl implements ObjectNameBuilder
038{
039    private String _domain = "hivemind";
040
041    static
042    {
043        // Register PropertyEditor for ObjectNames. This is needed
044        // in MBeans contributions. Since ObjectNameBuilder is injected in
045        // MBeanRegistry, this is done just in time here
046        // Registration should be done in a more general way,
047        // but the concept discussed here:
048        // http://wiki.apache.org/jakarta-hivemind/ExtendingSmartTranslator
049        // doesn't work because MBeanRegistry is eagerly loaded.
050        PropertyEditorManager.registerEditor(ObjectName.class, ObjectNameEditor.class);
051    }
052
053    /**
054     * Creates an ObjectName from a String
055     */
056    protected ObjectName createObjectNameInstance(String name)
057    {
058        ObjectName objectName;
059        try
060        {
061            objectName = new ObjectName(name);
062        }
063        catch (MalformedObjectNameException e)
064        {
065            // Should never occur
066            throw new ApplicationRuntimeException(e);
067        }
068        return objectName;
069
070    }
071
072    /**
073     * Creates an ObjectName from list of keys and values and prepends the domain. Maintains the
074     * order of the keys and this distinguishes the method from the ObjectName constructor that
075     * accepts an hashtable of keys and values. The order influences the visualization in JConsole.
076     * Example: Hivemind:key1=value1,key2=value2
077     */
078    public ObjectName createObjectName(String[] keys, String[] values)
079    {
080        if (keys.length != values.length)
081            throw new IllegalArgumentException("Arrays keys and values must have same length");
082        StringBuffer sb = new StringBuffer();
083        sb.append(_domain + ':');
084        for (int i = 0; i < values.length; i++)
085        {
086            if (i > 0)
087                sb.append(",");
088            sb.append(keys[i]);
089            sb.append("=");
090            sb.append(values[i]);
091        }
092        return createObjectNameInstance(sb.toString());
093    }
094
095    /**
096     * @see org.apache.hivemind.management.ObjectNameBuilder#createObjectName(java.lang.String,
097     *      java.lang.String)
098     */
099    public ObjectName createObjectName(String qualifiedId, String type)
100    {
101        String moduleId = IdUtils.extractModule(qualifiedId);
102        if (moduleId == null)
103            moduleId = "(default package)";
104        String id = IdUtils.stripModule(qualifiedId);
105        return createObjectName(moduleId, id, type);
106    }
107
108    /**
109     * @see org.apache.hivemind.management.ObjectNameBuilder#createObjectName(java.lang.String,
110     *      java.lang.String, java.lang.String)
111     */
112    public ObjectName createObjectName(String moduleId, String id, String type)
113    {
114        return createObjectName(new String[]
115        { "module", "type", "id" }, new String[]
116        { moduleId, type, id });
117    }
118
119    /**
120     * @see org.apache.hivemind.management.ObjectNameBuilder#createServiceObjectName(org.apache.hivemind.internal.ServicePoint)
121     */
122    public ObjectName createServiceObjectName(ServicePoint servicePoint)
123    {
124        return createObjectName(servicePoint.getExtensionPointId(), "service");
125    }
126
127    /**
128     * @see org.apache.hivemind.management.ObjectNameBuilder#createServiceDecoratorName(org.apache.hivemind.internal.ServicePoint,
129     *      java.lang.String)
130     */
131    public ObjectName createServiceDecoratorName(ServicePoint servicePoint, String decoratorType)
132    {
133        return createObjectName(new String[]
134        { "module", "type", "id", "decorator" }, new String[]
135        { servicePoint.getModule().getModuleId(), "service",
136                IdUtils.stripModule(servicePoint.getExtensionPointId()), decoratorType });
137    }
138
139    public String getDomain()
140    {
141        return _domain;
142    }
143
144    public void setDomain(String domain)
145    {
146        _domain = domain;
147    }
148
149}