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    
015    package org.apache.hivemind.management.impl;
016    
017    import java.beans.PropertyEditorManager;
018    
019    import javax.management.MalformedObjectNameException;
020    import javax.management.ObjectName;
021    
022    import org.apache.hivemind.ApplicationRuntimeException;
023    import org.apache.hivemind.internal.ServicePoint;
024    import org.apache.hivemind.management.ObjectNameBuilder;
025    import 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     */
037    public 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    }