Source Code Cross Referenced for MBeanInstaller.java in  » EJB-Server-JBoss-4.2.1 » jmx » org » jboss » mx » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » jmx » org.jboss.mx.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.mx.util;
023:
024:        import java.beans.PropertyEditor;
025:        import java.beans.PropertyEditorManager;
026:        import java.io.InputStream;
027:        import java.util.Date;
028:        import java.util.List;
029:        import java.util.HashMap;
030:        import java.util.Map;
031:
032:        import javax.management.InstanceNotFoundException;
033:        import javax.management.MalformedObjectNameException;
034:        import javax.management.MBeanException;
035:        import javax.management.MBeanServer;
036:        import javax.management.ObjectName;
037:        import javax.management.ObjectInstance;
038:        import javax.management.ReflectionException;
039:
040:        import org.jboss.logging.Logger;
041:        import org.jboss.mx.server.ObjectInputStreamWithClassLoader;
042:        import org.jboss.mx.server.ServerConstants;
043:        import org.jboss.mx.loading.MBeanElement;
044:        import org.jboss.util.UnreachableStatementException;
045:
046:        /**
047:         * MBean installer utility<p>
048:         *
049:         * This installer allows MLet to install or upgrade a mbean based on the version
050:         * specified in the MLet conf file. If the mbean version is newer than the 
051:         * registered in the server, the installer unregisters the old mbean and then
052:         * registers the new one. This management needs to store the mbean version into
053:         * the MBeanRegistry in the server.
054:         *
055:         * When we register mbeans, however, we can't pass the metadata to MBeanServer
056:         * through the standard JMX api because Both of createMBean() and registerMBean()
057:         * have no extra arguments to attach the metadata. Thus we call 
058:         * MBeanServer.invoke() directly to set/get the internal MBean metadata.
059:         *
060:         * Currently version and date are stored in the mbean registry as mbean metadata.
061:         * The date will be used for preparing presentaionString for this mbean info.
062:         * For managment purpose, we can add any extra data to the matadata if you need.
063:         *
064:         * @author  <a href="mailto:Fusayuki.Minamoto@fujixerox.co.jp">Fusayuki Minamoto</a>.
065:         * @author  <a href="mailto:jplindfo@helsinki.fi">Juha Lindfors</a>.
066:         *
067:         * @version $Revision: 57200 $
068:         *
069:         * <p><b>Revisions:</b>
070:         *
071:         * <p><b>20020219 Juha Lindfors:</b>
072:         * <ul>
073:         * <li>Clarified the use of classloaders in the code, renaming loader to a more
074:         *     explicit ctxClassLoader
075:         * </li>
076:         * <li>Fixed some irregularities with the install/update code -- original
077:         *     implementatio was cause IndexOutOfBoundsExceptions which prevented
078:         *     some replacements in valid cases. Fixing this uncovered update logic
079:         *     that would replace MBeans that were not associated with versioning
080:         *     information at all.
081:         *     <p>
082:         *     The current semantics should be:
083:         *     <ol>
084:         *     <li>If an MBean is registered without versioning information it can
085:         *         never be automatically replaced by another MBean (regardless of
086:         *         the versioning information in the new MBean).
087:         *     </li>
088:         *     <li>An MBean that has a higher version number (as determined by the
089:         *         MLetVersion Comparable interface) can automatically replace an 
090:         *         MBean that was registered with a lower version number.
091:         *     </li>
092:         *     <li>An MBean without versioning info can never automatically replace
093:         *         an MBean that was registered with version.
094:         *     </li>
095:         *     </ol>
096:         * </li>
097:         * </ul>
098:         */
099:        public class MBeanInstaller {
100:            // Constants -----------------------------------------------------
101:
102:            public static final String VERSIONS = "versions";
103:            public static final String DATE = "date";
104:
105:            // Static --------------------------------------------------------
106:
107:            /**
108:             * Logger instance.
109:             */
110:            private static final Logger log = Logger
111:                    .getLogger(MBeanInstaller.class);
112:
113:            /** Augment the PropertyEditorManager search path to incorporate the JBoss
114:                specific editors. This simply references the PropertyEditors.class to
115:                invoke its static initialization block.
116:             */
117:            static {
118:                Class c = org.jboss.util.propertyeditor.PropertyEditors.class;
119:                if (c == null)
120:                    throw new UnreachableStatementException();
121:            }
122:
123:            // Attributes ----------------------------------------------------
124:
125:            /**
126:             * Reference to the MBean server the installed MBeans will get registered to.
127:             */
128:            private MBeanServer server;
129:
130:            /**
131:             * Reference to the context classloader of the MLet MBean that is installing
132:             * the new MBeans.
133:             */
134:            private ClassLoader ctxClassLoader;
135:
136:            /**
137:             * Object name of the MLet MBean installing new MBeans to the server. This
138:             * object name is used as the explicit classloader object name when
139:             * instantiating new MBeans. This is to ensure the MLet's classloader is the
140:             * first one to be consulted when loading classes. This is implicitly
141:             * guaranteed by the UnifiedLoaderRepository but is not necessarily the case
142:             * with other loader repository implementations.
143:             */
144:            private ObjectName loaderName;
145:
146:            /**
147:             * Object name of the MBeanServer registry MBean.
148:             */
149:            private ObjectName registryName;
150:
151:            // Constructors --------------------------------------------------
152:
153:            /**
154:             * Create a new MBean installer instance.
155:             *
156:             * @param   server         reference to the MBean server where the new MBeans will
157:             *                         be registered to
158:             * @param   ctxClassLoader Context class loader reference which will be 
159:             *                         stored in the registry for the new MBeans. This
160:             *                         classloader will be set as the thread context
161:             *                         classloader when the MBean is invoked.
162:             * @param   loaderName     Object name of the classloader that should be
163:             *                         used to instantiate the newly registered MBeans.
164:             *                         This should normally be the object name of the
165:             *                         MLet MBean that is installing the new MBeans.
166:             */
167:            public MBeanInstaller(MBeanServer server,
168:                    ClassLoader ctxClassLoader, ObjectName loaderName)
169:                    throws Exception {
170:                this .server = server;
171:                this .ctxClassLoader = ctxClassLoader;
172:                this .loaderName = loaderName;
173:                this .registryName = new ObjectName(
174:                        ServerConstants.MBEAN_REGISTRY);
175:            }
176:
177:            // Public --------------------------------------------------------
178:
179:            /**
180:             * Install a mbean with mbean metadata<p>
181:             *
182:             * @param element    the data parsed from the Mlet file
183:             *
184:             * @return mbean instance
185:             */
186:            public ObjectInstance installMBean(MBeanElement element)
187:                    throws MBeanException, ReflectionException,
188:                    InstanceNotFoundException, MalformedObjectNameException {
189:                log.debug("Installing MBean: " + element);
190:
191:                ObjectInstance instance = null;
192:                ObjectName elementName = getElementName(element);
193:
194:                if (element.getVersions().isEmpty()
195:                        || !server.isRegistered(elementName)) {
196:                    if (element.getCode() != null)
197:                        instance = createMBean(element);
198:                    else if (element.getObject() != null)
199:                        instance = deserialize(element);
200:                    else
201:                        throw new MBeanException(new IllegalArgumentException(
202:                                "No code or object tag"));
203:                } else
204:                    instance = updateMBean(element);
205:
206:                return instance;
207:            }
208:
209:            public ObjectInstance createMBean(MBeanElement element)
210:                    throws MBeanException, ReflectionException,
211:                    InstanceNotFoundException, MalformedObjectNameException {
212:                log.debug("Creating MBean.. ");
213:
214:                ObjectName elementName = getElementName(element);
215:
216:                // Set up the valueMap passing to the registry.
217:                // This valueMap contains mbean meta data and update time.
218:                Map valueMap = createValueMap(element);
219:
220:                // Create the mbean instance
221:
222:                // TODO:
223:                // check the delegateToCLR attribute in the MLetElement here to determine
224:                // the loading behavior in case of CNFE
225:
226:                String[] classes = element.getConstructorTypes();
227:                String[] paramStrings = element.getConstructorValues();
228:                Object[] params = new Object[paramStrings.length];
229:                for (int i = 0; i < paramStrings.length; ++i) {
230:                    try {
231:                        Class typeClass = server.getClassLoaderRepository()
232:                                .loadClass(classes[i]);
233:                        PropertyEditor editor = PropertyEditorManager
234:                                .findEditor(typeClass);
235:                        if (editor == null)
236:                            throw new IllegalArgumentException(
237:                                    "No property editor for type=" + typeClass);
238:
239:                        editor.setAsText(paramStrings[i]);
240:                        params[i] = editor.getValue();
241:                    } catch (Exception e) {
242:                        throw new MBeanException(e);
243:                    }
244:                }
245:                Object instance = server.instantiate(element.getCode(),
246:                        loaderName, params, classes);
247:
248:                // Call MBeanRegistry.invoke("registerMBean") instead of server.registerMBean() to pass
249:                // the valueMap that contains management values including mbean metadata and update time.
250:                return registerMBean(instance, elementName, valueMap);
251:            }
252:
253:            public ObjectInstance deserialize(MBeanElement element)
254:                    throws MBeanException, ReflectionException,
255:                    InstanceNotFoundException, MalformedObjectNameException {
256:                InputStream is = null;
257:                Object instance = null;
258:                try {
259:                    is = ctxClassLoader
260:                            .getResourceAsStream(element.getObject());
261:                    if (is == null)
262:                        throw new IllegalArgumentException("Object not found "
263:                                + element.getObject());
264:                    ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(
265:                            is, ctxClassLoader);
266:                    instance = ois.readObject();
267:                } catch (Exception e) {
268:                    throw new MBeanException(e);
269:                } finally {
270:                    if (is != null) {
271:                        try {
272:                            is.close();
273:                        } catch (Exception ignored) {
274:                        }
275:                    }
276:                }
277:                ObjectName elementName = getElementName(element);
278:
279:                // Set up the valueMap passing to the registry.
280:                // This valueMap contains mbean meta data and update time.
281:                Map valueMap = createValueMap(element);
282:                return registerMBean(instance, elementName, valueMap);
283:            }
284:
285:            public ObjectInstance updateMBean(MBeanElement element)
286:                    throws MBeanException, ReflectionException,
287:                    InstanceNotFoundException, MalformedObjectNameException {
288:                log.debug("updating MBean... ");
289:
290:                ObjectName elementName = getElementName(element);
291:
292:                // Compare versions to decide whether to skip installation of this mbean
293:                MLetVersion preVersion = new MLetVersion(
294:                        getVersions(elementName));
295:                MLetVersion newVersion = new MLetVersion(element.getVersions());
296:
297:                log.debug("Installed version : " + preVersion);
298:                log.debug("Loaded version    : " + newVersion);
299:
300:                // FIXME: this comparison works well only if both versions are specified
301:                //        because jmx spec doesn't fully specify this behavior.
302:                if (!preVersion.isNull() && !newVersion.isNull()
303:                        && preVersion.compareTo(newVersion) < 0) {
304:                    // Unregister previous mbean
305:                    if (server.isRegistered(elementName)) {
306:                        unregisterMBean(elementName);
307:
308:                        log.debug("Unregistering previous version "
309:                                + preVersion);
310:                    }
311:
312:                    log.debug("Installing newer version " + newVersion);
313:
314:                    // Create mbean with value map
315:                    return createMBean(element);
316:                }
317:
318:                return server.getObjectInstance(elementName);
319:            }
320:
321:            // Private -------------------------------------------------------
322:
323:            private ObjectName getElementName(MBeanElement element)
324:                    throws MalformedObjectNameException {
325:                return (element.getName() != null) ? new ObjectName(element
326:                        .getName()) : null;
327:            }
328:
329:            private Map createValueMap(MBeanElement element) {
330:                HashMap valueMap = new HashMap();
331:
332:                // We need to set versions here because we can't get the mbean entry
333:                // outside the server.
334:                if (element.getVersions() != null
335:                        && !element.getVersions().isEmpty())
336:                    valueMap.put(VERSIONS, element.getVersions());
337:
338:                // The date would be used to make a presentationString for this mbean.
339:                valueMap.put(DATE, new Date(System.currentTimeMillis()));
340:
341:                // Context class loader for the MBean.
342:                valueMap.put(ServerConstants.CLASSLOADER, ctxClassLoader);
343:
344:                return valueMap;
345:            }
346:
347:            private List getVersions(ObjectName name) throws MBeanException,
348:                    ReflectionException, InstanceNotFoundException {
349:                if (!server.isRegistered(name))
350:                    return null;
351:
352:                return (List) getValue(name, VERSIONS);
353:            }
354:
355:            private Object getValue(ObjectName name, String key)
356:                    throws MBeanException, ReflectionException,
357:                    InstanceNotFoundException {
358:                Object value = server.invoke(registryName, "getValue",
359:                        new Object[] { name, key }, new String[] {
360:                                ObjectName.class.getName(),
361:                                String.class.getName() });
362:
363:                return value;
364:            }
365:
366:            private ObjectInstance registerMBean(Object object,
367:                    ObjectName name, Map valueMap) throws MBeanException,
368:                    ReflectionException, InstanceNotFoundException {
369:                if (object == null) {
370:                    throw new ReflectionException(new IllegalArgumentException(
371:                            "Attempting to register a null object"));
372:                }
373:
374:                return (ObjectInstance) server
375:                        .invoke(registryName, "registerMBean", new Object[] {
376:                                object, name, valueMap },
377:                                new String[] { Object.class.getName(),
378:                                        ObjectName.class.getName(),
379:                                        Map.class.getName() });
380:            }
381:
382:            private void unregisterMBean(ObjectName name)
383:                    throws MBeanException, ReflectionException,
384:                    InstanceNotFoundException {
385:                server.invoke(registryName, "unregisterMBean",
386:                        new Object[] { name, }, new String[] { ObjectName.class
387:                                .getName(), });
388:            }
389:        }
390:
391:        /**
392:         * MLetVersion for encapsulating the version representation<p>
393:         *
394:         * Because this class is comparable, you can elaborate the
395:         * version comparison algorithm if you need better one.
396:         */
397:        class MLetVersion implements  Comparable {
398:            protected List versions;
399:
400:            public MLetVersion(List versions) {
401:                this .versions = versions;
402:            }
403:
404:            public List getVersions() {
405:                return versions;
406:            }
407:
408:            public boolean isNull() {
409:                return versions == null || versions.isEmpty();
410:            }
411:
412:            public int compareTo(Object o) {
413:                MLetVersion other = (MLetVersion) o;
414:
415:                if (isNull() || other.isNull())
416:                    throw new IllegalArgumentException("MLet versions is null");
417:
418:                // FIXME: this compares only first element of the versions.
419:                //        do we really need multiple versions?
420:                String this Version = (String) versions.get(0);
421:                String otherVersion = (String) other.getVersions().get(0);
422:
423:                return (this Version.compareTo(otherVersion));
424:            }
425:
426:            public String toString() {
427:                return "Version " + versions.get(0);
428:            }
429:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.