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.jcs3.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 final ConcurrentMap<Key, MBeanServer> JVM_SINGLETONS = new ConcurrentHashMap<>(); 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 } 053 if (o == null || getClass() != o.getClass()) { 054 return false; 055 } 056 057 final Key key = Key.class.cast(o); 058 return !(domain != null ? !domain.equals(key.domain) : key.domain != null) 059 && !(outer != null ? !outer.equals(key.outer) : key.outer != null); 060 061 } 062 063 @Override 064 public int hashCode() 065 { 066 int result = domain != null ? domain.hashCode() : 0; 067 result = 31 * result + (outer != null ? outer.hashCode() : 0); 068 return result; 069 } 070 } 071 072 @Override 073 public MBeanServer newMBeanServer(final String defaultDomain, final MBeanServer outer, final MBeanServerDelegate delegate) 074 { 075 final Key key = new Key(defaultDomain, outer); 076 MBeanServer server = JVM_SINGLETONS.get(key); 077 if (server == null) 078 { 079 server = super.newMBeanServer(defaultDomain, outer, new ForceIdMBeanServerDelegate(delegate)); 080 final MBeanServer existing = JVM_SINGLETONS.putIfAbsent(key, server); 081 if (existing != null) 082 { 083 server = existing; 084 } 085 } 086 return server; 087 } 088 089 private class ForceIdMBeanServerDelegate extends MBeanServerDelegate 090 { 091 private final MBeanServerDelegate delegate; 092 093 public ForceIdMBeanServerDelegate(final MBeanServerDelegate delegate) 094 { 095 this.delegate = delegate; 096 } 097 098 @Override 099 public String getMBeanServerId() 100 { 101 return System.getProperty("org.jsr107.tck.management.agentId", delegate.getMBeanServerId()); 102 } 103 104 @Override 105 public String getSpecificationName() 106 { 107 return delegate.getSpecificationName(); 108 } 109 110 @Override 111 public String getSpecificationVersion() 112 { 113 return delegate.getSpecificationVersion(); 114 } 115 116 @Override 117 public String getSpecificationVendor() 118 { 119 return delegate.getSpecificationVendor(); 120 } 121 122 @Override 123 public String getImplementationName() 124 { 125 return delegate.getImplementationName(); 126 } 127 128 @Override 129 public String getImplementationVersion() 130 { 131 return delegate.getImplementationVersion(); 132 } 133 134 @Override 135 public String getImplementationVendor() 136 { 137 return delegate.getImplementationVendor(); 138 } 139 140 @Override 141 public MBeanNotificationInfo[] getNotificationInfo() 142 { 143 return delegate.getNotificationInfo(); 144 } 145 146 @Override 147 public void addNotificationListener(final NotificationListener listener, final NotificationFilter filter, final Object handback) 148 throws IllegalArgumentException 149 { 150 delegate.addNotificationListener(listener, filter, handback); 151 } 152 153 @Override 154 public void removeNotificationListener(final NotificationListener listener, final NotificationFilter filter, final Object handback) 155 throws ListenerNotFoundException 156 { 157 delegate.removeNotificationListener(listener, filter, handback); 158 } 159 160 @Override 161 public void removeNotificationListener(final NotificationListener listener) throws ListenerNotFoundException 162 { 163 delegate.removeNotificationListener(listener); 164 } 165 166 @Override 167 public void sendNotification(final Notification notification) 168 { 169 delegate.sendNotification(notification); 170 } 171 } 172}