001: /* JFox, the OpenSource J2EE Application Server
002: *
003: * Copyright (C) 2002 huihoo.com
004: * Distributable under GNU LGPL license
005: * See the GNU Lesser General Public License for more details.
006: */
007:
008: package org.huihoo.jfox.service;
009:
010: import java.lang.reflect.Proxy;
011:
012: import javax.management.ObjectName;
013: import javax.management.MBeanServer;
014: import javax.management.InstanceNotFoundException;
015: import javax.management.MBeanServerInvocationHandler;
016: import javax.management.AttributeChangeNotification;
017: import javax.management.Notification;
018: import javax.management.NotificationBroadcasterSupport;
019: import javax.management.MBeanRegistration;
020: import javax.management.NotificationBroadcaster;
021: import javax.management.NotificationListener;
022:
023: import org.huihoo.jfox.logging.Logger;
024: import org.huihoo.jfox.jmx.ExtendedObjectInstance;
025:
026: /**
027: *
028: * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
029: */
030:
031: public abstract class ComponentSupport extends
032: NotificationBroadcasterSupport implements
033: ComponentSupportMBean, MBeanRegistration,
034: NotificationBroadcaster, NotificationListener {
035: /**
036: * service name of the service
037: */
038: protected String name = null;
039: /**
040: * the ObjectName of the service register into the MBeanServer
041: */
042: protected ObjectName objectName = null;
043: /**
044: * the status value of the service
045: */
046: protected volatile State state = State.ORIGINAL;
047:
048: /**
049: * MBeanService instance
050: */
051: protected MBeanServer server = null;
052:
053: protected Logger logger = Logger.getLogger(getClass().getName());
054: protected volatile long sequence = 0L;
055:
056: protected Object proxyInstance = null;
057:
058: public ComponentSupport() {
059: setName(parseName(this .getClass().getName()));
060: }
061:
062: public ComponentSupport(String name) {
063: setName(name);
064: }
065:
066: public String getName() {
067: return name;
068: }
069:
070: protected void setName(String name) {
071: this .name = name;
072: }
073:
074: public ObjectName getObjectName() {
075: return objectName;
076: }
077:
078: public State getState() {
079: return state;
080: }
081:
082: /**
083: * get the proxy instance
084: * if return itself, unregisterMBean will invalidate
085: */
086: public Proxy getProxyInstance() {
087: if (server == null || objectName == null)
088: return null;
089: // initialzing proxyInstance;
090: if (proxyInstance == null) {
091: ExtendedObjectInstance oi = null;
092: try {
093: oi = (ExtendedObjectInstance) server
094: .getObjectInstance(objectName);
095: } catch (InstanceNotFoundException e) {
096: e.printStackTrace();
097: }
098: Class interfaceClass = oi.getInterfaceClass();
099: proxyInstance = MBeanServerInvocationHandler
100: .newProxyInstance(server, objectName,
101: interfaceClass, true);
102: }
103:
104: return (Proxy) proxyInstance;
105: }
106:
107: public Logger getLogger() {
108: return logger;
109: }
110:
111: protected void setLogger(Logger logger) {
112: this .logger = logger;
113: }
114:
115: public void init() throws Exception {
116: if (!State.canInit(state)) {
117: logger.warn(name + " can not initialize, state = " + state);
118: return;
119: }
120:
121: // if(logger == null) logger = Logger.getLogger(getClass().getName());
122: logger.info("initializing...");
123: sendNotification(new AttributeChangeNotification(this ,
124: sequence++, System.currentTimeMillis(), getName()
125: + " starting", "State", "java.lang.Integer",
126: new Integer(state.getId()), new Integer(
127: State.INITIALIZING.getId())));
128: state = State.INITIALIZING;
129:
130: try {
131: doInit();
132: } catch (Exception e) {
133: sendNotification(new AttributeChangeNotification(this ,
134: sequence++, System.currentTimeMillis(), getName()
135: + " creating failed", "State",
136: "java.lang.Integer", new Integer(state.getId()),
137: new Integer(State.INTERRUPTED.getId())));
138: state = State.INTERRUPTED;
139: logger.error("initialze failed", e);
140: throw e;
141: }
142: sendNotification(new AttributeChangeNotification(this ,
143: sequence++, System.currentTimeMillis(), getName()
144: + " created", "State", "java.lang.Integer",
145: new Integer(state.getId()), new Integer(
146: State.INITIALIZED.getId())));
147:
148: state = State.INITIALIZED;
149: logger.info("initialized.");
150:
151: }
152:
153: public void destroy() throws Exception {
154: if (!State.canDestroy(state)) {
155: logger.warn(name + " can not destroy, state = " + state);
156: return;
157: }
158:
159: logger.info("destroying...");
160:
161: sendNotification(new AttributeChangeNotification(this ,
162: sequence++, System.currentTimeMillis(), getName()
163: + " destroying", "State", "java.lang.Integer",
164: new Integer(state.getId()), new Integer(
165: State.DESTROYING.getId())));
166: state = State.DESTROYING;
167: try {
168: doDestroy();
169: } catch (Exception e) {
170: sendNotification(new AttributeChangeNotification(this ,
171: sequence++, System.currentTimeMillis(), getName()
172: + " destroy failed", "State",
173: "java.lang.Integer", new Integer(state.getId()),
174: new Integer(State.INTERRUPTED.getId())));
175: state = State.INTERRUPTED;
176: logger.error("stopping failed", e);
177: throw e;
178: }
179: sendNotification(new AttributeChangeNotification(this ,
180: sequence++, System.currentTimeMillis(), getName()
181: + " destroyed", "State", "java.lang.Integer",
182: new Integer(state.getId()), new Integer(State.DESTROYED
183: .getId())));
184: state = State.DESTROYED;
185: logger.info("destroyed");
186:
187: }
188:
189: /**
190: * ObjectName must specified in the MLet, or use registerMBean specified explicitly
191: */
192: public ObjectName preRegister(MBeanServer server, ObjectName name)
193: throws Exception {
194: if (name == null)
195: throw new IllegalArgumentException(
196: "ObjectName can not be null.");
197:
198: // get log service instance
199: this .server = server;
200: objectName = name;
201:
202: return name;
203: }
204:
205: public void postRegister(Boolean registrationDone) {
206: if (!registrationDone.booleanValue()) {
207: try {
208: this .destroy();
209: } catch (Exception e) {
210: logger.error(e.getMessage(), e);
211: }
212: } else {
213: // initilize & start
214: try {
215: this .init();
216: } catch (Exception e) {
217: logger.error(e.getMessage(), e);
218: }
219:
220: }
221:
222: }
223:
224: public void preDeregister() throws Exception {
225:
226: }
227:
228: public void postDeregister() {
229:
230: }
231:
232: public void handleNotification(Notification notification, Object obj) {
233: logger.info("Recieved notification, type: "
234: + notification.getType() + ", " + "message: "
235: + notification.getMessage() + ", " + "source: "
236: + notification.getSource());
237:
238: }
239:
240: /**
241: * do actually create action
242: */
243: protected abstract void doInit() throws Exception;
244:
245: /**
246: * do actually destory action
247: */
248: protected abstract void doDestroy() throws Exception;
249:
250: // trip the ServiceName from it's class nameSpace
251: protected static String parseName(String className) {
252: int lastDotIndex = className.lastIndexOf(".");
253: return className.substring(lastDotIndex + 1);
254: }
255:
256: }
|