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.commons.modeler.modules;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    import javax.management.DynamicMBean;
023    import javax.management.MBeanAttributeInfo;
024    import javax.management.MBeanInfo;
025    import javax.management.MBeanOperationInfo;
026    import javax.management.MBeanParameterInfo;
027    
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.commons.modeler.AttributeInfo;
031    import org.apache.commons.modeler.ManagedBean;
032    import org.apache.commons.modeler.OperationInfo;
033    import org.apache.commons.modeler.ParameterInfo;
034    import org.apache.commons.modeler.Registry;
035    
036    
037    /** Extract metadata from a dynamic mbean.
038     * Used to wrap a dynamic mbean in order to implement persistence.
039     * 
040     * This is really an ugly asspect of the JMX spec - we need to convery 
041     * from normal metainfo to model metainfo. The info is the same, but
042     * they use a different class. Just like the DOM spec - where all implementations
043     * get an order of unneeded complexity from the various types. 
044     * 
045     */ 
046    public class MbeansDescriptorsDynamicMBeanSource extends ModelerSource
047    {
048        private static Log log = LogFactory.getLog(MbeansDescriptorsDynamicMBeanSource.class);
049    
050        Registry registry;
051        String location;
052        String type;
053        Object source;
054        List mbeans=new ArrayList();
055    
056        public void setRegistry(Registry reg) {
057            this.registry=reg;
058        }
059    
060        public void setLocation( String loc ) {
061            this.location=loc;
062        }
063    
064        /** Used if a single component is loaded
065         *
066         * @param type
067         */
068        public void setType( String type ) {
069           this.type=type;
070        }
071    
072        public void setSource( Object source ) {
073            this.source=source;
074        }
075    
076        public List loadDescriptors( Registry registry, String location,
077                                     String type, Object source)
078                throws Exception
079        {
080            setRegistry(registry);
081            setLocation(location);
082            setType(type);
083            setSource(source);
084            execute();
085            return mbeans;
086        }
087    
088        public void execute() throws Exception {
089            if( registry==null ) registry=Registry.getRegistry();
090            try {
091                ManagedBean managed=createManagedBean(registry, null, source, type);
092                if( managed==null ) return;
093                managed.setName( type );
094                
095                mbeans.add(managed);
096    
097            } catch( Exception ex ) {
098                log.error( "Error reading descriptors ", ex);
099            }
100        }
101    
102    
103    
104        // ------------ Implementation for non-declared introspection classes
105    
106    
107        /**
108         * XXX Find if the 'className' is the name of the MBean or
109         *       the real class ( I suppose first )
110         * XXX Read (optional) descriptions from a .properties, generated
111         *       from source
112         * XXX Deal with constructors
113         *
114         */
115        public ManagedBean createManagedBean(Registry registry, String domain,
116                                             Object realObj, String type)
117        {
118            if( ! ( realObj instanceof DynamicMBean )) {
119                return null;
120            }
121            DynamicMBean dmb=(DynamicMBean)realObj;
122            
123            ManagedBean mbean= new ManagedBean();
124            
125            MBeanInfo mbi=dmb.getMBeanInfo();
126            
127            try {
128                MBeanAttributeInfo attInfo[]=mbi.getAttributes();
129                for( int i=0; i<attInfo.length; i++ ) {
130                    MBeanAttributeInfo mai=attInfo[i];
131                    String name=mai.getName();
132    
133                    AttributeInfo ai=new AttributeInfo();
134                    ai.setName( name );
135    
136                    ai.setType( mai.getType());
137                    ai.setReadable( mai.isReadable());
138                    ai.setWriteable( mai.isWritable());
139                                                    
140                    mbean.addAttribute(ai);
141                }
142    
143                MBeanOperationInfo opInfo[]=mbi.getOperations();
144                for( int i=0; i<opInfo.length; i++ ) {
145                    MBeanOperationInfo moi=opInfo[i];
146                    OperationInfo op=new OperationInfo();
147    
148                    op.setName(moi.getName());
149                    op.setReturnType(moi.getReturnType());
150                    
151                    MBeanParameterInfo parms[]=moi.getSignature();
152                    for(int j=0; j<parms.length; j++ ) {
153                        ParameterInfo pi=new ParameterInfo();
154                        pi.setType(parms[i].getType());
155                        pi.setName(parms[i].getName());
156                        op.addParameter(pi);
157                    }
158                    mbean.addOperation(op);
159                }
160    
161                if( log.isDebugEnabled())
162                    log.debug("Setting name: " + type );
163    
164                mbean.setName( type );
165    
166                return mbean;
167            } catch( Exception ex ) {
168                ex.printStackTrace();
169                return null;
170            }
171        }
172    
173    }