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.console.plugins.helpers;
023:
024: import org.jboss.console.manager.PluginManager;
025: import org.jboss.console.manager.interfaces.ConsolePlugin;
026: import org.jboss.console.manager.interfaces.ManageableResource;
027: import org.jboss.console.manager.interfaces.ResourceTreeNode;
028: import org.jboss.console.manager.interfaces.TreeAction;
029: import org.jboss.console.manager.interfaces.TreeNode;
030: import org.jboss.console.manager.interfaces.TreeNodeMenuEntry;
031: import org.jboss.console.manager.interfaces.impl.HttpLinkTreeAction;
032: import org.jboss.console.manager.interfaces.impl.MBeanResource;
033: import org.jboss.console.manager.interfaces.impl.SeparatorTreeNodeMenuEntry;
034: import org.jboss.console.manager.interfaces.impl.SimpleFolderResource;
035: import org.jboss.console.manager.interfaces.impl.SimpleResourceTreeNode;
036: import org.jboss.console.manager.interfaces.impl.SimpleTreeNode;
037: import org.jboss.console.manager.interfaces.impl.SimpleTreeNodeMenuEntryImpl;
038: import org.jboss.logging.Logger;
039: import org.jboss.mx.util.MBeanServerLocator;
040: import org.jboss.system.Registry;
041:
042: import javax.management.MBeanServer;
043: import javax.management.MalformedObjectNameException;
044: import javax.management.ObjectInstance;
045: import javax.management.ObjectName;
046: import javax.management.Query;
047: import javax.management.QueryExp;
048: import javax.servlet.ServletConfig;
049: import java.util.HashMap;
050: import java.util.Set;
051:
052: /**
053: * <description>
054: *
055: * @see <related>
056: *
057: * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
058: * @version $Revision: 57191 $
059: *
060: * <p><b>Revisions:</b>
061: *
062: * <p><b>2 janv. 2003 Sacha Labourey:</b>
063: * <ul>
064: * <li> First implementation </li>
065: * </ul>
066: */
067: public abstract class AbstractPluginWrapper implements PluginWrapper,
068: ConsolePlugin {
069: // Constants -----------------------------------------------------
070:
071: public static final String OBJECT_NAME_PARAM = "ObjectName";
072: public static final String FOLDER_NAME_PARAM = "FolderName";
073: public static final String MBEAN_CLASS_PARAM = "MBeanClass";
074: public static final String WRAPPER_CLASS_PARAM = "WrapperClass";
075: public static final String SCRIPT_NAME_PARAM = "ScriptName";
076: public static final String IS_ROOT_NODE_PARAM = "IsRootNode";
077:
078: // Attributes ----------------------------------------------------
079:
080: protected MBeanServer mbeanServer = null;
081: protected PluginManager pm = null;
082:
083: protected String pluginName = null;
084: protected String pluginVersion = null;
085:
086: protected String objectName = null;
087: protected String mbeanClass = null;
088: protected String folderName = null;
089:
090: protected String rootContextName = null;
091:
092: protected Logger log = org.jboss.logging.Logger.getLogger(this
093: .getClass());
094:
095: protected InternalResourceChecker checker = null;
096:
097: // Static --------------------------------------------------------
098:
099: // Constructors --------------------------------------------------
100:
101: public AbstractPluginWrapper() {
102: }
103:
104: // Public --------------------------------------------------------
105:
106: // Z implementation ----------------------------------------------
107:
108: // PluginWrapper overrides ---------------------------------------
109:
110: public void init(ServletConfig servletConfig) throws Exception {
111: findJBossMBeanServer();
112: findPluginManager();
113: readConfigurationParameters(servletConfig);
114:
115: this .pm.registerPlugin(this );
116: }
117:
118: public void destroy() {
119: if (pm != null)
120: pm.unregisterPlugin(this );
121: }
122:
123: public void readConfigurationParameters(ServletConfig config) {
124: this .pluginName = config.getInitParameter("PluginName");
125: this .pluginVersion = config.getInitParameter("PluginVersion");
126:
127: this .folderName = config.getInitParameter(FOLDER_NAME_PARAM);
128: this .objectName = config.getInitParameter(OBJECT_NAME_PARAM);
129: this .mbeanClass = config.getInitParameter(MBEAN_CLASS_PARAM);
130: this .rootContextName = config.getInitParameter("ContextName");
131:
132: String tmp = this .objectName;
133: if (tmp != null && !"".equals(tmp)) {
134: // this kind of plugin is associated with a single MBean
135: // which has a give JMX ObjectName
136: //
137: checker = new SingleMBeanChecker();
138: }
139:
140: tmp = this .folderName;
141: if (tmp != null && !"".equals(tmp)) {
142: // this kind of plugins is associated with one of the static folder of the tree
143: //
144: checker = new SubFolderChecker();
145: }
146:
147: tmp = config.getInitParameter(IS_ROOT_NODE_PARAM);
148: if (tmp != null && !"".equals(tmp)
149: && "true".equalsIgnoreCase(tmp)) {
150: // this kind of plugins is associated with the root of the tree
151: //
152: checker = new RootTreeChecker();
153: }
154:
155: tmp = this .mbeanClass;
156: if (tmp != null && !"".equals(tmp)) {
157: // this kind of plugins is associated with all MBean
158: // that share a given interface
159: //
160: checker = new StandardMBeanChecker();
161: }
162:
163: }
164:
165: // ConsolePlugin overrides ---------------------------------------
166:
167: public String getIdentifier() {
168: if (this .pluginName != null) {
169: return this .pluginName
170: + " (Wrapped by ServletPluginHelper)";
171: } else {
172: return getPluginIdentifier();
173: }
174: }
175:
176: public String getVersion() {
177: if (this .pluginVersion != null) {
178: return this .pluginVersion;
179: } else {
180: return getPluginVersion();
181: }
182: }
183:
184: public String[] getSupportedProfiles() {
185: return new String[] { ConsolePlugin.WEB_PROFILE };
186: }
187:
188: public TreeNode getSubTreeForResource(PluginManager master,
189: String profile, ManageableResource resource) {
190: if (!ConsolePlugin.WEB_PROFILE.equalsIgnoreCase(profile)) {
191: return null;
192: } else {
193: if (isResourceToBeManaged(resource)) {
194: return getTreeForResource(profile, resource);
195: } else {
196: return null;
197: }
198: }
199: }
200:
201: // Abstract Methods ---------------------------------------------
202:
203: protected boolean isResourceToBeManaged(ManageableResource resource) {
204: if (checker == null) {
205: return false;
206: } else {
207: return checker.isResourceToBeManaged(resource);
208: }
209: }
210:
211: protected abstract TreeNode getTreeForResource(String profile,
212: ManageableResource resource);
213:
214: protected String getPluginIdentifier() {
215: return "AbstractPluginWrapper (" + this .getClass() + ")";
216: }
217:
218: protected String getPluginVersion() {
219: return "unknown version";
220: }
221:
222: // Package protected ---------------------------------------------
223:
224: // Protected -----------------------------------------------------
225:
226: protected void findJBossMBeanServer() {
227: this .mbeanServer = MBeanServerLocator.locateJBoss();
228: }
229:
230: protected void findPluginManager() {
231: this .pm = (PluginManager) Registry
232: .lookup(PluginManager.PLUGIN_MANAGER_NAME);
233: }
234:
235: protected MBeanServer getMBeanServer() {
236: return this .mbeanServer;
237: }
238:
239: protected String fixUrl(String source) {
240: if (source == null) {
241: return null;
242: } else if (source.toLowerCase().startsWith("http://")
243: || source.toLowerCase().startsWith("https://")) {
244: return source;
245: } else if (source.startsWith("/")) {
246: return source; // already absolute
247: } else {
248: return this .rootContextName + "/" + source;
249: }
250: }
251:
252: protected ObjectInstance[] getMBeansForClass(String scope,
253: String className) {
254: try {
255: Set result = mbeanServer
256: .queryMBeans(new ObjectName(scope), Query.eq(Query
257: .classattr(), Query.value(className)));
258:
259: return (ObjectInstance[]) result
260: .toArray(new ObjectInstance[result.size()]);
261: } catch (MalformedObjectNameException e) {
262: log.debug(e);
263: return new ObjectInstance[0];
264: }
265:
266: }
267:
268: protected ObjectInstance[] getMBeansForQuery(String scope,
269: QueryExp query) {
270: try {
271: Set result = mbeanServer.queryMBeans(new ObjectName(scope),
272: query);
273: return (ObjectInstance[]) result
274: .toArray(new ObjectInstance[result.size()]);
275: } catch (MalformedObjectNameException e) {
276: log.debug(e);
277: return new ObjectInstance[0];
278: }
279:
280: }
281:
282: protected SimpleTreeNode createTreeNode(String name,
283: String description, String iconUrl, String defaultUrl,
284: TreeNodeMenuEntry[] menuEntries, TreeNode[] subNodes,
285: ResourceTreeNode[] subResNodes) throws Exception {
286: TreeAction action = new HttpLinkTreeAction(fixUrl(defaultUrl));
287: return new SimpleTreeNode(name, description, fixUrl(iconUrl),
288: action, menuEntries, subNodes, subResNodes);
289: }
290:
291: protected SimpleResourceTreeNode createResourceNode(String name,
292: String description, String iconUrl, String defaultUrl,
293: TreeNodeMenuEntry[] menuEntries, TreeNode[] subNodes,
294: ResourceTreeNode[] subResNodes, String jmxObjectName,
295: String jmxClassName) throws Exception {
296: TreeAction action = new HttpLinkTreeAction(fixUrl(defaultUrl));
297: ManageableResource res = new MBeanResource(new ObjectName(
298: jmxObjectName), jmxClassName);
299: return new SimpleResourceTreeNode(name, description,
300: fixUrl(iconUrl), action, menuEntries, subNodes,
301: subResNodes, res);
302: }
303:
304: protected SimpleResourceTreeNode createResourceNode(String name,
305: String description, String iconUrl, String defaultUrl,
306: TreeNodeMenuEntry[] menuEntries, TreeNode[] subNodes,
307: ResourceTreeNode[] subResNodes, ManageableResource resource)
308: throws Exception {
309: TreeAction action = new HttpLinkTreeAction(fixUrl(defaultUrl));
310: return new SimpleResourceTreeNode(name, description,
311: fixUrl(iconUrl), action, menuEntries, subNodes,
312: subResNodes, resource);
313: }
314:
315: protected TreeNodeMenuEntry[] createMenus(String[] content)
316: throws Exception {
317:
318: TreeNodeMenuEntry[] menuEntries = null;
319:
320: if (content != null && content.length > 0) {
321: menuEntries = new TreeNodeMenuEntry[content.length];
322: int i = 0;
323: while (i < content.length) {
324: if (content[i] == null) {
325: menuEntries[i] = new SeparatorTreeNodeMenuEntry();
326: i++;
327: } else {
328: String text = content[i];
329: TreeAction action = new HttpLinkTreeAction(
330: fixUrl(content[i + 1]));
331: menuEntries[i] = new SimpleTreeNodeMenuEntryImpl(
332: text, action);
333: i += 2;
334: }
335: }
336: } else {
337: menuEntries = new TreeNodeMenuEntry[0];
338: }
339: return menuEntries;
340: }
341:
342: protected String encode(String source) {
343: try {
344: return java.net.URLEncoder.encode(source);
345: } catch (Exception e) {
346: return source;
347: }
348: }
349:
350: // Private -------------------------------------------------------
351:
352: // Inner classes -------------------------------------------------
353:
354: public interface InternalResourceChecker {
355: boolean isResourceToBeManaged(ManageableResource resource);
356: }
357:
358: public class StandardMBeanChecker implements
359: InternalResourceChecker {
360:
361: protected Class targetClass = null;
362: public HashMap knownAnswers = new HashMap();
363:
364: public StandardMBeanChecker() {
365: try {
366: targetClass = Thread.currentThread()
367: .getContextClassLoader().loadClass(mbeanClass);
368: } catch (Exception displayed) {
369: displayed.printStackTrace();
370: }
371: }
372:
373: public boolean isResourceToBeManaged(ManageableResource resource) {
374: if (resource instanceof MBeanResource) {
375: MBeanResource mbr = (MBeanResource) resource;
376:
377: Boolean result = (Boolean) knownAnswers.get(mbr
378: .getClassName());
379: if (result == null) {
380: // find answer and cache it
381: //
382: try {
383: //System.out.println("CHECK: " +
384: Class resourceClass = Thread.currentThread()
385: .getContextClassLoader().loadClass(
386: mbr.getClassName());
387: result = new Boolean(targetClass
388: .isAssignableFrom(resourceClass));
389: //result = new Boolean (resourceClass.isAssignableFrom(targetClass));
390: } catch (Exception e) {
391: result = Boolean.FALSE;
392: }
393: knownAnswers.put(mbr.getClassName(), result);
394:
395: }
396: return result.booleanValue();
397: } else
398: return false;
399: }
400: }
401:
402: public class RootTreeChecker implements InternalResourceChecker {
403:
404: public boolean isResourceToBeManaged(ManageableResource resource) {
405: if (resource == null)
406: return false;
407: else
408: return resource.equals(pm.getBootstrapResource());
409: }
410: }
411:
412: public class SingleMBeanChecker implements InternalResourceChecker {
413:
414: public boolean isResourceToBeManaged(ManageableResource resource) {
415: if (objectName != null && resource instanceof MBeanResource) {
416: MBeanResource mbr = (MBeanResource) resource;
417: return objectName
418: .equals(mbr.getObjectName().toString());
419:
420: } else
421: return false;
422: }
423:
424: }
425:
426: public class SubFolderChecker implements InternalResourceChecker {
427: public boolean isResourceToBeManaged(ManageableResource resource) {
428: if (resource == null
429: || !(resource instanceof SimpleFolderResource)) {
430: return false;
431: } else {
432: return folderName.equals(resource.getId());
433: }
434: }
435: }
436:
437: }
|