001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.jcs.jcache.jmx; 020 021import javax.management.ListenerNotFoundException; 022import javax.management.MBeanNotificationInfo; 023import javax.management.MBeanServer; 024import javax.management.MBeanServerBuilder; 025import javax.management.MBeanServerDelegate; 026import javax.management.Notification; 027import javax.management.NotificationFilter; 028import javax.management.NotificationListener; 029import java.util.concurrent.ConcurrentHashMap; 030import java.util.concurrent.ConcurrentMap; 031 032public class ConfigurableMBeanServerIdBuilder extends MBeanServerBuilder 033{ 034 private static ConcurrentMap<Key, MBeanServer> JVM_SINGLETONS = new ConcurrentHashMap<Key, MBeanServer>(); 035 036 private static class Key 037 { 038 private final String domain; 039 private final MBeanServer outer; 040 041 private Key(final String domain, final MBeanServer outer) 042 { 043 this.domain = domain; 044 this.outer = outer; 045 } 046 047 @Override 048 public boolean equals(final Object o) 049 { 050 if (this == o) 051 return true; 052 if (o == null || getClass() != o.getClass()) 053 return false; 054 055 final Key key = Key.class.cast(o); 056 return !(domain != null ? !domain.equals(key.domain) : key.domain != null) 057 && !(outer != null ? !outer.equals(key.outer) : key.outer != null); 058 059 } 060 061 @Override 062 public int hashCode() 063 { 064 int result = domain != null ? domain.hashCode() : 0; 065 result = 31 * result + (outer != null ? outer.hashCode() : 0); 066 return result; 067 } 068 } 069 070 @Override 071 public MBeanServer newMBeanServer(final String defaultDomain, final MBeanServer outer, final MBeanServerDelegate delegate) 072 { 073 final Key key = new Key(defaultDomain, outer); 074 MBeanServer server = JVM_SINGLETONS.get(key); 075 if (server == null) 076 { 077 server = super.newMBeanServer(defaultDomain, outer, new ForceIdMBeanServerDelegate(delegate)); 078 final MBeanServer existing = JVM_SINGLETONS.putIfAbsent(key, server); 079 if (existing != null) 080 { 081 server = existing; 082 } 083 } 084 return server; 085 } 086 087 private class ForceIdMBeanServerDelegate extends MBeanServerDelegate 088 { 089 private final MBeanServerDelegate delegate; 090 091 public ForceIdMBeanServerDelegate(final MBeanServerDelegate delegate) 092 { 093 this.delegate = delegate; 094 } 095 096 @Override 097 public String getMBeanServerId() 098 { 099 return System.getProperty("org.jsr107.tck.management.agentId", delegate.getMBeanServerId()); 100 } 101 102 @Override 103 public String getSpecificationName() 104 { 105 return delegate.getSpecificationName(); 106 } 107 108 @Override 109 public String getSpecificationVersion() 110 { 111 return delegate.getSpecificationVersion(); 112 } 113 114 @Override 115 public String getSpecificationVendor() 116 { 117 return delegate.getSpecificationVendor(); 118 } 119 120 @Override 121 public String getImplementationName() 122 { 123 return delegate.getImplementationName(); 124 } 125 126 @Override 127 public String getImplementationVersion() 128 { 129 return delegate.getImplementationVersion(); 130 } 131 132 @Override 133 public String getImplementationVendor() 134 { 135 return delegate.getImplementationVendor(); 136 } 137 138 @Override 139 public MBeanNotificationInfo[] getNotificationInfo() 140 { 141 return delegate.getNotificationInfo(); 142 } 143 144 @Override 145 public void addNotificationListener(final NotificationListener listener, final NotificationFilter filter, final Object handback) 146 throws IllegalArgumentException 147 { 148 delegate.addNotificationListener(listener, filter, handback); 149 } 150 151 @Override 152 public void removeNotificationListener(final NotificationListener listener, final NotificationFilter filter, final Object handback) 153 throws ListenerNotFoundException 154 { 155 delegate.removeNotificationListener(listener, filter, handback); 156 } 157 158 @Override 159 public void removeNotificationListener(final NotificationListener listener) throws ListenerNotFoundException 160 { 161 delegate.removeNotificationListener(listener); 162 } 163 164 @Override 165 public void sendNotification(final Notification notification) 166 { 167 delegate.sendNotification(notification); 168 } 169 } 170}