EMMA Coverage Report (generated Sat Jul 01 16:38:45 PDT 2006)
[all classes][jade.jademx.agent]

COVERAGE SUMMARY FOR SOURCE FILE [JademxAgent.java]

nameclass, %method, %block, %line, %
JademxAgent.java100% (1/1)74%  (48/65)56%  (1807/3216)61%  (397.2/653)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JademxAgent100% (1/1)74%  (48/65)56%  (1807/3216)61%  (397.2/653)
setMBeanInfo (MBeanInfo): void 0%   (0/1)0%   (0/5)0%   (0/1)
setUnitTestCmpContent (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpConversationId (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpEncoding (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpEnvelope (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpInReplyTo (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpLanguage (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpOntology (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpPerformative (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpProtocol (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpReceiver (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpReplyTo (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpReplyWith (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpSender (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestCmpUserProperties (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestIgnoreContentAIDAddresses (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUnitTestNewlinesNormalized (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setAttribute (Attribute): void 100% (1/1)12%  (136/1156)22%  (44/204)
setUnitTestExpectedMessage (String): void 100% (1/1)30%  (11/37)57%  (4/7)
setUnitTestInjectMessage (String): void 100% (1/1)30%  (6/20)60%  (3/5)
setAttributes (AttributeList): AttributeList 100% (1/1)50%  (14/28)42%  (3.8/9)
getAttributes (String []): AttributeList 100% (1/1)64%  (23/36)68%  (6.8/10)
getUnitTestActualMessage (): String 100% (1/1)67%  (8/12)75%  (3/4)
getUnitTestExpectedMessage (): String 100% (1/1)67%  (8/12)75%  (3/4)
getUnitTestInjectMessage (): String 100% (1/1)67%  (8/12)75%  (3/4)
assertExpectedMessage (String, ObjectName, MBeanServer): void 100% (1/1)67%  (188/280)66%  (52/79)
invoke (String, Object [], String []): Object 100% (1/1)71%  (78/110)78%  (14/18)
setup (): void 100% (1/1)74%  (174/236)83%  (38/46)
<static initializer> 100% (1/1)82%  (122/149)96%  (28.8/30)
changedMBeanInfo (): void 100% (1/1)84%  (48/57)82%  (7.4/9)
getMBeanInfo (): MBeanInfo 100% (1/1)91%  (48/53)92%  (7.4/8)
unitTestInjectAndExpect (): void 100% (1/1)92%  (55/60)93%  (14/15)
assertIsJademxAgent (ObjectName, MBeanServer, long, long): void 100% (1/1)92%  (34/37)86%  (12/14)
isUnitTestVisible (ObjectName, MBeanServer): boolean 100% (1/1)95%  (19/20)88%  (7/8)
JademxAgent (): void 100% (1/1)95%  (100/105)100% (29/29)
assertExpectedMessage (ObjectName, MBeanServer): void 100% (1/1)100% (5/5)100% (2/2)
assertIsJademxAgent (ObjectName, MBeanServer): void 100% (1/1)100% (6/6)100% (2/2)
constructMBeanInfo (): MBeanInfo 100% (1/1)100% (377/377)100% (12/12)
getAttribute (String): Object 100% (1/1)100% (235/235)100% (65/65)
getUnitTestTimeout (): String 100% (1/1)100% (4/4)100% (1/1)
isJademxBound (ObjectName, MBeanServer): boolean 100% (1/1)100% (6/6)100% (2/2)
isUnitTestCmpContent (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpConversationId (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpEncoding (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpEnvelope (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpInReplyTo (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpLanguage (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpOntology (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpPerformative (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpProtocol (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpReceiver (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpReplyBy (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpReplyTo (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpReplyWith (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpSender (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestCmpUserProperties (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestIgnoreContentAIDAddresses (): boolean 100% (1/1)100% (3/3)100% (1/1)
isUnitTestNewlinesNormalized (): boolean 100% (1/1)100% (3/3)100% (1/1)
notifyListeners (String, String, Object): void 100% (1/1)100% (11/11)100% (3/3)
setJadeAgent (JadeAgent): void 100% (1/1)100% (6/6)100% (3/3)
setUnitTestActualMessage (ACLMessage): void 100% (1/1)100% (4/4)100% (2/2)
setUnitTestCmpReplyBy (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setUnitTestTimeout (String): void 100% (1/1)100% (7/7)100% (2/2)
unitTestAddVariable (String, String): void 100% (1/1)100% (7/7)100% (2/2)
unitTestClearVariables (): void 100% (1/1)100% (4/4)100% (2/2)

1// jademx - JADE management using JMX
2// Copyright 2005-2006 Caboodle Networks, Inc.
3//
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8//
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12// Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 
18package jade.jademx.agent;
19 
20import jade.content.lang.sl.SLCodec;
21import jade.core.Agent;
22import jade.domain.FIPANames;
23import jade.domain.FIPAAgentManagement.FIPAManagementOntology;
24import jade.domain.JADEAgentManagement.JADEManagementOntology;
25import jade.domain.introspection.IntrospectionOntology;
26import jade.jademx.mbean.JadeAgent;
27import jade.jademx.mbean.JadeJMXAgent;
28import jade.jademx.mbean.JadePlatform;
29import jade.jademx.mbean.JadeRuntime;
30import jade.jademx.mbean.JadeRuntimeMBean;
31import jade.jademx.mbean.JademxException;
32import jade.jademx.server.JadeMXServer;
33import jade.jademx.server.JadeMXServerFactory;
34import jade.jademx.unit.UnitTestBehaviour;
35import jade.jademx.unit.UnitTestNotificationListener;
36import jade.jademx.util.AclMsgCmp;
37import jade.jademx.util.MBeanUtil;
38import jade.jademx.util.ThrowableUtil;
39import jade.jademx.util.iso8601.Duration;
40import jade.lang.acl.ACLMessage;
41import jade.lang.acl.ACLCodec.CodecException;
42import jade.util.Logger;
43 
44import java.util.Date;
45import java.util.Properties;
46import java.util.logging.Level;
47 
48import javax.management.Attribute;
49import javax.management.AttributeList;
50import javax.management.AttributeNotFoundException;
51import javax.management.InvalidAttributeValueException;
52import javax.management.MBeanAttributeInfo;
53import javax.management.MBeanConstructorInfo;
54import javax.management.MBeanException;
55import javax.management.MBeanInfo;
56import javax.management.MBeanNotificationInfo;
57import javax.management.MBeanOperationInfo;
58import javax.management.MBeanParameterInfo;
59import javax.management.MBeanServer;
60import javax.management.Notification;
61import javax.management.ObjectName;
62import javax.management.ReflectionException;
63 
64import junit.framework.Assert;
65 
66/** 
67 * base class for agent to be managed by jademx.
68 * if you override any of the DynamicMBean methods, then be aware that they
69 * may be called by a thread different from the one running regular behaviours
70 * and so you need to be careful about field access, deadlock, etc.
71 * TODO: make sure don't have multiple threads running unit tests.........
72 * @author David Bernstein, <a href="http://www.caboodlenetworks.com"
73 *  >Caboodle Networks, Inc.</a>
74 */
75public class JademxAgent extends Agent implements JadeJMXAgent {
76    
77    //
78    // ATTRIBUTES
79    //
80    
81    // unit testing attributes
82    
83    /** expected ACL message attribute name */
84    public static final String ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME = 
85        "UnitTestExpectedMessage";
86    /** expected ACL message attribute description */
87    private static final String ATTR_UNIT_TEST_EXPECTED_MESSAGE_DESC = 
88        "ACL message expected after inject an ACL message, as string";
89    /** expected ACL message attribute type */
90    private final static String ATTR_UNIT_TEST_EXPECTED_MESSAGE_TYPE = 
91        String.class.getName();
92 
93    
94    /** inject ACL message attribute name */
95    public static final String ATTR_UNIT_TEST_INJECT_MESSAGE_NAME = 
96        "UnitTestInjectMessage";
97    /** inject ACL message attribute description */
98    private static final String ATTR_UNIT_TEST_INJECT_MESSAGE_DESC = 
99        "ACL message to inject for unit testing, as string";
100    /** inject ACL message attribute type */
101    private final static String ATTR_UNIT_TEST_INJECT_MESSAGE_TYPE = 
102        String.class.getName();
103    
104    /** timeout attribute name */
105    public static final String ATTR_UNIT_TEST_TIMEOUT_NAME = 
106        "UnitTestTimeout";
107    /** timeout attribute description */
108    private static final String ATTR_UNIT_TEST_TIMEOUT_DESC = 
109        "timeout expressed as ISO8601 duration, e.g. PT1M";
110    /** timeout attribute type */
111    private final static String ATTR_UNIT_TEST_TIMEOUT_TYPE = 
112        String.class.getName();
113    
114    /** actual ACL message attribute name */
115    public static final String ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME = 
116        "UnitTestActualMessage";
117    /** actual ACL message attribute description */
118    private static final String ATTR_UNIT_TEST_ACTUAL_MESSAGE_DESC = 
119        "actual generated ACL message compared after inject an ACL message, as string";
120    /** actual ACL message attribute type */
121    private final static String ATTR_UNIT_TEST_ACTUAL_MESSAGE_TYPE = 
122        String.class.getName();
123    
124    // unit testing flags for governing message comparison
125    
126    /** compare content attribute name */
127    public static final String ATTR_UNIT_TEST_CMP_CONTENT_NAME = 
128        "UnitTestCmpContent";
129    /** compare content attribute description */
130    private static final String ATTR_UNIT_TEST_CMP_CONTENT_DESC = 
131        "compare content";
132    /** compare content attribute type */
133    private final static String ATTR_UNIT_TEST_CMP_CONTENT_TYPE = 
134        boolean.class.getName();
135    
136    /** compare conversation-id attribute name */
137    public static final String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME = 
138        "UnitTestCmpConversationId";
139    /** compare conversation-id attribute description */
140    private static final String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_DESC = 
141        "compare conversation-id";
142    /** compare conversation-id attribute type */
143    private final static String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_TYPE = 
144        boolean.class.getName();
145 
146    /** compare encoding attribute name */
147    public static final String ATTR_UNIT_TEST_CMP_ENCODING_NAME = 
148        "UnitTestCmpEncoding";
149    /** compare encoding attribute description */
150    private static final String ATTR_UNIT_TEST_CMP_ENCODING_DESC = 
151        "compare encoding";
152    /** compare encoding attribute type */
153    private final static String ATTR_UNIT_TEST_CMP_ENCODING_TYPE = 
154        boolean.class.getName();
155    
156    /** compare envelope attribute name */
157    public static final String ATTR_UNIT_TEST_CMP_ENVELOPE_NAME = 
158        "UnitTestCmpEnvelope";
159    /** compare envelope attribute description */
160    private static final String ATTR_UNIT_TEST_CMP_ENVELOPE_DESC = 
161        "compare envelope";
162    /** compare envelope attribute type */
163    private final static String ATTR_UNIT_TEST_CMP_ENVELOPE_TYPE = 
164        boolean.class.getName();
165    
166    /** compare in-reply-to attribute name */
167    public static final String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME = 
168        "UnitTestCmpInReplyTo";
169    /** compare in-reply-to attribute description */
170    private static final String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_DESC = 
171        "compare in-reply-to";
172    /** compare in-reply-to attribute type */
173    private final static String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_TYPE = 
174        boolean.class.getName();
175    
176    /** compare language attribute name */
177    public static final String ATTR_UNIT_TEST_CMP_LANGUAGE_NAME = 
178        "UnitTestCmpLanguage";
179    /** compare language attribute description */
180    private static final String ATTR_UNIT_TEST_CMP_LANGUAGE_DESC = 
181        "compare language";
182    /** compare language attribute type */
183    private final static String ATTR_UNIT_TEST_CMP_LANGUAGE_TYPE = 
184        boolean.class.getName();
185    
186    /** compare ontology attribute name */
187    public static final String ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME = 
188        "UnitTestCmpOntology";
189    /** compare ontology attribute description */
190    private static final String ATTR_UNIT_TEST_CMP_ONTOLOGY_DESC = 
191        "compare ontology";
192    /** compare ontology attribute type */
193    private final static String ATTR_UNIT_TEST_CMP_ONTOLOGY_TYPE = 
194        boolean.class.getName();
195    
196    /** compare performative attribute name */
197    public static final String ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME = 
198        "UnitTestCmpPerformative";
199    /** compare performative attribute description */
200    private static final String ATTR_UNIT_TEST_CMP_PERFORMATIVE_DESC = 
201        "compare performative";
202    /** compare performative attribute type */
203    private final static String ATTR_UNIT_TEST_CMP_PERFORMATIVE_TYPE = 
204        boolean.class.getName();
205    
206    /** compare protocol attribute name */
207    public static final String ATTR_UNIT_TEST_CMP_PROTOCOL_NAME = 
208        "UnitTestCmpProtocol";
209    /** compare protocol attribute description */
210    private static final String ATTR_UNIT_TEST_CMP_PROTOCOL_DESC = 
211        "compare protocol";
212    /** compare protocol attribute type */
213    private final static String ATTR_UNIT_TEST_CMP_PROTOCOL_TYPE = 
214        boolean.class.getName();
215    
216    /** compare receiver attribute name */
217    public static final String ATTR_UNIT_TEST_CMP_RECEIVER_NAME = 
218        "UnitTestCmpReceiver";
219    /** compare receiver attribute description */
220    private static final String ATTR_UNIT_TEST_CMP_RECEIVER_DESC = 
221        "compare receiver";
222    /** compare receiver attribute type */
223    private final static String ATTR_UNIT_TEST_CMP_RECEIVER_TYPE = 
224        boolean.class.getName();
225    
226    /** compare reply-by attribute name */
227    public static final String ATTR_UNIT_TEST_CMP_REPLY_BY_NAME = 
228        "UnitTestCmpReplyBy";
229    /** compare reply-by attribute description */
230    private static final String ATTR_UNIT_TEST_CMP_REPLY_BY_DESC = 
231        "compare reply-by";
232    /** compare reply-by attribute type */
233    private final static String ATTR_UNIT_TEST_CMP_REPLY_BY_TYPE = 
234        boolean.class.getName();
235    
236    /** compare reply-to attribute name */
237    public static final String ATTR_UNIT_TEST_CMP_REPLY_TO_NAME = 
238        "UnitTestCmpReplyTo";
239    /** compare reply-to attribute description */
240    private static final String ATTR_UNIT_TEST_CMP_REPLY_TO_DESC = 
241        "compare reply-to";
242    /** compare reply-to attribute type */
243    private final static String ATTR_UNIT_TEST_CMP_REPLY_TO_TYPE = 
244        boolean.class.getName();
245    
246    /** compare reply-with attribute name */
247    public static final String ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME = 
248        "UnitTestCmpReplyWith";
249    /** compare reply-with attribute description */
250    private static final String ATTR_UNIT_TEST_CMP_REPLY_WITH_DESC = 
251        "compare reply-with";
252    /** compare reply-with attribute type */
253    private final static String ATTR_UNIT_TEST_CMP_REPLY_WITH_TYPE = 
254        boolean.class.getName();
255 
256    /** compare sender attribute name */
257    public static final String ATTR_UNIT_TEST_CMP_SENDER_NAME = 
258        "UnitTestCmpSender";
259    /** compare sender attribute description */
260    private static final String ATTR_UNIT_TEST_CMP_SENDER_DESC = 
261        "compare sender";
262    /** compare sender attribute type */
263    private final static String ATTR_UNIT_TEST_CMP_SENDER_TYPE = 
264        boolean.class.getName();
265    
266    /** compare user-properties attribute name */
267    public static final String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME = 
268        "UnitTestCmpUserProperties";
269    /** compare user-properties attribute description */
270    private static final String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_DESC = 
271        "compare user-properties";
272    /** compare user-properties attribute type */
273    private final static String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_TYPE = 
274        boolean.class.getName();
275    
276    /** ignore content AID addresses attribute name */
277    public static final String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME = 
278        "UnitTestCmpIgnoreContentAIDAddresses";
279    /** ignore content AID addresses attribute description */
280    private static final String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_DESC = 
281        "ignore content AID addresses";
282    /** ignore content AID addresses attribute type */
283    private final static String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_TYPE = 
284        boolean.class.getName();
285    
286    /** newlines normalized attribute name */
287    public static final String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME = 
288        "UnitTestNewlinesNormalized";
289    /** newlines normalized attribute description */
290    private static final String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_DESC = 
291        "newlines normalized";
292    /** newlines normalized attribute type */
293    private final static String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_TYPE = 
294        boolean.class.getName();
295    
296    //
297    // OPERATIONS
298    //
299      
300    //
301    // unit testing operations
302    //
303    
304    // unitTestInjectAndExpect
305    
306    /** unitTestInjectAndExpect operation name */
307    public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME = 
308        "unitTestInjectAndExpect";
309    /** unitTestInjectAndExpect operation description */
310    private final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_DESC = 
311        "inject an ACL message to agent and notify based on expected message";
312    /** signature for a unitTestInjectAndExpect operation */
313    public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE[] = { 
314     };
315    /** return type for unitTestInjectAndExpect operation */
316    public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_TYPE = 
317        void.class.getName();
318 
319    // unitTestAddVariable
320    
321    /** addVariable operation name */
322    public final static String OPER_UNIT_TEST_ADD_VARIABLE_NAME = 
323        "unitTestAddVariable";
324    /** addVariable operation description */
325    private final static String OPER_UNIT_TEST_ADD_VARIABLE_DESC = 
326        "add a message comparison variable";
327    /** variable parameter name */
328    private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_NAME = 
329        "variable";
330    /** variable parameter type */
331    private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE = 
332        String.class.getName();
333    /** variable parameter description */
334    private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_DESC = 
335        "String expected to be different from one message to next";
336    /** type parameter name */
337    private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_NAME = 
338        "type";
339    /** type parameter type */
340    private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE = 
341        String.class.getName();
342    /** type parameter description */
343    private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_DESC = 
344        "grouping for variable, see AclMsgCmp.*_MAP";
345    /** signature for a addVariable operation */
346    public final static String OPER_UNIT_TEST_ADD_VARIABLE_SIGNATURE[] = { 
347        OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE, 
348        OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE 
349    };
350    /** return type for addVariable operation */
351    public final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE = 
352        void.class.getName();
353    
354    // unitTestClearVariables
355    
356    /** clearVariables operation name */
357    public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_NAME = 
358        "unitTestClearVariables";
359    /** clearVariables operation description */
360    private final static String OPER_UNIT_TEST_CLEAR_VARIABLES_DESC = 
361        "clear message comparison variables";
362    /** signature for a clearVariables operation */
363    public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_SIGNATURE[] = { 
364    };
365    /** return type for addVariable operation */
366    public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_TYPE = 
367        void.class.getName();
368    
369 
370 
371    
372    //
373    // NOTIFICATIONS
374    //
375    
376    
377    String NOTIF_INFO_DESCRIPTION = 
378        "notification set for " + JademxAgent.class.getName();
379    
380    // unit testing notifications
381    
382    /** notification that unit test failed */
383    public final static String NOTIF_UNIT_TEST_FAILURE_NAME =
384        "unitTestFailure";
385    /** notification that unit test succeeded */
386    public final static String NOTIF_UNIT_TEST_SUCCESS_NAME =
387        "unitTestSuccess";
388    
389//    // jademx binding notifications
390//    /** notification that jademx bound */
391//    public final static String NOTIF_JADEMX_BOUND =
392//        "jademxBound";
393    
394    //
395    // MBEAN INFO
396    //
397    
398    
399    /** local MBeanInfo exposed */
400    private MBeanInfo mBeanInfo = null;
401    /** has MBeanInfo changed since JadeAgent last saw it */
402    private Boolean mBeanInfoChanged = Boolean.FALSE;
403    /** description for MBeanInfo */
404    private final static String DESCRIPTION = 
405        "JademxAgent";
406    
407    
408    // UNIT TESTING
409    
410    /** default unit test timeout duration string */
411    private final static String DFLT_UNIT_TEST_TIMEOUT_STR = "PT1M";
412    /** test timeout duration */
413    private Duration unitTestTimeout = new Duration( DFLT_UNIT_TEST_TIMEOUT_STR );
414    /** inject message */
415    private ACLMessage unitTestInjectMessage = null;
416    /** expected message */
417    private ACLMessage unitTestExpectedMessage = null;
418    /** actual message */
419    private ACLMessage unitTestActualMessage = null;
420    /** variables */
421    private Properties unitTestVariableProperties = new Properties();
422    
423    
424    /**
425     * construct JADE agent with DynamicMBean capability via jademx.
426     */
427    public JademxAgent() {
428        super();
429        logger.log( Logger.FINER, "in JademxAgent constructor");
430    }
431 
432    /** my logger */
433    private static final Logger logger = 
434        Logger.getMyLogger(JademxAgent.class.getName());
435    
436    // attribute values/methods governing message comparison
437    
438    /** whether to compare content slots */
439    private boolean unitTestCmpContent = true;
440    
441    /**
442     * set content comparison flag (default is true)
443     * @param doCompare
444     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
445     */
446    public void setUnitTestCmpContent( boolean doCompare ) {
447        unitTestCmpContent = doCompare;
448    }
449    
450    /**
451     * get content comparison flag (default is true)
452     * @return content comparison flag
453     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
454     */
455    public boolean isUnitTestCmpContent() {
456        return unitTestCmpContent;
457    }
458    
459    /** whether to compare conversation-id slots */
460    private boolean unitTestCmpConversationId = true;
461    
462    /**
463     * set conversation-id comparison flag (default is true)
464     * @param doCompare
465     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
466     */
467    public void setUnitTestCmpConversationId( boolean doCompare ) {
468        unitTestCmpConversationId = doCompare;
469    }
470    
471    /**
472     * get conversation-id comparison flag (default is true)
473     * @return conversation-id comparison flag
474     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
475     */
476    public boolean isUnitTestCmpConversationId() {
477        return unitTestCmpConversationId;
478    }
479    
480    /** whether to compare encoding slots */
481    private boolean unitTestCmpEncoding = true;
482    
483    /**
484     * set encoding comparison flag (default is true)
485     * @param doCompare
486     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
487     */
488    public void setUnitTestCmpEncoding( boolean doCompare ) {
489        unitTestCmpEncoding = doCompare;
490    }
491    
492    /**
493     * get encoding comparison flag (default is true)
494     * @return encoding comparison flag
495     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
496     */
497    public boolean isUnitTestCmpEncoding() {
498        return unitTestCmpEncoding;
499    }
500    
501    /** whether to compare envelope slots */
502    private boolean unitTestCmpEnvelope = false;
503    
504    /**
505     * set envelope comparison flag (default is false)
506     * @param doCompare
507     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
508     */
509    public void setUnitTestCmpEnvelope( boolean doCompare ) {
510        unitTestCmpEnvelope = doCompare;
511    }
512    
513    /**
514     * get envelope comparison flag (default is false)
515     * @return envelope comparison flag
516     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
517     */
518    public boolean isUnitTestCmpEnvelope() {
519        return unitTestCmpEnvelope;
520    }
521    
522    /** whether to compare in-reply-to slots */
523    private boolean unitTestCmpInReplyTo = true;
524    
525    /**
526     * set in-reply-to comparison flag (default is true)
527     * @param doCompare
528     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
529     */
530    public void setUnitTestCmpInReplyTo( boolean doCompare ) {
531        unitTestCmpInReplyTo = doCompare;
532    }
533    
534    /**
535     * get in-reply-to comparison flag (default is true)
536     * @return in-reply-to comparison flag
537     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
538     */
539    public boolean isUnitTestCmpInReplyTo() {
540        return unitTestCmpInReplyTo;
541    }
542    
543    /** whether to compare language slots */
544    private boolean unitTestCmpLanguage = true;
545    
546    /**
547     * set language comparison flag (default is true)
548     * @param doCompare
549     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
550     */
551    public void setUnitTestCmpLanguage( boolean doCompare ) {
552        unitTestCmpLanguage = doCompare;
553    }
554    
555    /**
556     * get language comparison flag (default is true)
557     * @return language comparison flag
558     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
559     */
560    public boolean isUnitTestCmpLanguage() {
561        return unitTestCmpLanguage;
562    }
563    
564    /** whether to compare ontology slots */
565    private boolean unitTestCmpOntology = true;
566    
567    /**
568     * set ontology comparison flag (default is true)
569     * @param doCompare
570     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
571     */
572    public void setUnitTestCmpOntology( boolean doCompare ) {
573        unitTestCmpOntology = doCompare;
574    }
575    
576    /**
577     * get ontology comparison flag (default is true)
578     * @return ontology comparison flag
579     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
580     */
581    public boolean isUnitTestCmpOntology() {
582        return unitTestCmpOntology;
583    }
584    
585    /** whether to compare performative slots */
586    private boolean unitTestCmpPerformative = true;
587    
588    /**
589     * set performative comparison flag (default is true)
590     * @param doCompare
591     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
592     */
593    public void setUnitTestCmpPerformative( boolean doCompare ) {
594        unitTestCmpPerformative = doCompare;
595    }
596    
597    /**
598     * get performative comparison flag (default is true)
599     * @return performative comparison flag
600     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
601     */
602    public boolean isUnitTestCmpPerformative() {
603        return unitTestCmpPerformative;
604    }
605    
606    /** whether to compare protocol slots */
607    private boolean unitTestCmpProtocol = true;
608    
609    /**
610     * set protocol comparison flag (default is true)
611     * @param doCompare
612     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
613     */
614    public void setUnitTestCmpProtocol( boolean doCompare ) {
615        unitTestCmpProtocol = doCompare;
616    }
617    
618    /**
619     * get protocol comparison flag (default is true)
620     * @return protocol comparison flag
621     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
622     */
623    public boolean isUnitTestCmpProtocol() {
624        return unitTestCmpProtocol;
625    }
626    
627    /** whether to compare receiver slots */
628    private boolean unitTestCmpReceiver = true;
629    
630    /**
631     * set receiver comparison flag (default is true)
632     * @param doCompare
633     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
634     */
635    public void setUnitTestCmpReceiver( boolean doCompare ) {
636        unitTestCmpReceiver = doCompare;
637    }
638    
639    /**
640     * get receiver comparison flag (default is true)
641     * @return receiver comparison flag
642     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
643     */
644    public boolean isUnitTestCmpReceiver() {
645        return unitTestCmpReceiver;
646    }
647    
648    /** whether to compare reply-by slots */
649    private boolean unitTestCmpReplyBy = true;
650    
651    /**
652     * set reply-by comparison flag (default is true)
653     * @param doCompare
654     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
655     */
656    public void setUnitTestCmpReplyBy( boolean doCompare ) {
657        unitTestCmpReplyBy = doCompare;
658    }
659    
660    /**
661     * get reply-by comparison flag (default is true)
662     * @return reply-by comparison flag
663     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
664     */
665    public boolean isUnitTestCmpReplyBy() {
666        return unitTestCmpReplyBy;
667    }
668    
669    /** whether to compare reply-to slots */
670    private boolean unitTestCmpReplyTo = true;
671    
672    /**
673     * set reply-to comparison flag (default is true)
674     * @param doCompare
675     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
676     */
677    public void setUnitTestCmpReplyTo( boolean doCompare ) {
678        unitTestCmpReplyTo = doCompare;
679    }
680    
681    /**
682     * get reply-to comparison flag (default is true)
683     * @return reply-to comparison flag
684     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
685     */
686    public boolean isUnitTestCmpReplyTo() {
687        return unitTestCmpReplyTo;
688    }
689    
690    /** whether to compare reply-with slots */
691    private boolean unitTestCmpReplyWith = true;
692    
693    /**
694     * set reply-with comparison flag (default is true)
695     * @param doCompare
696     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
697     */
698    public void setUnitTestCmpReplyWith( boolean doCompare ) {
699        unitTestCmpReplyWith = doCompare;
700    }
701    
702    /**
703     * get reply-with comparison flag (default is true)
704     * @return reply-with comparison flag
705     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
706     */
707    public boolean isUnitTestCmpReplyWith() {
708        return unitTestCmpReplyWith;
709    }
710    
711    /** whether to compare sender slots */
712    private boolean unitTestCmpSender = true;
713    
714    /**
715     * set sender comparison flag (default is true)
716     * @param doCompare
717     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
718     */
719    public void setUnitTestCmpSender( boolean doCompare ) {
720        unitTestCmpSender = doCompare;
721    }
722    
723    /**
724     * get sender comparison flag (default is true)
725     * @return sender comparison flag
726     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
727     */
728    public boolean isUnitTestCmpSender() {
729        return unitTestCmpSender;
730    }
731    
732    /** whether to compare user properties slots */
733    private boolean unitTestCmpUserProperties = true;
734    
735    /**
736     * set user properties comparison flag (default is true)
737     * @param doCompare
738     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
739     */
740    public void setUnitTestCmpUserProperties( boolean doCompare ) {
741        unitTestCmpUserProperties = doCompare;
742    }
743    
744    /**
745     * get user properties comparison flag (default is true)
746     * @return user properties comparison flag
747     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
748     */
749    public boolean isUnitTestCmpUserProperties() {
750        return unitTestCmpUserProperties;
751    }
752    
753    /** 
754     * whether to ignore :addresses inside agent-identifier in content.
755     * N.B.: no effect if content is byte sequence instead of string.
756     */
757    private boolean unitTestIgnoreContentAIDAddresses = true;
758    
759    /**
760     * set content AID address ignoring flag (default is true)
761     * @param ignore
762     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
763     */
764    public void setUnitTestIgnoreContentAIDAddresses( boolean ignore ) {
765        unitTestIgnoreContentAIDAddresses = ignore;
766    }
767    
768    /**
769     * get content AID address ignoring flag (default is true)
770     * @return content AID address ignoring
771     * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage )
772     */
773    public boolean isUnitTestIgnoreContentAIDAddresses() {
774        return unitTestIgnoreContentAIDAddresses;
775    }
776    
777    /** whether to normalize newlines */
778    private boolean unitTestNewlinesNormalized = true;
779    
780    /**
781     * set newline normalization flag (default is true)
782     * @param normalize
783     * @see jade.jademx.util.AclMsgCmp#setNewlinesNormalized
784     */
785    public void setUnitTestNewlinesNormalized( boolean normalize ) {
786        unitTestNewlinesNormalized = normalize;
787    }
788    
789    /**
790     * get newline normalization flag (default is true)
791     * @return newline normalization flag
792     * @see jade.jademx.util.AclMsgCmp#isNewlinesNormalized
793     */
794    public boolean isUnitTestNewlinesNormalized() {
795        return unitTestNewlinesNormalized;
796    }
797    
798    //    /**
799    //     * convenience method to write all system properties to log
800    //     * @param l logger to use
801    //     * @param s some message to prepend log message with
802    //     */
803    //    public static void logSysProps( Logger l, String s ) {
804    //        java.util.Properties p = System.getProperties();
805    //        java.io.StringWriter sw = new java.io.StringWriter();
806    //        java.io.PrintWriter pw = new java.io.PrintWriter( sw );
807    //        p.list( pw );
808    //        l.log( Logger.INFO, "system properties "+s+":\n"+sw);
809    //    }
810    
811    // SETUP/TAKEDOWN
812 
813    /**
814     * get ready after initialization but before running behaviours.
815     * subclasses must make sure to call this method if they expect to
816     * expose control as a DynamicMBean.
817     */
818    protected void setup() {
819        
820        logger.log( Logger.FINE, "entering JademxAgent.setup() for "+getName()+
821                " in platform "+getContainerController().getPlatformName() );
822        
823        // register languages and ontologies used by UnitTestBehaviour
824        
825        getContentManager().registerOntology( 
826                FIPAManagementOntology.getInstance() );
827        getContentManager().registerOntology( 
828                JADEManagementOntology.getInstance() );
829        getContentManager().registerOntology( 
830                IntrospectionOntology.getInstance()  );
831        
832        SLCodec slCodec = new SLCodec();
833        getContentManager().registerLanguage( 
834                slCodec, FIPANames.ContentLanguage.FIPA_SL  );
835        getContentManager().registerLanguage( 
836                slCodec, FIPANames.ContentLanguage.FIPA_SL0 );
837        getContentManager().registerLanguage( 
838                slCodec, FIPANames.ContentLanguage.FIPA_SL1 );
839        getContentManager().registerLanguage( 
840                slCodec, FIPANames.ContentLanguage.FIPA_SL2 );
841        
842        // get self talking to jademx system if available
843        
844        String jadeMXServerClassName = 
845            System.getProperty(JadeMXServerFactory.SERVER_TYPE_PROPERTY);
846        String runtimeMBeanName = 
847            System.getProperty(JadeRuntimeMBean.MBEAN_SYS_PROP_NAME); 
848        JadeMXServer jadeMXServer = null;
849        String platformName = null;
850        if ( ( null != jadeMXServerClassName ) && ( null != runtimeMBeanName )){
851            try {
852                jadeMXServer = JadeMXServerFactory.jadeMXServerBySysProp();
853            }
854            catch ( Exception e ) {
855                logger.log( Logger.WARNING, 
856                   "unable to instantiate JadeMXServer from system property \""
857                   +JadeMXServerFactory.SERVER_TYPE_PROPERTY+"\"=\""+
858                   System.getProperty(JadeMXServerFactory.SERVER_TYPE_PROPERTY)+
859                   "\"", e );
860            }
861            logger.log( Logger.FINE, "JadeMXServer:"+jadeMXServer);
862            if ( null != jadeMXServer ) {
863                MBeanServer mBeanServer = jadeMXServer.getMBeanServer();
864                platformName = getContainerController().getPlatformName();
865                ObjectName runtimeON = null;
866                try {
867                    runtimeON = new ObjectName( runtimeMBeanName );
868                }
869                catch ( Exception e ) {
870                    logger.log( Logger.WARNING,
871                            "unable to create ObjectName for \""+
872                            runtimeMBeanName + "\"", e );
873                }
874                JadePlatform jadePlatform = null;
875                logger.log( Logger.FINE, "JadeRuntime ObjectName: "+runtimeON);
876                if ( null != runtimeON ) {
877                    try {
878                        jadePlatform = (JadePlatform)mBeanServer.invoke( 
879                                runtimeON, 
880                                JadeRuntimeMBean.OPER_PLATFORM_FROM_JADE_NAME, 
881                                new Object[] { platformName }, 
882                                JadeRuntime.SIGN_STR );
883                    }
884                    catch ( Exception e ) {
885                        logger.log( Logger.WARNING,
886                                "unable to get JadePlatform for \""+
887                                platformName + "\"", e );
888                    }
889                    logger.log( Logger.FINE, "JadePlatform:"+jadePlatform);
890                    if ( null != jadePlatform ) {
891                        JadeAgent jadeAgent = null;
892                        try {
893                            jadeAgent = jadePlatform.getAgent(  getLocalName() );
894                        }
895                        catch (JademxException e ) {
896                            logger.log( Logger.WARNING,
897                                    "unable to get JadeAgent for"+
898                                    " agent with local name \""+
899                                    getLocalName() + "\"", e );
900                        }
901                        logger.log( Logger.FINE, "JadeAgent:"+jadeAgent);
902                        if ( null != jadeAgent ) {
903                            // finally: exchange references
904                            setJadeAgent( jadeAgent );
905                            changedMBeanInfo();
906                        }
907                    }
908                }
909            }
910        }
911        
912//        // AID not known during construction, but known now.
913//        // this method is called by jademx calling the agent controller's
914//        // start method. put my name out as a system property so that jademx
915//        // can know that this agent exposes management via JMX.
916//        // if controlled by jademx, then this property will be read and cleared.
917//        // after reading this property, then jademx will pass a reference to
918//        // itself through the O2A queue.  create a threaded behaviour that
919//        // will wait for that object, and then when it's available, register
920//        // this agent with jademx as exposing JMX DynamicMBean interfaces.
921//        // a threaded behaviour is used in an attempt to decouple this agent's
922//        // intended activity from its JMX activity
923//        String jademxAgentSysProp = jademxSysProp( getLocalName() );
924//        setEnabledO2ACommunication( true, 1 );
925//        System.setProperty( jademxAgentSysProp, JADEMX_AGENT_SYSPROP_VALUE );
926//        addBehaviour( new JademxRegistrationBehaviour( this ) );
927//        //logSysProps( logger, "after JademxAgent.setup() for "+getName());
928    }
929    
930//    /** is the agent shutting down: volatile due to multithread access */ 
931//    private boolean shuttingDown = false;
932//    
933//    /**
934//     * is the agent shutting down
935//     * @return whether agent shutting down
936//     */
937//    public boolean isShuttingDown() {
938//        return shuttingDown;
939//    }
940//    
941//    /**
942//     * clean agent shutdown.
943//     * subclasses must make sure to call this method if they have called the
944//     * corresponding setup() method.
945//     */
946//    protected void takeDown() {
947//        shuttingDown = true;
948//    }
949    
950    // BEGIN DynamicMBean IMPLEMENTATION
951    
952    /** the JadeAgent for this agent - volatile due to multithread access */
953    private volatile JadeAgent jadeAgent = null;
954    
955    /**
956     * set the JademxAgent for this agent
957     * @param jadeAgent this agent's JadeAgent
958     */
959    void setJadeAgent( JadeAgent jadeAgent ) {
960        this.jadeAgent = jadeAgent;
961        changedMBeanInfo();
962    }
963 
964    /**
965     * notify listeners - message and userData can be null.
966     * sets source, sequence number, timestamp automatically.
967     * NOP if no JadeAgent has been set.
968     * @param type notification type
969     * @param message notification message
970     * @param userData user data
971     */
972    public void notifyListeners( 
973            String type, String message, Object userData ) {
974        if ( null != jadeAgent ) {
975            jadeAgent.notifyListeners( type, message, userData );
976        }
977    }
978    
979    /**
980     * create a new MBeanInfo object to describe this agent.
981     * @return new MBeanInfo object to describe this agent.
982     */
983    private MBeanInfo constructMBeanInfo() {
984        
985        // attributes
986 
987        MBeanAttributeInfo aI[] = new MBeanAttributeInfo[] {
988                new MBeanAttributeInfo( 
989                        ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME, 
990                        ATTR_UNIT_TEST_EXPECTED_MESSAGE_TYPE, 
991                        ATTR_UNIT_TEST_EXPECTED_MESSAGE_DESC,
992                        true, true, false ),
993                new MBeanAttributeInfo( 
994                        ATTR_UNIT_TEST_INJECT_MESSAGE_NAME, 
995                        ATTR_UNIT_TEST_INJECT_MESSAGE_TYPE, 
996                        ATTR_UNIT_TEST_INJECT_MESSAGE_DESC,
997                        true, true, false ),
998                new MBeanAttributeInfo( 
999                        ATTR_UNIT_TEST_TIMEOUT_NAME, 
1000                        ATTR_UNIT_TEST_TIMEOUT_TYPE, 
1001                        ATTR_UNIT_TEST_TIMEOUT_DESC,
1002                        true, true, false ),
1003                new MBeanAttributeInfo( 
1004                        ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME, 
1005                        ATTR_UNIT_TEST_ACTUAL_MESSAGE_TYPE, 
1006                        ATTR_UNIT_TEST_ACTUAL_MESSAGE_DESC,
1007                        true, false, false ),                        
1008                new MBeanAttributeInfo( 
1009                        ATTR_UNIT_TEST_CMP_CONTENT_NAME, 
1010                        ATTR_UNIT_TEST_CMP_CONTENT_TYPE, 
1011                        ATTR_UNIT_TEST_CMP_CONTENT_DESC,
1012                        true, true, true ),
1013                new MBeanAttributeInfo( 
1014                        ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME, 
1015                        ATTR_UNIT_TEST_CMP_CONVERSATION_ID_TYPE, 
1016                        ATTR_UNIT_TEST_CMP_CONVERSATION_ID_DESC,
1017                        true, true, true ),
1018                new MBeanAttributeInfo( 
1019                        ATTR_UNIT_TEST_CMP_ENCODING_NAME, 
1020                        ATTR_UNIT_TEST_CMP_ENCODING_TYPE, 
1021                        ATTR_UNIT_TEST_CMP_ENCODING_DESC,
1022                        true, true, true ),
1023                new MBeanAttributeInfo( 
1024                        ATTR_UNIT_TEST_CMP_ENVELOPE_NAME, 
1025                        ATTR_UNIT_TEST_CMP_ENVELOPE_TYPE, 
1026                        ATTR_UNIT_TEST_CMP_ENVELOPE_DESC,
1027                        true, true, true ),
1028                new MBeanAttributeInfo( 
1029                        ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME, 
1030                        ATTR_UNIT_TEST_CMP_IN_REPLY_TO_TYPE, 
1031                        ATTR_UNIT_TEST_CMP_IN_REPLY_TO_DESC,
1032                        true, true, true ),
1033                new MBeanAttributeInfo( 
1034                        ATTR_UNIT_TEST_CMP_LANGUAGE_NAME, 
1035                        ATTR_UNIT_TEST_CMP_LANGUAGE_TYPE, 
1036                        ATTR_UNIT_TEST_CMP_LANGUAGE_DESC,
1037                        true, true, true ),
1038                new MBeanAttributeInfo( 
1039                        ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME, 
1040                        ATTR_UNIT_TEST_CMP_ONTOLOGY_TYPE, 
1041                        ATTR_UNIT_TEST_CMP_ONTOLOGY_DESC,
1042                        true, true, true ),
1043                new MBeanAttributeInfo( 
1044                        ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME, 
1045                        ATTR_UNIT_TEST_CMP_PERFORMATIVE_TYPE, 
1046                        ATTR_UNIT_TEST_CMP_PERFORMATIVE_DESC,
1047                        true, true, true ),
1048                new MBeanAttributeInfo( 
1049                        ATTR_UNIT_TEST_CMP_PROTOCOL_NAME, 
1050                        ATTR_UNIT_TEST_CMP_PROTOCOL_TYPE, 
1051                        ATTR_UNIT_TEST_CMP_PROTOCOL_DESC,
1052                        true, true, true ),
1053                new MBeanAttributeInfo( 
1054                        ATTR_UNIT_TEST_CMP_RECEIVER_NAME, 
1055                        ATTR_UNIT_TEST_CMP_RECEIVER_TYPE, 
1056                        ATTR_UNIT_TEST_CMP_RECEIVER_DESC,
1057                        true, true, true ),
1058                new MBeanAttributeInfo( 
1059                        ATTR_UNIT_TEST_CMP_REPLY_BY_NAME, 
1060                        ATTR_UNIT_TEST_CMP_REPLY_BY_TYPE, 
1061                        ATTR_UNIT_TEST_CMP_REPLY_BY_DESC,
1062                        true, true, true ),
1063                new MBeanAttributeInfo( 
1064                        ATTR_UNIT_TEST_CMP_REPLY_TO_NAME, 
1065                        ATTR_UNIT_TEST_CMP_REPLY_TO_TYPE, 
1066                        ATTR_UNIT_TEST_CMP_REPLY_TO_DESC,
1067                        true, true, true ),
1068                new MBeanAttributeInfo( 
1069                        ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME, 
1070                        ATTR_UNIT_TEST_CMP_REPLY_WITH_TYPE, 
1071                        ATTR_UNIT_TEST_CMP_REPLY_WITH_DESC,
1072                        true, true, true ),
1073                new MBeanAttributeInfo( 
1074                        ATTR_UNIT_TEST_CMP_SENDER_NAME, 
1075                        ATTR_UNIT_TEST_CMP_SENDER_TYPE, 
1076                        ATTR_UNIT_TEST_CMP_SENDER_DESC,
1077                        true, true, true ),
1078                new MBeanAttributeInfo( 
1079                        ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME, 
1080                        ATTR_UNIT_TEST_CMP_USER_PROPERTIES_TYPE, 
1081                        ATTR_UNIT_TEST_CMP_USER_PROPERTIES_DESC,
1082                        true, true, true ),
1083                new MBeanAttributeInfo( 
1084                        ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME, 
1085                        ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_TYPE, 
1086                        ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_DESC,
1087                        true, true, true ),
1088                new MBeanAttributeInfo( 
1089                        ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME, 
1090                        ATTR_UNIT_TEST_NEWLINES_NORMALIZED_TYPE, 
1091                        ATTR_UNIT_TEST_NEWLINES_NORMALIZED_DESC,
1092                        true, true, true )
1093        };
1094        
1095        // constructors
1096 
1097        MBeanConstructorInfo cI[] = new MBeanConstructorInfo[0];
1098        
1099        // operations
1100 
1101        MBeanParameterInfo pIInject[] = { 
1102        };
1103        MBeanParameterInfo pIAddVariable[] = { 
1104                new MBeanParameterInfo( 
1105                        OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_NAME, 
1106                        OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE, 
1107                        OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_DESC), 
1108                new MBeanParameterInfo( 
1109                        OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_NAME, 
1110                        OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE, 
1111                        OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_DESC) 
1112        };
1113        MBeanParameterInfo pIClearVariables[] = { 
1114        };
1115        MBeanOperationInfo oI[] = new MBeanOperationInfo[] {
1116                new MBeanOperationInfo( 
1117                        OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, 
1118                        OPER_UNIT_TEST_INJECT_AND_EXPECT_DESC, 
1119                        pIInject, 
1120                        OPER_UNIT_TEST_INJECT_AND_EXPECT_TYPE, 
1121                        MBeanOperationInfo.ACTION ),
1122                new MBeanOperationInfo( 
1123                        OPER_UNIT_TEST_ADD_VARIABLE_NAME, 
1124                        OPER_UNIT_TEST_ADD_VARIABLE_DESC, 
1125                        pIAddVariable, 
1126                        OPER_UNIT_TEST_ADD_VARIABLE_TYPE, 
1127                        MBeanOperationInfo.ACTION ),
1128                new MBeanOperationInfo( 
1129                        OPER_UNIT_TEST_CLEAR_VARIABLES_NAME, 
1130                        OPER_UNIT_TEST_CLEAR_VARIABLES_DESC, 
1131                        pIClearVariables, 
1132                        OPER_UNIT_TEST_CLEAR_VARIABLES_TYPE, 
1133                        MBeanOperationInfo.ACTION )
1134        };
1135        
1136        // notifications
1137        
1138        String notifications[] = {
1139                NOTIF_UNIT_TEST_FAILURE_NAME, 
1140                NOTIF_UNIT_TEST_SUCCESS_NAME 
1141        };
1142        String myClassName = getClass().getName();
1143        String NOTIF_INFO_DESCRIPTION = 
1144            "notification set for " + myClassName;
1145        MBeanNotificationInfo nI[] = new MBeanNotificationInfo[] {
1146                new MBeanNotificationInfo(
1147                        notifications,
1148                        Notification.class.getName(),
1149                        NOTIF_INFO_DESCRIPTION )
1150        };
1151        
1152        // now, MBeanInfo for this level of class hierarchy
1153        MBeanInfo mBeanInfo = new MBeanInfo( myClassName, 
1154                DESCRIPTION,
1155                aI, cI, oI, nI );
1156        
1157        return mBeanInfo;
1158        
1159    }
1160 
1161    
1162//    /**
1163//     * has MBeanInfo changed since last checked
1164//     * @return whether MBeanInfo has changed since last checked
1165//     */
1166//    public boolean isMBeanInfoChanged() {
1167//        boolean infoChanged;
1168//        synchronized ( mBeanInfoChanged ) {
1169//            infoChanged = mBeanInfoChanged.booleanValue();
1170//        }
1171//        return infoChanged;
1172//    }
1173    
1174    /**
1175     * mark this agent's MBeanInfo as having been changed.
1176     */
1177    protected void changedMBeanInfo() {
1178        synchronized ( mBeanInfoChanged ) {
1179            mBeanInfoChanged = Boolean.TRUE;
1180            //mBeanInfo = null;
1181            if ( null != jadeAgent ) {
1182                logger.log( Logger.FINE, 
1183                        "calling JadeAgent.setJademxAgent(),JadeAgent="+
1184                        jadeAgent+",JadeAgent.hashCode()="+jadeAgent.hashCode()+
1185                        ",jademxAgent="+this+",jademxAgent.hashCode()="+
1186                        this.hashCode());
1187                jadeAgent.setJademxAgent( this );
1188            }
1189            else {
1190                logger.log( Logger.WARNING, "jadeAgent is null so can't "+
1191                        "inform it about changed MBeanInfo");
1192            }
1193        }
1194    }
1195    
1196    /** 
1197     * set MBeanInfo for JADE side of this agent (excluding jademx).
1198     * @deprecated subclasses should call MBeanUtil.mergeMBeanInfo()
1199     *  on their own MBeanInfo and MBeanInfo obtained for this class
1200     *  by super.getMBeanInfo() and return the merged MBeanInfo.
1201     */
1202    protected void setMBeanInfo( MBeanInfo mBeanInfo ) {
1203        throw new RuntimeException(
1204                "JademxAgent.setMBeanInfo() is deprecated, "+
1205                "agents should call super.getMBeanInfo() to get "+
1206                "MBeanInfo for JademxAgent and then call "+
1207                "MBeanUtil.mergeMBeanInfo() to get an MBeanInfo "+
1208                "representing MBean capabilities for entire JADE side "+
1209                "of agent.  Whenever an agent has changed its own level "+
1210                "MBean information, it should call "+
1211                "JademxAgent.changedMBeanInfo().");
1212    }
1213    
1214    /**
1215     * override this method to do anything meaningful as DynamicMBean.
1216     * this is a merge of the agent, this class, and this class's superclass.
1217     * @return MBean information for base JADE MBean class
1218     */
1219    public MBeanInfo getMBeanInfo() {
1220        synchronized ( mBeanInfoChanged ) {
1221            // lazy evaluation
1222            if ( null == mBeanInfo ) {
1223                mBeanInfo = constructMBeanInfo();
1224                mBeanInfoChanged = Boolean.FALSE;
1225                logger.log(Logger.FINE,"made MBeanInfo "+mBeanInfo);
1226            }
1227        }
1228        logger.log(Logger.FINE,"returning MBeanInfo "+mBeanInfo+"...");
1229        return mBeanInfo;
1230    }
1231 
1232 
1233    /**
1234     * get an attribute value: <em>override this method to have an attribute</em>.
1235     * @param attribute name of attribute to get
1236     * @return attribute value
1237     * @throws AttributeNotFoundException no such attribute
1238     * @throws MBeanException exception from getter
1239     * @throws ReflectionException exception invoking getter
1240     */
1241    public Object getAttribute( String attribute ) 
1242      throws AttributeNotFoundException,
1243             MBeanException, 
1244             ReflectionException {
1245        Object o;
1246        if ( ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME.equals( attribute ) ) {
1247            o = getUnitTestExpectedMessage();
1248        }
1249        else if ( ATTR_UNIT_TEST_INJECT_MESSAGE_NAME.equals( attribute ) ) {
1250            o = getUnitTestInjectMessage();
1251        }
1252        else if ( ATTR_UNIT_TEST_TIMEOUT_NAME.equals( attribute ) ) {
1253            o = getUnitTestTimeout();
1254        }
1255        else if ( ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME.equals( attribute ) ) {
1256            o = getUnitTestActualMessage();
1257        }        
1258        else if ( ATTR_UNIT_TEST_CMP_CONTENT_NAME.equals( attribute ) ) {
1259            o = new Boolean( isUnitTestCmpContent() );
1260        }
1261        else if ( ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME.equals( attribute ) ) {
1262            o = new Boolean( isUnitTestCmpConversationId() );
1263        }
1264        else if ( ATTR_UNIT_TEST_CMP_ENCODING_NAME.equals( attribute ) ) {
1265            o = new Boolean( isUnitTestCmpEncoding() );
1266        }
1267        else if ( ATTR_UNIT_TEST_CMP_ENVELOPE_NAME.equals( attribute ) ) {
1268            o = new Boolean( isUnitTestCmpEnvelope() );
1269        }
1270        else if ( ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME.equals( attribute ) ) {
1271            o = new Boolean( isUnitTestCmpInReplyTo() );
1272        }
1273        else if ( ATTR_UNIT_TEST_CMP_LANGUAGE_NAME.equals( attribute ) ) {
1274            o = new Boolean( isUnitTestCmpLanguage() );
1275        }
1276        else if ( ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME.equals( attribute ) ) {
1277            o = new Boolean( isUnitTestCmpOntology() );
1278        }
1279        else if ( ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME.equals( attribute ) ) {
1280            o = new Boolean( isUnitTestCmpPerformative() );
1281        }
1282        else if ( ATTR_UNIT_TEST_CMP_PROTOCOL_NAME.equals( attribute ) ) {
1283            o = new Boolean( isUnitTestCmpProtocol() );
1284        }
1285        else if ( ATTR_UNIT_TEST_CMP_RECEIVER_NAME.equals( attribute ) ) {
1286            o = new Boolean( isUnitTestCmpReceiver() );
1287        }
1288        else if ( ATTR_UNIT_TEST_CMP_REPLY_BY_NAME.equals( attribute ) ) {
1289            o = new Boolean( isUnitTestCmpReplyBy() );
1290        }
1291        else if ( ATTR_UNIT_TEST_CMP_REPLY_TO_NAME.equals( attribute ) ) {
1292            o = new Boolean( isUnitTestCmpReplyTo() );
1293        }
1294        else if ( ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME.equals( attribute ) ) {
1295            o = new Boolean( isUnitTestCmpReplyWith() );
1296        }
1297        else if ( ATTR_UNIT_TEST_CMP_SENDER_NAME.equals( attribute ) ) {
1298            o = new Boolean( isUnitTestCmpSender() );
1299        }
1300        else if ( ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME.equals( attribute ) ) {
1301            o = new Boolean( isUnitTestCmpUserProperties() );
1302        }
1303        else if ( ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME.equals( attribute ) ) {
1304            o = new Boolean( isUnitTestIgnoreContentAIDAddresses() );
1305        }
1306        else if ( ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME.equals( attribute ) ) {
1307            o = new Boolean( isUnitTestNewlinesNormalized() );
1308        }
1309        else {
1310            // no parent class to try, subclasses had first crack
1311            throw new AttributeNotFoundException(
1312                    "no such readable attribute \""+attribute+"\"");
1313        }
1314        return o;
1315    }
1316    
1317    /**
1318     * get multiple attribute values
1319     * @param attributes attributes to be retrieved
1320     * @return retrieved attributes 
1321     */
1322    public AttributeList getAttributes(String[] attributes) {
1323        AttributeList aL = null;
1324        int attrCount = attributes.length;
1325        if ( attrCount >= 0 ) {
1326            aL = new AttributeList( attrCount );
1327            for ( int i = 0; i < attrCount; i++ ) {
1328                try {
1329                    aL.add( getAttribute( attributes[i] ) );
1330                }
1331                catch ( Exception e ) {
1332                    throw new RuntimeException( e );
1333                }
1334            }
1335        }
1336        return aL;
1337    }
1338    
1339    /**
1340     * set an attribute
1341     * @param attribute
1342     * @throws AttributeNotFoundException
1343     * @throws InvalidAttributeValueException
1344     * @throws MBeanException
1345     * @throws ReflectionException
1346     */
1347    public void setAttribute( Attribute attribute )
1348      throws AttributeNotFoundException,
1349             InvalidAttributeValueException,
1350             MBeanException,
1351             ReflectionException {
1352        
1353        String n = attribute.getName();
1354        Object v = attribute.getValue();
1355//        System.err.println("attribute name:"+n);
1356//        System.err.println("expected msg attribute name:"+ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME);
1357//        System.err.println("inject msg attribute name:"+ATTR_UNIT_TEST_INJECT_MESSAGE_NAME);
1358//        System.err.println("timeout attribute name:"+ATTR_UNIT_TEST_TIMEOUT_NAME);
1359        if ( ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME.equals( n ) ) {
1360            String s;
1361            try {
1362                s = (String) v;
1363            }
1364            catch ( ClassCastException cce ){
1365                throw new InvalidAttributeValueException( "for attribute "+
1366                        " need "+String.class.getName()+" got "+
1367                        v.getClass().getName() );
1368            }
1369            try {
1370                setUnitTestExpectedMessage( s );
1371                // invoking directly, not indirectly, 
1372                // so can't throw ReflectionException
1373            }
1374            catch ( Exception e ) {
1375                throw new MBeanException( e,
1376                        "exception setting "+n+" attribute" );
1377            }
1378        }
1379        else if ( ATTR_UNIT_TEST_INJECT_MESSAGE_NAME.equals( n ) ) {
1380            String s;
1381            try {
1382                s = (String) v;
1383            }
1384            catch ( ClassCastException cce ){
1385                throw new InvalidAttributeValueException( "for attribute "+
1386                        " need "+String.class.getName()+" got "+
1387                        v.getClass().getName() );
1388            }
1389            try {
1390                setUnitTestInjectMessage( s );
1391                // invoking directly, not indirectly, 
1392                // so can't throw ReflectionException
1393            }
1394            catch ( Exception e ) {
1395                throw new MBeanException( e,
1396                        "exception setting "+n+" attribute" );
1397            }
1398        }
1399        else if ( ATTR_UNIT_TEST_TIMEOUT_NAME.equals( n ) ) {
1400            String s;
1401            try {
1402                s = (String) v;
1403            }
1404            catch ( ClassCastException cce ){
1405                throw new InvalidAttributeValueException( "for attribute "+
1406                        " need "+String.class.getName()+" got "+
1407                        v.getClass().getName() );
1408            }
1409            try {
1410                setUnitTestTimeout( s );
1411                // invoking directly, not indirectly, 
1412                // so can't throw ReflectionException
1413            }
1414            catch ( Exception e ) {
1415                throw new MBeanException( e,
1416                        "exception setting "+n+" attribute" );
1417            }
1418        }
1419        else if ( ATTR_UNIT_TEST_CMP_CONTENT_NAME.equals( n ) ) {
1420            boolean b;
1421            try {
1422                b = ((Boolean)v).booleanValue();
1423            }
1424            catch ( ClassCastException cce ){
1425                throw new InvalidAttributeValueException( "for attribute "+
1426                        " need "+Boolean.class.getName()+" got "+
1427                        v.getClass().getName() );
1428            }
1429            try {
1430                setUnitTestCmpContent( b );
1431                // invoking directly, not indirectly, 
1432                // so can't throw ReflectionException
1433            }
1434            catch ( Exception e ) {
1435                throw new MBeanException( e,
1436                        "exception setting "+n+" attribute" );
1437            }
1438        }
1439        else if ( ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME.equals( n ) ) {
1440            boolean b;
1441            try {
1442                b = ((Boolean)v).booleanValue();
1443            }
1444            catch ( ClassCastException cce ){
1445                throw new InvalidAttributeValueException( "for attribute "+
1446                        " need "+Boolean.class.getName()+" got "+
1447                        v.getClass().getName() );
1448            }
1449            try {
1450                setUnitTestCmpConversationId( b );
1451                // invoking directly, not indirectly, 
1452                // so can't throw ReflectionException
1453            }
1454            catch ( Exception e ) {
1455                throw new MBeanException( e,
1456                        "exception setting "+n+" attribute" );
1457            }
1458        }
1459        else if ( ATTR_UNIT_TEST_CMP_ENCODING_NAME.equals( n ) ) {
1460            boolean b;
1461            try {
1462                b = ((Boolean)v).booleanValue();
1463            }
1464            catch ( ClassCastException cce ){
1465                throw new InvalidAttributeValueException( "for attribute "+
1466                        " need "+Boolean.class.getName()+" got "+
1467                        v.getClass().getName() );
1468            }
1469            try {
1470                setUnitTestCmpEncoding( b );
1471                // invoking directly, not indirectly, 
1472                // so can't throw ReflectionException
1473            }
1474            catch ( Exception e ) {
1475                throw new MBeanException( e,
1476                        "exception setting "+n+" attribute" );
1477            }
1478        }
1479        else if ( ATTR_UNIT_TEST_CMP_ENVELOPE_NAME.equals( n ) ) {
1480            boolean b;
1481            try {
1482                b = ((Boolean)v).booleanValue();
1483            }
1484            catch ( ClassCastException cce ){
1485                throw new InvalidAttributeValueException( "for attribute "+
1486                        " need "+Boolean.class.getName()+" got "+
1487                        v.getClass().getName() );
1488            }
1489            try {
1490                setUnitTestCmpEnvelope( b );
1491                // invoking directly, not indirectly, 
1492                // so can't throw ReflectionException
1493            }
1494            catch ( Exception e ) {
1495                throw new MBeanException( e,
1496                        "exception setting "+n+" attribute" );
1497            }
1498        }
1499        else if ( ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME.equals( n ) ) {
1500            boolean b;
1501            try {
1502                b = ((Boolean)v).booleanValue();
1503            }
1504            catch ( ClassCastException cce ){
1505                throw new InvalidAttributeValueException( "for attribute "+
1506                        " need "+Boolean.class.getName()+" got "+
1507                        v.getClass().getName() );
1508            }
1509            try {
1510                setUnitTestCmpInReplyTo( b );
1511                // invoking directly, not indirectly, 
1512                // so can't throw ReflectionException
1513            }
1514            catch ( Exception e ) {
1515                throw new MBeanException( e,
1516                        "exception setting "+n+" attribute" );
1517            }
1518        }
1519        else if ( ATTR_UNIT_TEST_CMP_LANGUAGE_NAME.equals( n ) ) {
1520            boolean b;
1521            try {
1522                b = ((Boolean)v).booleanValue();
1523            }
1524            catch ( ClassCastException cce ){
1525                throw new InvalidAttributeValueException( "for attribute "+
1526                        " need "+Boolean.class.getName()+" got "+
1527                        v.getClass().getName() );
1528            }
1529            try {
1530                setUnitTestCmpLanguage( b );
1531                // invoking directly, not indirectly, 
1532                // so can't throw ReflectionException
1533            }
1534            catch ( Exception e ) {
1535                throw new MBeanException( e,
1536                        "exception setting "+n+" attribute" );
1537            }
1538        }
1539        else if ( ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME.equals( n ) ) {
1540            boolean b;
1541            try {
1542                b = ((Boolean)v).booleanValue();
1543            }
1544            catch ( ClassCastException cce ){
1545                throw new InvalidAttributeValueException( "for attribute "+
1546                        " need "+Boolean.class.getName()+" got "+
1547                        v.getClass().getName() );
1548            }
1549            try {
1550                setUnitTestCmpOntology( b );
1551                // invoking directly, not indirectly, 
1552                // so can't throw ReflectionException
1553            }
1554            catch ( Exception e ) {
1555                throw new MBeanException( e,
1556                        "exception setting "+n+" attribute" );
1557            }
1558        }
1559        else if ( ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME.equals( n ) ) {
1560            boolean b;
1561            try {
1562                b = ((Boolean)v).booleanValue();
1563            }
1564            catch ( ClassCastException cce ){
1565                throw new InvalidAttributeValueException( "for attribute "+
1566                        " need "+Boolean.class.getName()+" got "+
1567                        v.getClass().getName() );
1568            }
1569            try {
1570                setUnitTestCmpPerformative( b );
1571                // invoking directly, not indirectly, 
1572                // so can't throw ReflectionException
1573            }
1574            catch ( Exception e ) {
1575                throw new MBeanException( e,
1576                        "exception setting "+n+" attribute" );
1577            }
1578        }
1579        else if ( ATTR_UNIT_TEST_CMP_PROTOCOL_NAME.equals( n ) ) {
1580            boolean b;
1581            try {
1582                b = ((Boolean)v).booleanValue();
1583            }
1584            catch ( ClassCastException cce ){
1585                throw new InvalidAttributeValueException( "for attribute "+
1586                        " need "+Boolean.class.getName()+" got "+
1587                        v.getClass().getName() );
1588            }
1589            try {
1590                setUnitTestCmpProtocol( b );
1591                // invoking directly, not indirectly, 
1592                // so can't throw ReflectionException
1593            }
1594            catch ( Exception e ) {
1595                throw new MBeanException( e,
1596                        "exception setting "+n+" attribute" );
1597            }
1598        }
1599        else if ( ATTR_UNIT_TEST_CMP_RECEIVER_NAME.equals( n ) ) {
1600            boolean b;
1601            try {
1602                b = ((Boolean)v).booleanValue();
1603            }
1604            catch ( ClassCastException cce ){
1605                throw new InvalidAttributeValueException( "for attribute "+
1606                        " need "+Boolean.class.getName()+" got "+
1607                        v.getClass().getName() );
1608            }
1609            try {
1610                setUnitTestCmpReceiver( b );
1611                // invoking directly, not indirectly, 
1612                // so can't throw ReflectionException
1613            }
1614            catch ( Exception e ) {
1615                throw new MBeanException( e,
1616                        "exception setting "+n+" attribute" );
1617            }
1618        }
1619        else if ( ATTR_UNIT_TEST_CMP_REPLY_BY_NAME.equals( n ) ) {
1620            boolean b;
1621            try {
1622                b = ((Boolean)v).booleanValue();
1623            }
1624            catch ( ClassCastException cce ){
1625                throw new InvalidAttributeValueException( "for attribute "+
1626                        " need "+Boolean.class.getName()+" got "+
1627                        v.getClass().getName() );
1628            }
1629            try {
1630                setUnitTestCmpReplyBy( b );
1631                // invoking directly, not indirectly, 
1632                // so can't throw ReflectionException
1633            }
1634            catch ( Exception e ) {
1635                throw new MBeanException( e,
1636                        "exception setting "+n+" attribute" );
1637            }
1638        }
1639        else if ( ATTR_UNIT_TEST_CMP_REPLY_TO_NAME.equals( n ) ) {
1640            boolean b;
1641            try {
1642                b = ((Boolean)v).booleanValue();
1643            }
1644            catch ( ClassCastException cce ){
1645                throw new InvalidAttributeValueException( "for attribute "+
1646                        " need "+Boolean.class.getName()+" got "+
1647                        v.getClass().getName() );
1648            }
1649            try {
1650                setUnitTestCmpReplyTo( b );
1651                // invoking directly, not indirectly, 
1652                // so can't throw ReflectionException
1653            }
1654            catch ( Exception e ) {
1655                throw new MBeanException( e,
1656                        "exception setting "+n+" attribute" );
1657            }
1658        }
1659        else if ( ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME.equals( n ) ) {
1660            boolean b;
1661            try {
1662                b = ((Boolean)v).booleanValue();
1663            }
1664            catch ( ClassCastException cce ){
1665                throw new InvalidAttributeValueException( "for attribute "+
1666                        " need "+Boolean.class.getName()+" got "+
1667                        v.getClass().getName() );
1668            }
1669            try {
1670                setUnitTestCmpReplyWith( b );
1671                // invoking directly, not indirectly, 
1672                // so can't throw ReflectionException
1673            }
1674            catch ( Exception e ) {
1675                throw new MBeanException( e,
1676                        "exception setting "+n+" attribute" );
1677            }
1678        }
1679        else if ( ATTR_UNIT_TEST_CMP_SENDER_NAME.equals( n ) ) {
1680            boolean b;
1681            try {
1682                b = ((Boolean)v).booleanValue();
1683            }
1684            catch ( ClassCastException cce ){
1685                throw new InvalidAttributeValueException( "for attribute "+
1686                        " need "+Boolean.class.getName()+" got "+
1687                        v.getClass().getName() );
1688            }
1689            try {
1690                setUnitTestCmpSender( b );
1691                // invoking directly, not indirectly, 
1692                // so can't throw ReflectionException
1693            }
1694            catch ( Exception e ) {
1695                throw new MBeanException( e,
1696                        "exception setting "+n+" attribute" );
1697            }
1698        }
1699        else if ( ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME.equals( n ) ) {
1700            boolean b;
1701            try {
1702                b = ((Boolean)v).booleanValue();
1703            }
1704            catch ( ClassCastException cce ){
1705                throw new InvalidAttributeValueException( "for attribute "+
1706                        " need "+Boolean.class.getName()+" got "+
1707                        v.getClass().getName() );
1708            }
1709            try {
1710                setUnitTestCmpUserProperties( b );
1711                // invoking directly, not indirectly, 
1712                // so can't throw ReflectionException
1713            }
1714            catch ( Exception e ) {
1715                throw new MBeanException( e,
1716                        "exception setting "+n+" attribute" );
1717            }
1718        }
1719        else if ( ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME.equals( n ) ) {
1720            boolean b;
1721            try {
1722                b = ((Boolean)v).booleanValue();
1723            }
1724            catch ( ClassCastException cce ){
1725                throw new InvalidAttributeValueException( "for attribute "+
1726                        " need "+Boolean.class.getName()+" got "+
1727                        v.getClass().getName() );
1728            }
1729            try {
1730                setUnitTestIgnoreContentAIDAddresses( b );
1731                // invoking directly, not indirectly, 
1732                // so can't throw ReflectionException
1733            }
1734            catch ( Exception e ) {
1735                throw new MBeanException( e,
1736                        "exception setting "+n+" attribute" );
1737            }
1738        }
1739        else if ( ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME.equals( n ) ) {
1740            boolean b;
1741            try {
1742                b = ((Boolean)v).booleanValue();
1743            }
1744            catch ( ClassCastException cce ){
1745                throw new InvalidAttributeValueException( "for attribute "+
1746                        " need "+Boolean.class.getName()+" got "+
1747                        v.getClass().getName() );
1748            }
1749            try {
1750                setUnitTestNewlinesNormalized( b );
1751                // invoking directly, not indirectly, 
1752                // so can't throw ReflectionException
1753            }
1754            catch ( Exception e ) {
1755                throw new MBeanException( e,
1756                        "exception setting "+n+" attribute" );
1757            }
1758        }        
1759        else {
1760            // no parent class to try, subclasses had first crack
1761            throw new AttributeNotFoundException(
1762                    "no such writable attribute"+n );
1763        }
1764        
1765 
1766    }
1767    
1768    /**
1769     * set multiple attribute values
1770     * @param attributes attribute values to set
1771     * @return set attribute values
1772     */
1773    public AttributeList setAttributes(AttributeList attributes) {
1774        int attrCount = attributes.size();
1775        for ( int i = 0; i < attrCount; i++ ) {
1776            try {
1777                setAttribute( (Attribute)attributes.get(i) );
1778            }
1779            catch ( RuntimeException re ) {
1780                throw re;
1781            }
1782            catch ( Exception e ) {
1783                throw new RuntimeException( e );
1784            }
1785        }
1786        return attributes;
1787    }
1788    
1789    /**
1790     * invoke an operation
1791     * @param actionName name of action to invoke
1792     * @param params action parameters
1793     * @param signature action signature
1794     * @return object result
1795     * @exception MBeanException wrap action exception
1796     * @exception ReflectionException wrap action invocation exception
1797     */
1798    public Object invoke(String actionName, Object params[], String signature[])
1799          throws MBeanException, ReflectionException {
1800        
1801        Object o = null;
1802        if ( OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME.equals( actionName ) && 
1803             MBeanUtil.signaturesEqual( 
1804                     OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE, signature ) ) {
1805            try {
1806                unitTestInjectAndExpect();
1807            }
1808            catch ( Exception e ) {
1809                throw new MBeanException( e, 
1810                        "exception invoking "+actionName+" operation");
1811            }  
1812        }
1813        else if ( OPER_UNIT_TEST_ADD_VARIABLE_NAME.equals( actionName ) && 
1814                MBeanUtil.signaturesEqual( 
1815                        OPER_UNIT_TEST_ADD_VARIABLE_SIGNATURE, signature ) ) {
1816               try {
1817                   unitTestAddVariable( (String)params[0], (String)params[1] );
1818               }
1819               catch ( Exception e ) {
1820                   throw new MBeanException( e, 
1821                           "exception invoking "+actionName+" operation");
1822               }  
1823        }
1824        else if ( OPER_UNIT_TEST_CLEAR_VARIABLES_NAME.equals( actionName ) && 
1825                MBeanUtil.signaturesEqual( 
1826                        OPER_UNIT_TEST_CLEAR_VARIABLES_SIGNATURE, signature ) ) {
1827               try {
1828                   unitTestClearVariables();
1829               }
1830               catch ( Exception e ) {
1831                   throw new MBeanException( e, 
1832                           "exception invoking "+actionName+" operation");
1833               }  
1834        }
1835        else {
1836            // no superclass to try and any subclass already had first crack
1837            throw new ReflectionException( new RuntimeException(), 
1838                    "no action named \""+actionName+"\" with given signature");
1839        }
1840        return o;
1841    }
1842    
1843    // END DynamicMBean IMPLEMENTATION
1844    
1845    //
1846    // UNIT TESTING
1847    //
1848    
1849    /**
1850     * set timeout to use for testing expressed as ISO 8601 duration.
1851     * The timeout does have a default which is, however, not guaranteed 
1852     * to remain the same.
1853     * @param timeoutStr timeout for test expressed as ISO 8601 duration
1854     */
1855    public void setUnitTestTimeout( String timeoutStr ) {
1856        this.unitTestTimeout = new Duration( timeoutStr );
1857    }
1858    
1859    /**
1860     * return unit test timeout as an ISO8601 duration string
1861     * @return unit test timeout as an ISO8601 duration string
1862     */
1863    public String getUnitTestTimeout() {
1864        return unitTestTimeout.toString();
1865    }
1866    
1867    /**
1868     * set the expected message for unit testing
1869     * @param expectMsg message to expect to see as result of injecting msg
1870     * @throws JademxException wrap any exception thrown
1871     */
1872    public void setUnitTestExpectedMessage( String expectMsg ) throws JademxException  {
1873        try {
1874            unitTestExpectedMessage = AclMsgCmp.stringToMessage( expectMsg );
1875            if ( null == unitTestExpectedMessage.getSender() ) {
1876                throw new JademxException("expected message has no sender:"+
1877                        expectMsg);
1878            }
1879        } 
1880        catch ( CodecException e ) {
1881            throw new JademxException(
1882                    "exception converting to ACLMessage from string:"+expectMsg,
1883                    e );
1884        }
1885    }
1886    
1887    /**
1888     * return the expected message for unit testing as a string
1889     * @return string representation of expected message for unit testing
1890     */
1891    public String getUnitTestExpectedMessage() {
1892        String expectedMessageStr = null;
1893        if ( null != unitTestExpectedMessage ) {
1894            expectedMessageStr = unitTestExpectedMessage.toString();
1895        }
1896        return expectedMessageStr;
1897    }
1898 
1899    
1900    
1901    /**
1902     * set the inject message for unit testing
1903     * @param injectMsg message to inject
1904     * @throws JademxException wrap any exception thrown
1905     */
1906    public void setUnitTestInjectMessage( String injectMsg ) throws JademxException  {
1907        try {
1908            unitTestInjectMessage = AclMsgCmp.stringToMessage( injectMsg );
1909        } 
1910        catch ( CodecException e ) {
1911            throw new JademxException(
1912                    "exception converting to ACLMessage from string:"+injectMsg,
1913                    e );
1914        }
1915    }
1916    
1917    /**
1918     * return the message to inject for unit testing as a string
1919     * @return string representation of message to inject for unit testing
1920     */
1921    public String getUnitTestInjectMessage() {
1922        String injectMessageStr = null;
1923        if ( null != unitTestInjectMessage ) {
1924            injectMessageStr = unitTestInjectMessage.toString();
1925        }
1926        return injectMessageStr;
1927    }
1928    
1929    /**
1930     * return the actual message that was compared for unit testing as a string
1931     * @return string representation of actual message for unit testing
1932     */
1933    public String getUnitTestActualMessage() {
1934        String actualMessageStr = null;
1935        if ( null != unitTestActualMessage ) {
1936            actualMessageStr = unitTestActualMessage.toString();
1937        }
1938        return actualMessageStr;
1939    }
1940    
1941    /**
1942     * set the actual message
1943     * @param unitTestActualMessage actual message to set
1944     */
1945    public void setUnitTestActualMessage( ACLMessage unitTestActualMessage ) {
1946        this.unitTestActualMessage = unitTestActualMessage;
1947    }
1948 
1949    
1950    /**
1951     * method to inject a message for unit testing.
1952     * will generate either a success or failure (asynchronous) notification.
1953     * @throws JademxException wrap any exception thrown
1954     */
1955    public void unitTestInjectAndExpect() 
1956      throws JademxException {
1957        
1958        Exception e = null;
1959        if ( null == unitTestExpectedMessage ) {
1960            e = new IllegalStateException("expected message not set");
1961        }
1962        else if ( null == unitTestInjectMessage ) {
1963            e = new IllegalStateException("inject message not set");
1964        }
1965        else if ( null == unitTestTimeout ) {
1966            e = new IllegalStateException("timeout not set");
1967        }
1968        if ( null != e ) {
1969            throw new JademxException(
1970                    "agent not properly initialized for unit testing", e );
1971        }
1972        unitTestActualMessage = null;
1973        
1974        // add a behaviour to inject test message and cause notification
1975        UnitTestBehaviour b = new UnitTestBehaviour( 
1976                this, 
1977                unitTestExpectedMessage, 
1978                unitTestInjectMessage, 
1979                unitTestTimeout,
1980                unitTestVariableProperties );
1981        
1982        addBehaviour( b );
1983    }
1984    
1985    /**
1986     * add a variable
1987     * @param variable string that can vary one message to next
1988     * @param type type of string (see AclMsgCmp.*_MAP)
1989     */
1990    public void unitTestAddVariable( String variable, String type ) {
1991        unitTestVariableProperties.setProperty( variable, type );
1992    }
1993    
1994    /**
1995     * clear all variables
1996     */
1997    public void unitTestClearVariables() {
1998        unitTestVariableProperties.clear();
1999    }
2000    
2001    /**
2002     * see if unit testing part of agent yet visible via JMX
2003     * @param agentObjectName ObjectName for agent MBean
2004     * @param mBeanServer MBeanServer with agent MBean
2005     * @return whether unit test mbean stuff yet visible
2006     */
2007    private static boolean isUnitTestVisible( 
2008            ObjectName agentObjectName,
2009            MBeanServer mBeanServer ) {
2010        boolean visible = false;
2011        MBeanInfo mBeanInfo = null;
2012        try {
2013            mBeanInfo = mBeanServer.getMBeanInfo( agentObjectName );
2014        }
2015        catch ( Exception e ) {
2016            // ignore, will return false
2017        }
2018        if ( null != mBeanInfo ) {
2019            visible = MBeanUtil.mBeanHasOper( mBeanInfo, 
2020                    OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, 
2021                    OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE );
2022        }
2023        return visible;
2024    }
2025    
2026    /** how long to sleep waiting for unit testing visibility */
2027    private final static long UNIT_TEST_VISIBILITY_SLEEP_MS = 1000; // 1,000ms = 1sec
2028    /** how long to wait for unit testing visibility */
2029    private final static long UNIT_TEST_VISIBILITY_PATIENCE_MS = 60 * 1000; // 60,000ms = 1min
2030 
2031    
2032    /**
2033     * see if agent MBean is currently bound to a JademxAgent
2034     * @return whether arg is currently bound to a JademxAgent
2035     */
2036    public static boolean isJademxBound(
2037            ObjectName agentObjectName,
2038            MBeanServer mBeanServer) {
2039        // do this by being able to see unitTestInvoke operation
2040        boolean bound = isUnitTestVisible( agentObjectName, mBeanServer );
2041        return bound;
2042    }
2043    
2044    
2045    /**
2046     * assert that MBean bound to JademxAgent
2047     * @param agentObjectName ObjectName for agent
2048     * @param mBeanServer MBeanServer for agent MBean
2049     * @param sleepMS interval sleep time while checking in milliseconds
2050     * @param patienceMS maximum time to wait in milliseconds
2051     */
2052    public static void assertIsJademxAgent(
2053            ObjectName agentObjectName,
2054            MBeanServer mBeanServer,
2055            long sleepMS,
2056            long patienceMS ) {
2057        // make sure the agent is bound to jademx
2058        if ( !isJademxBound( agentObjectName, mBeanServer ) ) {
2059            boolean visible = false;
2060            Date now = new Date();
2061            long nowMS = now.getTime();
2062            long stopMS = nowMS + patienceMS;
2063            while ( !visible && ( nowMS < stopMS ) ) {
2064                try {
2065                    Thread.sleep( sleepMS );
2066                }
2067                catch ( Exception e ) {
2068                    // don't care why sleep stopped
2069                }
2070                visible = isJademxBound( agentObjectName, mBeanServer );
2071            }
2072            if ( !visible ) {
2073                Assert.fail("unit testing capability not visible within "+
2074                        UNIT_TEST_VISIBILITY_PATIENCE_MS+"ms");
2075            }
2076        }
2077    }
2078 
2079    
2080    /**
2081     * using default timeout values, assert that MBean bound to JademxAgent
2082     * @param agentObjectName ObjectName for agent
2083     * @param mBeanServer MBeanServer for agent MBean
2084     */
2085    public static void assertIsJademxAgent(
2086            ObjectName agentObjectName,
2087            MBeanServer mBeanServer) {
2088        assertIsJademxAgent( agentObjectName, mBeanServer, 
2089                UNIT_TEST_VISIBILITY_SLEEP_MS, 
2090                UNIT_TEST_VISIBILITY_PATIENCE_MS );
2091    }
2092    
2093    /**
2094     * do a JUnit assertion that expected message seen after a message injected.
2095     * This method is similar in concept to a synchronous version of
2096     * the <code>unitTestInjectAndExpect</code> JadeAgentMBeanDef MBean operation.
2097     * It is not accessible as an MBean operation so that the MBeanServer
2098     * does not hang waiting for its return.  It intended to be used in
2099     * a JUnit test like Junit.Assert methods.  It is a static method
2100     * rather than an instance method because JMX users are only expected to 
2101     * have JMX access rather than direct access.
2102     * @param junitFailureMessage the string to use for junit failure message
2103     * @param agentObjectName ObjectName for agent MBean
2104     * @param mBeanServer MBeanServer with agent MBean
2105     */
2106    public static void assertExpectedMessage( 
2107            String junitFailureMessage, 
2108            ObjectName agentObjectName,
2109            MBeanServer mBeanServer ) {
2110        
2111        logger.log( Level.FINE, "entering");
2112        
2113        // make sure the agent is bound to jademx (can see unitTestInvoke oper)
2114        assertIsJademxAgent( agentObjectName, mBeanServer );
2115        logger.log( Level.FINE, "unit test visible");
2116 
2117        // register notification listener for agent mbean
2118        UnitTestNotificationListener nListener = 
2119            new UnitTestNotificationListener();
2120        try {
2121            mBeanServer.addNotificationListener( 
2122                    agentObjectName, nListener, null, null );
2123        }
2124        catch ( Exception e ) {
2125            Assert.fail( ThrowableUtil.errMsg(
2126                    "problem adding notification listener to "+agentObjectName, 
2127                    e ) );
2128        }
2129 
2130        logger.log( Level.FINE, "notification listener added");
2131 
2132        // try block for removing notification listener finally
2133        try {
2134            
2135            // invoke the unitTestInvoke operation
2136            
2137            Notification notification = null;
2138            String actionMsgStr = null;
2139            logger.log( Level.FINE, "entering block synchronized on listener");
2140            synchronized( nListener ) {
2141            
2142                long timeoutMS = 0;
2143                try {
2144                    logger.log( Level.FINE, "invoking "+OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME);
2145                    mBeanServer.invoke( 
2146                            agentObjectName, 
2147                            OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, 
2148                            new Object[] {}, 
2149                            OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE );
2150                    logger.log( Level.FINE, "returned from "+OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME);
2151                    logger.log( Level.FINE, "getting attribute "+ATTR_UNIT_TEST_TIMEOUT_NAME);
2152                    String timeoutStr = (String)mBeanServer.getAttribute( 
2153                            agentObjectName, ATTR_UNIT_TEST_TIMEOUT_NAME );
2154                    logger.log( Level.FINE, "got attribute "+ATTR_UNIT_TEST_TIMEOUT_NAME);
2155                    Duration timeoutDuration = new Duration( timeoutStr );
2156                    timeoutMS = timeoutDuration.toMilliseconds();
2157                    
2158                }
2159                catch ( Throwable t ) {
2160                    Assert.fail(
2161                            ThrowableUtil.errMsg("problem invoking test injection", t ) ); 
2162                }
2163                
2164                // wait until get a notification or time out
2165                
2166                logger.log( Level.FINE, "waiting for notification or timeout");
2167                Date now = new Date();
2168                long nowMS = now.getTime();
2169                long startMS = nowMS;
2170                long stopMS = startMS + timeoutMS;
2171                boolean doneWaiting = false;
2172                while ( !doneWaiting ) {
2173                    long timeLeftMS = stopMS - nowMS;
2174                    try {
2175                        logger.log( Level.FINE, "calling wait on listener");
2176                        nListener.wait( timeLeftMS );
2177                        logger.log( Level.FINE, "returned from wait on listener");
2178                    }
2179                    catch ( InterruptedException ie ) {
2180                        // interrupted while waiting, try waiting again
2181                        logger.log( Level.FINE,
2182                          "interrupted waiting for unit test invocation");
2183                    }
2184                    notification = nListener.getNotification();
2185                    if ( null != notification ) {
2186                        doneWaiting = true;
2187                    }
2188                    else {
2189                        now = new Date();
2190                        nowMS = now.getTime();
2191                        if ( nowMS >= stopMS ) {
2192                            doneWaiting = true;
2193                            actionMsgStr = 
2194                                "timeout waiting for unit test notification";
2195                        }
2196                    }
2197                }
2198                logger.log( Level.FINE, "done waiting for notification or timeout");
2199            
2200            }
2201            
2202            // if timed out or saw exception
2203            //   junitAssert with a timeout/exception message or 
2204            // else
2205            //   if success
2206            //     junitAssert true
2207            //   else
2208            //     junitAssert failure
2209            
2210            if ( null == notification ) {
2211                Assert.fail( actionMsgStr );
2212            }
2213            else {
2214                if ( NOTIF_UNIT_TEST_SUCCESS_NAME.equals( notification.getType() ) ) {
2215                    Assert.assertTrue( true );
2216                }
2217                else {
2218                    String notificationMessage = notification.getMessage();
2219                    StringBuffer failureMsgSB = new StringBuffer();
2220                    if ( null != junitFailureMessage ) {
2221                        failureMsgSB.append( junitFailureMessage );
2222                    }
2223                    if ( null != notificationMessage ) {
2224                        if ( null != junitFailureMessage ) {
2225                            failureMsgSB.append( "(" );
2226                        }
2227                        failureMsgSB.append( notificationMessage );
2228                        if ( null != junitFailureMessage ) {
2229                            failureMsgSB.append( ")" );
2230                        }
2231                    }
2232                    String failureMsg = failureMsgSB.toString();
2233                    Assert.fail( failureMsg );
2234                }
2235            }
2236                
2237        }
2238        finally {
2239            // make sure notification listener removed
2240            try {
2241                logger.log( Level.FINE, "removing notification listener");
2242                mBeanServer.removeNotificationListener( 
2243                        agentObjectName, nListener );
2244                logger.log( Level.FINE, "notification listener removed");
2245            }
2246            catch ( Exception e ) {
2247                logger.warning(ThrowableUtil.errMsg(
2248                        "problem removing notification listener:",e));
2249            }
2250            logger.log( Level.FINE, "exiting");
2251        }
2252 
2253 
2254    }
2255    
2256    /**
2257     * do a JUnit assertion that expected message seen after a message injected.
2258     * This method is similar in concept to a synchronous version of
2259     * the <code>unitTestInjectAndExpect</code> JadeAgentMBeanDef MBean operation.
2260     * It is not accessible as an MBean operation so that the MBeanServer
2261     * does not hang waiting for its return.  It intended to be used in
2262     * a JUnit test like other Junit.Assert methods.  It is a static method
2263     * rather than an instance method because JMX users are expected to have
2264     * JMX access rather than direct access.
2265     * @param agentObjectName ObjectName for agent MBean
2266     * @param mBeanServer MBeanServer with agent MBean
2267     */
2268    public static void assertExpectedMessage( 
2269            ObjectName agentObjectName,            
2270            MBeanServer mBeanServer ) {
2271        assertExpectedMessage( null, agentObjectName, mBeanServer );
2272    }
2273    
2274    // END UNIT TESTING
2275    
2276}

[all classes][jade.jademx.agent]
EMMA 2.0.5312 (C) Vladimir Roubtsov