001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.console.filter;
018    
019    import java.io.IOException;
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.Iterator;
023    import java.util.List;
024    import java.util.Set;
025    
026    import javax.management.Attribute;
027    import javax.management.AttributeList;
028    import javax.management.InstanceNotFoundException;
029    import javax.management.IntrospectionException;
030    import javax.management.MBeanAttributeInfo;
031    import javax.management.MBeanServerConnection;
032    import javax.management.ObjectInstance;
033    import javax.management.ObjectName;
034    import javax.management.ReflectionException;
035    import javax.management.remote.JMXConnector;
036    import javax.management.remote.JMXConnectorFactory;
037    import javax.management.remote.JMXServiceURL;
038    
039    public class MBeansAttributeQueryFilter extends AbstractQueryFilter {
040        public static final String KEY_OBJECT_NAME_ATTRIBUTE = "Attribute:ObjectName:";
041    
042        private MBeanServerConnection jmxConnection;
043        private Set attribView;
044    
045        /**
046         * Create an mbean attributes query filter that is able to select specific
047         * mbean attributes based on the object name to get.
048         * 
049         * @param jmxConnection - JMX connection to use.
050         * @param attribView - the attributes to extract
051         * @param next - the next query filter
052         */
053        public MBeansAttributeQueryFilter(MBeanServerConnection jmxConnection, Set attribView, MBeansObjectNameQueryFilter next) {
054            super(next);
055            this.jmxConnection = jmxConnection;
056            this.attribView = attribView;
057        }
058    
059        /**
060         * Filter the query by retrieving the attributes specified, this will modify
061         * the collection to a list of AttributeList
062         * 
063         * @param queries - query list
064         * @return List of AttributeList, which includes the ObjectName, which has a
065         *         key of MBeansAttributeQueryFilter.KEY_OBJECT_NAME_ATTRIBUTE
066         * @throws Exception
067         */
068        public List query(List queries) throws Exception {
069            return getMBeanAttributesCollection(next.query(queries));
070        }
071    
072        /**
073         * Retrieve the specified attributes of the mbean
074         * 
075         * @param result - collection of ObjectInstances and/or ObjectNames
076         * @return List of AttributeList
077         * @throws IOException
078         * @throws ReflectionException
079         * @throws InstanceNotFoundException
080         * @throws NoSuchMethodException
081         */
082        protected List getMBeanAttributesCollection(Collection result) throws IOException, ReflectionException, InstanceNotFoundException, NoSuchMethodException, IntrospectionException {
083            List mbeansCollection = new ArrayList();
084    
085            for (Iterator i = result.iterator(); i.hasNext();) {
086                Object mbean = i.next();
087                if (mbean instanceof ObjectInstance) {
088                    mbeansCollection.add(getMBeanAttributes(((ObjectInstance)mbean).getObjectName(), attribView));
089                } else if (mbean instanceof ObjectName) {
090                    mbeansCollection.add(getMBeanAttributes((ObjectName)mbean, attribView));
091                } else {
092                    throw new NoSuchMethodException("Cannot get the mbean attributes for class: " + mbean.getClass().getName());
093                }
094            }
095    
096            return mbeansCollection;
097        }
098    
099        /**
100         * Retrieve the specified attributes of the mbean
101         * 
102         * @param obj - mbean ObjectInstance
103         * @param attrView - list of attributes to retrieve
104         * @return AttributeList for the mbean
105         * @throws ReflectionException
106         * @throws InstanceNotFoundException
107         * @throws IOException
108         */
109        protected AttributeList getMBeanAttributes(ObjectInstance obj, Set attrView) throws ReflectionException, InstanceNotFoundException, IOException, IntrospectionException {
110            return getMBeanAttributes(obj.getObjectName(), attrView);
111        }
112    
113        /**
114         * Retrieve the specified attributes of the mbean
115         * 
116         * @param objName - mbean ObjectName
117         * @param attrView - list of attributes to retrieve
118         * @return AttributeList for the mbean
119         * @throws IOException
120         * @throws ReflectionException
121         * @throws InstanceNotFoundException
122         */
123        protected AttributeList getMBeanAttributes(ObjectName objName, Set attrView) throws IOException, ReflectionException, InstanceNotFoundException, IntrospectionException {
124            // If no attribute view specified, get all attributes
125            String[] attribs;
126            if (attrView == null || attrView.isEmpty()) {
127                MBeanAttributeInfo[] infos = jmxConnection.getMBeanInfo(objName).getAttributes();
128                attribs = new String[infos.length];
129    
130                for (int i = 0; i < infos.length; i++) {
131                    if (infos[i].isReadable()) {
132                        attribs[i] = infos[i].getName();
133                    }
134                }
135    
136                // Get selected attributes
137            } else {
138    
139                attribs = new String[attrView.size()];
140                int count = 0;
141                for (Iterator i = attrView.iterator(); i.hasNext();) {
142                    attribs[count++] = (String)i.next();
143                }
144            }
145    
146            AttributeList attribList = jmxConnection.getAttributes(objName, attribs);
147    
148            attribList.add(0, new Attribute(KEY_OBJECT_NAME_ATTRIBUTE, objName));
149    
150            return attribList;
151        }
152    }