001: package com.tc.admin;
002:
003: import com.tc.util.event.EventMulticaster;
004: import com.tc.util.event.UpdateEventListener;
005:
006: import java.io.IOException;
007: import java.util.Map;
008:
009: import javax.management.ListenerNotFoundException;
010: import javax.management.MBeanServerConnection;
011: import javax.management.NotificationFilter;
012: import javax.management.NotificationListener;
013: import javax.management.remote.JMXConnector;
014: import javax.security.auth.Subject;
015:
016: /**
017: * Decorator for <tt>JMXConnector</tt>
018: */
019: public final class AuthenticatingJMXConnector implements JMXConnector {
020:
021: private ServerConnectionManager m_connectManager;
022: private JMXConnector m_connector;
023: private final EventMulticaster m_authObserver;
024: private final EventMulticaster m_collapseObserver;
025: private final EventMulticaster m_exceptionObserver;
026: private boolean m_authenticating;
027: private boolean m_securityEnabled;
028: private final Object m_error_lock;
029: private Exception m_error;
030:
031: public AuthenticatingJMXConnector(
032: ServerConnectionManager connectManager) throws IOException {
033: if (false)
034: throw new IOException(); // quiet compiler
035: m_connectManager = connectManager;
036: this .m_error_lock = new Object();
037: this .m_authObserver = new EventMulticaster();
038: this .m_collapseObserver = new EventMulticaster();
039: this .m_exceptionObserver = new EventMulticaster();
040: }
041:
042: private synchronized JMXConnector getConnector() {
043: return m_connector;
044: }
045:
046: private synchronized void setConnector(JMXConnector connector) {
047: this .m_connector = connector;
048: }
049:
050: public void addAuthenticationListener(UpdateEventListener listener) {
051: m_authObserver.addListener(listener);
052: }
053:
054: public void addCollapseListener(UpdateEventListener listener) {
055: this .m_collapseObserver.addListener(listener);
056: }
057:
058: public void addExceptionListener(UpdateEventListener listener) {
059: this .m_exceptionObserver.addListener(listener);
060: }
061:
062: public void addConnectionNotificationListener(
063: NotificationListener arg0, NotificationFilter arg1,
064: Object arg2) {
065: getConnector().addConnectionNotificationListener(arg0, arg1,
066: arg2);
067: }
068:
069: public void close() throws IOException {
070: getConnector().close();
071: }
072:
073: public void connect() throws IOException {
074: getConnector().connect();
075: }
076:
077: private void _connect() throws IOException {
078: Map env = m_connectManager.getConnectionEnvironment();
079:
080: setConnector(m_connectManager.getJmxConnector());
081: getConnector().connect(env);
082: }
083:
084: public synchronized void connect(Map conEnv) throws IOException {
085: try {
086: _connect();
087: } catch (RuntimeException e) {
088: if (e instanceof SecurityException) {
089: m_securityEnabled = true;
090: try {
091: Thread.sleep(500);
092: } catch (InterruptedException ie) {
093: m_collapseObserver.fireUpdateEvent();
094: return;
095: }
096: m_authenticating = true;
097: m_authObserver.fireUpdateEvent();
098: try {
099: while (m_authenticating)
100: wait();
101: } catch (InterruptedException ie) {
102: m_exceptionObserver.fireUpdateEvent();
103: return;
104: }
105: } else {
106: throw e;
107: }
108: } catch (IOException e) {
109: m_exceptionObserver.fireUpdateEvent();
110: throw e;
111: }
112: throwExceptions();
113: }
114:
115: private void throwExceptions() throws IOException {
116: synchronized (m_error_lock) {
117: if (m_error != null) {
118: m_exceptionObserver.fireUpdateEvent();
119: if (m_error instanceof IOException)
120: throw (IOException) m_error;
121: else if (m_error instanceof RuntimeException)
122: throw (RuntimeException) m_error;
123: }
124: }
125: if (m_securityEnabled)
126: throw new AuthenticationException();
127: }
128:
129: public synchronized void handleOkClick(String username,
130: String password) {
131: m_connectManager.setCredentials(username, password);
132: try {
133: m_collapseObserver.fireUpdateEvent();
134: setConnector(m_connectManager.getJmxConnector());
135: getConnector().connect(
136: m_connectManager.getConnectionEnvironment());
137: } catch (Exception e) {
138: synchronized (m_error_lock) {
139: m_error = e;
140: }
141: }
142: m_authenticating = false;
143: notifyAll();
144: }
145:
146: public String getConnectionId() throws IOException {
147: return getConnector().getConnectionId();
148: }
149:
150: public MBeanServerConnection getMBeanServerConnection()
151: throws IOException {
152: return getConnector().getMBeanServerConnection();
153: }
154:
155: public MBeanServerConnection getMBeanServerConnection(Subject arg0)
156: throws IOException {
157: return getConnector().getMBeanServerConnection(arg0);
158: }
159:
160: public void removeConnectionNotificationListener(
161: NotificationListener arg0, NotificationFilter arg1,
162: Object arg2) throws ListenerNotFoundException {
163: getConnector().removeConnectionNotificationListener(arg0, arg1,
164: arg2);
165: }
166:
167: public void removeConnectionNotificationListener(
168: NotificationListener arg0) throws ListenerNotFoundException {
169: getConnector().removeConnectionNotificationListener(arg0);
170: }
171:
172: // --------------------------------------------------------------------------------
173:
174: public static class AuthenticationException extends
175: RuntimeException {
176: public AuthenticationException() {
177: super();
178: }
179: }
180: }
|