📄 servernotifforwarder.java
字号:
/* * @(#)ServerNotifForwarder.java 1.50 06/03/01 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.jmx.remote.internal;import com.sun.jmx.remote.security.NotificationAccessController;import com.sun.jmx.remote.util.ClassLogger;import com.sun.jmx.remote.util.EnvHelp;import java.io.IOException;import java.security.AccessControlContext;import java.security.AccessController;import java.security.PrivilegedActionException;import java.security.PrivilegedExceptionAction;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import javax.management.InstanceNotFoundException;import javax.management.ListenerNotFoundException;import javax.management.MBeanPermission;import javax.management.MBeanServer;import javax.management.Notification;import javax.management.NotificationBroadcaster;import javax.management.NotificationFilter;import javax.management.ObjectInstance;import javax.management.ObjectName;import javax.management.remote.NotificationResult;import javax.management.remote.TargetedNotification;import javax.management.MalformedObjectNameException;import javax.security.auth.Subject;public class ServerNotifForwarder { public ServerNotifForwarder(MBeanServer mbeanServer, Map env, NotificationBuffer notifBuffer, String connectionId) { this.mbeanServer = mbeanServer; this.notifBuffer = notifBuffer; this.connectionId = connectionId; connectionTimeout = EnvHelp.getServerConnectionTimeout(env); checkNotificationEmission = EnvHelp.computeBooleanFromString( env, "jmx.remote.x.check.notification.emission"); notificationAccessController = (NotificationAccessController) env.get("com.sun.jmx.remote.notification.access.controller"); } public Integer addNotificationListener(final ObjectName name, final NotificationFilter filter) throws InstanceNotFoundException, IOException { if (logger.traceOn()) { logger.trace("addNotificationListener", "Add a listener at " + name); } checkState(); // Explicitly check MBeanPermission for addNotificationListener // checkMBeanPermission(name, "addNotificationListener"); if (notificationAccessController != null) { notificationAccessController.addNotificationListener( connectionId, name, Subject.getSubject(AccessController.getContext())); } try { Boolean instanceOf = (Boolean) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws InstanceNotFoundException { return new Boolean( mbeanServer.isInstanceOf(name, broadcasterClass)); } }); if (!instanceOf.booleanValue()) { throw new IllegalArgumentException("The specified MBean [" + name + "] is not a " + "NotificationBroadcaster " + "object."); } } catch (PrivilegedActionException e) { throw (InstanceNotFoundException) extractException(e); } final Integer id = getListenerID(); // 6238731: set the default domain if no domain is set. ObjectName nn = name; if (name.getDomain() == null || name.getDomain().equals("")) { try { nn = ObjectName.getInstance(mbeanServer.getDefaultDomain(), name.getKeyPropertyList()); } catch (MalformedObjectNameException mfoe) { // impossible, but... IOException ioe = new IOException(mfoe.getMessage()); ioe.initCause(mfoe); throw ioe; } } synchronized (listenerMap) { IdAndFilter idaf = new IdAndFilter(id, filter); Set<IdAndFilter> set = listenerMap.get(nn); // Tread carefully because if set.size() == 1 it may be the // Collections.singleton we make here, which is unmodifiable. if (set == null) set = Collections.singleton(idaf); else { if (set.size() == 1) set = new HashSet<IdAndFilter>(set); set.add(idaf); } listenerMap.put(nn, set); } return id; } public void removeNotificationListener(ObjectName name, Integer[] listenerIDs) throws Exception { if (logger.traceOn()) { logger.trace("removeNotificationListener", "Remove some listeners from " + name); } checkState(); // Explicitly check MBeanPermission for removeNotificationListener // checkMBeanPermission(name, "removeNotificationListener"); if (notificationAccessController != null) { notificationAccessController.removeNotificationListener( connectionId, name, Subject.getSubject(AccessController.getContext())); } Exception re = null; for (int i = 0 ; i < listenerIDs.length ; i++) { try { removeNotificationListener(name, listenerIDs[i]); } catch (Exception e) { // Give back the first exception // if (re != null) { re = e; } } } if (re != null) { throw re; } } public void removeNotificationListener(ObjectName name, Integer listenerID) throws InstanceNotFoundException, ListenerNotFoundException, IOException { if (logger.traceOn()) { logger.trace("removeNotificationListener", "Remove the listener " + listenerID + " from " + name); } checkState(); if (name != null && !name.isPattern()) { if (!mbeanServer.isRegistered(name)) { throw new InstanceNotFoundException("The MBean " + name + " is not registered."); } } synchronized (listenerMap) { // Tread carefully because if set.size() == 1 it may be a // Collections.singleton, which is unmodifiable. Set<IdAndFilter> set = listenerMap.get(name); IdAndFilter idaf = new IdAndFilter(listenerID, null); if (set == null || !set.contains(idaf)) throw new ListenerNotFoundException("Listener not found"); if (set.size() == 1) listenerMap.remove(name); else set.remove(idaf); } } /* This is the object that will apply our filtering to candidate * notifications. First of all, if there are no listeners for the * ObjectName that the notification is coming from, we go no further. * Then, for each listener, we must apply the corresponding filter (if any) * and ignore the listener if the filter rejects. Finally, we apply * some access checks which may also reject the listener. * * A given notification may trigger several listeners on the same MBean, * which is why listenerMap is a Map<ObjectName, Set<IdAndFilter>> and * why we add the found notifications to a supplied List rather than * just returning a boolean. */ private final NotificationBufferFilter bufferFilter = new NotificationBufferFilter() { public void apply(List<TargetedNotification> targetedNotifs, ObjectName source, Notification notif) { // We proceed in two stages here, to avoid holding the listenerMap // lock while invoking the filters (which are user code). final IdAndFilter[] candidates; synchronized (listenerMap) { final Set<IdAndFilter> set = listenerMap.get(source); if (set == null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -