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    
018    package org.apache.commons.modeler.ant;
019    
020    import java.net.URL;
021    import java.util.ArrayList;
022    import java.util.List;
023    
024    import javax.management.JMException;
025    import javax.management.MBeanServer;
026    import javax.management.MBeanServerFactory;
027    import javax.management.ObjectName;
028    import javax.management.loading.MLet;
029    
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.tools.ant.BuildException;
033    import org.apache.tools.ant.Task;
034    
035    /**
036     * Load an MBean. The syntax is similar with the <mlet>, with few
037     * ant-specific extensions.
038     *
039     * A separate classloader can be used, the mechanism is similar with
040     * what taskdef is using.
041     *
042     * Note that mlet will use the arguments in the constructor.
043     *
044     *
045     */
046    public class MLETTask extends Task {
047        private static Log log = LogFactory.getLog(MLETTask.class);
048        String code;
049        String archive;
050        String codebase;
051        String objectName;
052        ObjectName oname;
053    
054        List args=new ArrayList();
055        List attributes=new ArrayList();
056    
057        // ant specific
058        String loaderRef; // class loader ref
059    
060        public MLETTask() {
061        }
062    
063        public void addArg(Arg arg ) {
064            args.add(arg);
065        }
066    
067        public void addAttribute( JmxSet arg ) {
068            attributes.add( arg );
069        }
070    
071    
072        public void setCode(String code) {
073            this.code = code;
074        }
075    
076        public void setArchive(String archive) {
077            this.archive = archive;
078        }
079    
080        public void setCodebase(String codebase) {
081            this.codebase = codebase;
082        }
083    
084        public void setName(String name) {
085            this.objectName = name;
086        }
087    
088        MBeanServer server;
089    
090        public MBeanServer getMBeanServer() {
091            if( server!= null ) return server;
092    
093            server=(MBeanServer)project.getReference("jmx.server");
094    
095            if (server != null) return server;
096    
097            try {
098                if( MBeanServerFactory.findMBeanServer(null).size() > 0 ) {
099                    server=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
100                } else {
101                    server=MBeanServerFactory.createMBeanServer();
102    
103                    // Register a loader that will be find ant classes.
104                    ObjectName defaultLoader= new ObjectName("modeler-ant",
105                            "loader", "ant");
106                    MLet mlet=new MLet( new URL[0], this.getClass().getClassLoader());
107                    server.registerMBean(mlet, defaultLoader);
108    
109                    if( log.isDebugEnabled())
110                        log.debug("Creating mbean server and loader "+ mlet +
111                                " " + this.getClass().getClassLoader());
112                }
113                project.addReference("jmx.server", server);
114    
115                // Create the MLet object
116            } catch( JMException ex ) {
117                log.error("Error creating server", ex);
118            }
119    
120            if( log.isDebugEnabled()) log.debug("Using Mserver " + server );
121    
122            return server;
123        }
124    
125        boolean modeler=false;
126    
127        public void setModeler(boolean modeler) {
128            this.modeler = modeler;
129        }
130    
131        protected void bindJmx(String objectName, String code,
132                               String arg0, List args)
133                throws Exception
134        {
135            MBeanServer server=getMBeanServer();
136            oname=new ObjectName( objectName );
137            if( modeler ) {
138                Arg codeArg=new Arg();
139                codeArg.setType("java.lang.String");
140                codeArg.setValue( code );
141                if( args==null) args=new ArrayList();
142                args.add(0, codeArg);
143                code="org.apache.commons.modeler.BaseModelMBean";
144            }
145    
146            Object argsA[]=new Object[ args.size()];
147            String sigA[]=new String[args.size()];
148            for( int i=0; i<args.size(); i++ ) {
149                Arg arg=(Arg)args.get(i);
150                if( arg.type==null )
151                    arg.type="java.lang.String";
152                sigA[i]=arg.getType();
153                argsA[i]=arg.getValue();
154                // XXX Deal with not string types - IntrospectionUtils
155            }
156    
157            // XXX Use the loader ref, if any
158            if( args.size()==0 ) {
159                server.createMBean(code, oname);
160            } else {
161                server.createMBean(code, oname, argsA, sigA );
162            }
163            log.debug( "Created MBEAN " + oname + " " + code);
164        }
165    
166        public ObjectName getObjectName() {
167            return oname;
168        }
169    
170        public void execute() throws BuildException {
171            try {
172                // create the mbean
173                bindJmx( objectName, code, null, args);
174    
175                // process attributes
176                for( int i=0; i<attributes.size(); i++ ) {
177                    JmxSet att=(JmxSet)attributes.get(i);
178                    att.setObjectName( oname );
179                    log.info("Setting attribute " + oname + " " + att.getName());
180                    att.execute();
181                }
182            } catch(Exception ex) {
183                log.error("Can't create mbean " + objectName, ex);
184            }
185        }
186    
187    }