001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jmx;
031:
032: import com.caucho.log.Log;
033: import com.caucho.util.L10N;
034: import com.caucho.loader.*;
035:
036: import javax.management.*;
037: import java.util.*;
038: import java.util.logging.Logger;
039:
040: /**
041: * The view for administration.
042: */
043: public class MBeanView {
044: private static final Logger log = Logger.getLogger(MBeanView.class
045: .getName());
046: private static final L10N L = new L10N(MBeanView.class);
047:
048: private ClassLoader _classLoader;
049:
050: private AbstractMBeanServer _mbeanServer;
051:
052: private MBeanServerDelegateImpl _delegate;
053:
054: private HashMap<ObjectName, MBeanWrapper> _mbeans = new HashMap<ObjectName, MBeanWrapper>();
055:
056: MBeanView(AbstractMBeanServer mbeanServer, ClassLoader loader,
057: String agentId) {
058: for (; loader != null
059: && loader != ClassLoader.getSystemClassLoader()
060: && !(loader instanceof EnvironmentClassLoader); loader = loader
061: .getParent()) {
062: }
063:
064: if (loader == null)
065: loader = ClassLoader.getSystemClassLoader();
066:
067: _mbeanServer = mbeanServer;
068:
069: _classLoader = loader;
070: _delegate = new MBeanServerDelegateImpl(agentId);
071: }
072:
073: /**
074: * Returns the class loader.
075: */
076: public ClassLoader getClassLoader() {
077: return _classLoader;
078: }
079:
080: /**
081: * Returns the parent local view.
082: */
083: protected MBeanView getParentView() {
084: if (_classLoader == null)
085: return null;
086:
087: MBeanContext context = _mbeanServer.createContext(_classLoader
088: .getParent());
089:
090: if (context.getView() == this )
091: return null;
092: else
093: return context.getView();
094:
095: /*
096: if (_classLoader != null)
097: return Jmx.getLocalView(_classLoader.getParent());
098: else
099: return null;
100: */
101: }
102:
103: /**
104: * Returns the parent global view.
105: */
106: protected MBeanView getParentGlobalView() {
107: return null;
108: /*
109: if (_classLoader != null)
110: return Jmx.getLocalView(_classLoader.getParent());
111: else
112: return null;
113: */
114: }
115:
116: /**
117: * Returns the mbean count.
118: */
119: public int getMBeanCount() {
120: MBeanView parentView = getParentView();
121:
122: if (parentView != null)
123: return _mbeans.size() + parentView.getMBeanCount();
124: else
125: return _mbeans.size();
126: }
127:
128: /**
129: * Returns the mbean domains.
130: */
131: public String[] getDomains() {
132: ArrayList<String> domains = new ArrayList<String>();
133:
134: getDomains(domains);
135:
136: return domains.toArray(new String[domains.size()]);
137: }
138:
139: /**
140: * Returns the mbean domains.
141: */
142: protected void getDomains(ArrayList<String> domains) {
143: synchronized (_mbeans) {
144: Iterator<ObjectName> names = _mbeans.keySet().iterator();
145: while (names.hasNext()) {
146: ObjectName name = names.next();
147:
148: String domain = name.getDomain();
149:
150: if (!domains.contains(domain))
151: domains.add(domain);
152: }
153: }
154:
155: MBeanView parent = getParentView();
156:
157: if (parent != null)
158: parent.getDomains(domains);
159: }
160:
161: /**
162: * Finds names matching the query.
163: */
164: public Set<ObjectName> queryNames(ObjectName queryName,
165: QueryExp query) throws BadStringOperationException,
166: BadBinaryOpValueExpException,
167: BadAttributeValueExpException, InvalidApplicationException {
168: // TreeSet would be better but it causes jconsole to fail
169: HashSet<ObjectName> set = new HashSet<ObjectName>();
170:
171: queryNames(set, queryName, query);
172:
173: return set;
174: }
175:
176: /**
177: * Finds names matching the query.
178: */
179: protected void queryNames(Set<ObjectName> set,
180: ObjectName queryName, QueryExp query)
181: throws BadStringOperationException,
182: BadBinaryOpValueExpException,
183: BadAttributeValueExpException, InvalidApplicationException {
184: synchronized (_mbeans) {
185: Iterator<ObjectName> iter = _mbeans.keySet().iterator();
186:
187: while (iter.hasNext()) {
188: ObjectName name = iter.next();
189:
190: if (isMatch(name, queryName, query)) {
191: set.add(name);
192: }
193: }
194: }
195:
196: MBeanView parentView = getParentView();
197:
198: if (parentView != null)
199: parentView.queryNames(set, queryName, query);
200: }
201:
202: /**
203: * Finds names matching the query.
204: */
205: public Set<ObjectInstance> queryMBeans(ObjectName name,
206: QueryExp query) throws BadStringOperationException,
207: BadBinaryOpValueExpException,
208: BadAttributeValueExpException, InvalidApplicationException {
209: HashSet<ObjectInstance> set = new HashSet<ObjectInstance>();
210:
211: queryMBeans(set, name, query);
212:
213: return set;
214: }
215:
216: /**
217: * Finds names matching the query.
218: */
219: protected void queryMBeans(Set<ObjectInstance> set,
220: ObjectName name, QueryExp query)
221: throws BadStringOperationException,
222: BadBinaryOpValueExpException,
223: BadAttributeValueExpException, InvalidApplicationException {
224: synchronized (_mbeans) {
225: Iterator<ObjectName> iter = _mbeans.keySet().iterator();
226:
227: while (iter.hasNext()) {
228: ObjectName testName = iter.next();
229:
230: if (isMatch(testName, name, query)) {
231: MBeanWrapper mbean = _mbeans.get(testName);
232:
233: if (mbean != null)
234: set.add(mbean.getObjectInstance());
235: }
236: }
237: }
238:
239: MBeanView parentView = getParentView();
240:
241: if (parentView != null)
242: parentView.queryMBeans(set, name, query);
243: }
244:
245: /**
246: * Tests if the name matches.
247: *
248: * @param name the object name to match
249: * @param queryName the name of the query pattern
250: */
251: private boolean isMatch(ObjectName name, ObjectName queryName,
252: QueryExp query) throws BadStringOperationException,
253: BadBinaryOpValueExpException,
254: BadAttributeValueExpException, InvalidApplicationException {
255: if (queryName == null)
256: return true;
257:
258: if (!queryName.isDomainPattern()
259: && !name.getDomain().equals(queryName.getDomain()))
260: return false;
261:
262: if (queryName.isPropertyPattern()) {
263: // If the queryName has a '*' in the properties, then check
264: // the queryName properties to see if they match
265:
266: Hashtable<String, String> map = queryName
267: .getKeyPropertyList();
268: Iterator<String> iter = map.keySet().iterator();
269: while (iter.hasNext()) {
270: String key = iter.next();
271: String value = map.get(key);
272:
273: if (!value.equals(name.getKeyProperty(key)))
274: return false;
275: }
276: } else {
277: String testProps = name.getCanonicalKeyPropertyListString();
278: String queryProps = queryName
279: .getCanonicalKeyPropertyListString();
280:
281: if (!testProps.equals(queryProps))
282: return false;
283: }
284:
285: if (query != null && !query.apply(name))
286: return false;
287:
288: return true;
289: }
290:
291: /**
292: * Adds an mbean instance to the view.
293: */
294: boolean add(ObjectName name, MBeanWrapper mbean) {
295: return add(name, mbean, false);
296: }
297:
298: /**
299: * Adds an mbean instance to the view.
300: */
301: boolean add(ObjectName name, MBeanWrapper mbean, boolean overwrite) {
302: synchronized (_mbeans) {
303: if (overwrite || _mbeans.get(name) == null) {
304: _mbeans.put(name, mbean);
305:
306: return true;
307: } else
308: return false;
309: }
310: }
311:
312: /**
313: * Removes an mbean instance from the view.
314: */
315: MBeanWrapper remove(ObjectName name) {
316: synchronized (_mbeans) {
317: return _mbeans.remove(name);
318: }
319: }
320:
321: /**
322: * Removes an mbean instance from the view.
323: */
324: MBeanWrapper remove(ObjectName name, MBeanWrapper mbean) {
325: synchronized (_mbeans) {
326: if (mbean != null && _mbeans.get(name) != mbean)
327: return null;
328:
329: return _mbeans.remove(name);
330: }
331: }
332:
333: /**
334: * Returns the object.
335: */
336: public MBeanWrapper getMBean(ObjectName name) {
337: synchronized (_mbeans) {
338: MBeanWrapper mbean = _mbeans.get(name);
339: if (mbean != null)
340: return mbean;
341:
342: if (_classLoader == null)
343: return null;
344: }
345:
346: MBeanView parentView = getParentView();
347:
348: if (parentView != null)
349: return parentView.getMBean(name);
350: else
351: return null;
352: }
353:
354: /**
355: * Closes the view.
356: */
357: void close() {
358: _mbeans = null;
359: }
360:
361: public String toString() {
362: return "MBeanView[" + _classLoader + "]";
363: }
364:
365: }
|