View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact tma@netspace.net.au. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2001-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: TestFilter.java,v 1.7 2004/01/31 13:44:24 tanderson Exp $ 44 */ 45 package org.exolab.jmscts.core; 46 47 import java.util.Enumeration; 48 import java.util.HashMap; 49 50 import javax.jms.BytesMessage; 51 import javax.jms.DeliveryMode; 52 import javax.jms.MapMessage; 53 import javax.jms.Message; 54 import javax.jms.QueueConnectionFactory; 55 import javax.jms.ObjectMessage; 56 import javax.jms.StreamMessage; 57 import javax.jms.TextMessage; 58 import javax.jms.TopicConnectionFactory; 59 import javax.jms.XAQueueConnectionFactory; 60 import javax.jms.XATopicConnectionFactory; 61 62 import junit.extensions.TestDecorator; 63 import junit.framework.Test; 64 import junit.framework.TestCase; 65 import junit.framework.TestSuite; 66 67 import org.apache.log4j.Category; 68 import org.apache.oro.text.regex.MalformedPatternException; 69 import org.apache.oro.text.regex.Pattern; 70 import org.apache.oro.text.regex.PatternMatcher; 71 import org.apache.oro.text.regex.Perl5Compiler; 72 import org.apache.oro.text.regex.Perl5Matcher; 73 74 75 import org.exolab.jmscts.core.filter.Exclude; 76 import org.exolab.jmscts.core.filter.Filter; 77 import org.exolab.jmscts.core.filter.Include; 78 import org.exolab.jmscts.core.filter.Selector; 79 import org.exolab.jmscts.core.types.DeliveryModeType; 80 import org.exolab.jmscts.core.types.DestinationType; 81 import org.exolab.jmscts.core.types.FactoryType; 82 import org.exolab.jmscts.core.types.MessageType; 83 import org.exolab.jmscts.core.types.ReceiverType; 84 import org.exolab.jmscts.core.types.SessionType; 85 86 87 /*** 88 * Instances of this class determine if a test case is to be tested or not, 89 * based on a filter specified by {@link Filter} 90 * 91 * @version $Revision: 1.7 $ $Date: 2004/01/31 13:44:24 $ 92 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 93 */ 94 public class TestFilter { 95 96 /*** 97 * The filter 98 */ 99 private Filter _filter; 100 101 /*** 102 * The set of included tests 103 */ 104 private Include[] _includes; 105 106 /*** 107 * The set of excluded tests 108 */ 109 private Exclude[] _excludes; 110 111 /*** 112 * Pattern matcher for wildcarded tests 113 */ 114 private PatternMatcher _matcher = new Perl5Matcher(); 115 116 /*** 117 * The logger 118 */ 119 private static final Category log = Category.getInstance(TestFilter.class); 120 121 /*** 122 * A map of connection factory classes, to their corresponding 123 * <code>FactoryType</code>s 124 */ 125 private static final HashMap FACTORIES; 126 127 /*** 128 * A map of <code>AckType</code>s to their corresponding 129 * <code>SessionType</code>s 130 */ 131 private static final HashMap SESSIONS; 132 133 /*** 134 * A map of message classes, to their corresponding 135 * <code>MessageType</code>s 136 */ 137 private static final HashMap MESSAGES; 138 139 140 /*** 141 * Construct a new <code>TestFilter</code> 142 * 143 * @param filter the filter 144 */ 145 public TestFilter(Filter filter) { 146 if (filter == null) { 147 throw new IllegalArgumentException("Argument 'filter' is null"); 148 } 149 _filter = filter; 150 _includes = _filter.getInclude(); 151 _excludes = _filter.getExclude(); 152 } 153 154 /*** 155 * Determines if a test is included by the filter 156 * 157 * @param factoryType the class of the connection factorry 158 * @param test the test case 159 * @return <code>true</code> if it is included, <code>false</code> 160 * otherwise 161 */ 162 public boolean includes(Class factoryType, Test test) { 163 boolean result = false; 164 FactoryType factory = (FactoryType) FACTORIES.get(factoryType); 165 if (!excludes(factory, null, null, null, null, null, test) 166 && includes(factory, null, null, null, null, null, test)) { 167 result = true; 168 } 169 if (log.isDebugEnabled()) { 170 log.debug("include(factory=" + factory 171 + ", test=" + getTestName(test) + ")=" + result); 172 } 173 return result; 174 } 175 176 /*** 177 * Determines if a test is included by the filter 178 * 179 * @param context the test context 180 * @param mode the session acknowledgement mode 181 * @param test the test case 182 * @return <code>true</code> if it is included, <code>false</code> 183 * otherwise 184 */ 185 public boolean includes(TestContext context, AckType mode, Test test) { 186 boolean result = false; 187 FactoryType factory = (FactoryType) FACTORIES.get( 188 ConnectionFactoryTypes.getType(context.getConnectionFactory())); 189 SessionType session = (SessionType) SESSIONS.get(mode); 190 191 if (!excludes(factory, session, null, null, null, null, test) 192 && includes(factory, session, null, null, null, null, test)) { 193 result = true; 194 } 195 if (log.isDebugEnabled()) { 196 log.debug("include(factory=" + factory + ", session=" + session 197 + ", test=" + getTestName(test) + ")=" + result); 198 } 199 return result; 200 } 201 202 /*** 203 * Determines if a test is included by the filter 204 * 205 * @param context the test context 206 * @param messageType the message type 207 * @param test the test case 208 * @return <code>true</code> if it is included, <code>false</code> 209 * otherwise 210 */ 211 public boolean includes(TestContext context, Class messageType, 212 Test test) { 213 boolean result = false; 214 FactoryType factory = (FactoryType) FACTORIES.get( 215 ConnectionFactoryTypes.getType(context.getConnectionFactory())); 216 SessionType session = (SessionType) SESSIONS.get(context.getAckType()); 217 MessageType message = (MessageType) MESSAGES.get(messageType); 218 219 if (!excludes(factory, session, null, null, null, message, test) 220 && includes(factory, session, null, null, null, message, test)) { 221 result = true; 222 } 223 if (log.isDebugEnabled()) { 224 log.debug("include(factory=" + factory + ", session=" + session 225 + ", message=" + message + ", test=" + getTestName(test) 226 + ")=" + result); 227 } 228 return result; 229 } 230 231 /*** 232 * Determines if a test is included by the filter 233 * 234 * @param context the test context 235 * @param behaviour the messaging behaviour 236 * @param messageType the message type 237 * @param test the test case 238 * @return <code>true</code> if it is included, <code>false</code> 239 * otherwise 240 */ 241 public boolean includes(TestContext context, MessagingBehaviour behaviour, 242 Class messageType, Test test) { 243 boolean result = false; 244 245 FactoryType factory = (FactoryType) FACTORIES.get( 246 ConnectionFactoryTypes.getType(context.getConnectionFactory())); 247 248 SessionType session = (SessionType) SESSIONS.get( 249 context.getAckType()); 250 251 DestinationType destination = (behaviour.getAdministered()) 252 ? DestinationType.ADMINISTERED : DestinationType.TEMPORARY; 253 254 DeliveryModeType delivery; 255 if (behaviour.getDeliveryMode() == DeliveryMode.PERSISTENT) { 256 delivery = DeliveryModeType.PERSISTENT; 257 } else { 258 delivery = DeliveryModeType.NON_PERSISTENT; 259 } 260 261 ReceiverType receiver = null; 262 ReceiptType receipt = behaviour.getReceiptType(); 263 if (receipt != null) { 264 if (receipt.equals(ReceiptType.SYNCHRONOUS)) { 265 receiver = (behaviour.getDurable()) 266 ? ReceiverType.DURABLE_SYNCHRONOUS 267 : ReceiverType.SYNCHRONOUS; 268 } else if (receipt.equals(ReceiptType.ASYNCHRONOUS)) { 269 receiver = (behaviour.getDurable()) 270 ? ReceiverType.DURABLE_ASYNCHRONOUS 271 : ReceiverType.ASYNCHRONOUS; 272 } else { 273 receiver = ReceiverType.BROWSER; 274 } 275 } 276 277 MessageType message = (MessageType) MESSAGES.get(messageType); 278 279 if (!excludes(factory, session, destination, delivery, receiver, 280 message, test) 281 && includes(factory, session, destination, delivery, receiver, 282 message, test)) { 283 result = true; 284 } 285 if (log.isDebugEnabled()) { 286 log.debug("include(factory=" + factory + ", session=" + session 287 + ", destination=" + destination + ", delivery=" 288 + delivery + ", receiver=" + receiver + ", message=" 289 + message + ", test=" + test + ")=" + result); 290 } 291 return result; 292 } 293 294 /*** 295 * Determines if a test is included by the filter 296 * 297 * @param factory the connection factory 298 * @param session the session type 299 * @param destination the destination type 300 * @param delivery the delivery mode 301 * @param receiver the receiver type 302 * @param message the message type 303 * @param test the test case 304 * @return <code>true</code> if it is included, <code>false</code> 305 * otherwise 306 */ 307 private boolean includes(FactoryType factory, SessionType session, 308 DestinationType destination, 309 DeliveryModeType delivery, ReceiverType receiver, 310 MessageType message, Test test) { 311 boolean result = (_includes == null || _includes.length == 0); 312 if (!result) { 313 for (int i = 0; i < _includes.length; ++i) { 314 if (includes(_includes[i], factory, session, destination, 315 delivery, receiver, message, test)) { 316 result = true; 317 break; 318 } 319 } 320 } 321 return result; 322 } 323 324 /*** 325 * Determines if a test is included by the filter 326 * 327 * @param selector the filter criteria 328 * @param factory the connection factory 329 * @param session the session type 330 * @param destination the destination type 331 * @param delivery the delivery mode 332 * @param receiver the receiver type 333 * @param message the message type 334 * @param test the test case 335 * @return <code>true</code> if it is included, <code>false</code> 336 * otherwise 337 */ 338 private boolean includes(Selector selector, FactoryType factory, 339 SessionType session, DestinationType destination, 340 DeliveryModeType delivery, ReceiverType receiver, 341 MessageType message, Test test) { 342 boolean result = false; 343 if (selector.getTest() == null) { 344 result = true; 345 } else if (test != null) { 346 result = containsTest(test, selector.getTest()); 347 } else { 348 result = true; 349 } 350 351 if (result) { 352 result = includes(selector.getFactory(), factory) 353 && includes(selector.getSession(), session) 354 && includes(selector.getDestination(), destination) 355 && includes(selector.getDeliveryMode(), delivery) 356 && includes(selector.getReceiver(), receiver) 357 && includes(selector.getMessage(), message); 358 } 359 return result; 360 } 361 362 /*** 363 * Determines if an object is included 364 * 365 * @param selector the filter criteria 366 * @param object the object to compare 367 * @return <code>true</code> if it is included, <code>false</code> 368 * otherwise 369 */ 370 private boolean includes(Object selector, Object object) { 371 boolean result = false; 372 if (selector == null || selector.equals(object) || object == null) { 373 result = true; 374 } 375 if (log.isDebugEnabled()) { 376 log.debug("includes(selector=" + selector + ", object=" + object 377 + ")=" + result); 378 } 379 return result; 380 } 381 382 /*** 383 * Determines if a test is excluded by the filter 384 * 385 * @param factory the connection factory 386 * @param session the session type 387 * @param destination the destination type 388 * @param delivery the delivery mode 389 * @param receiver the receiver type 390 * @param message the message type 391 * @param test the test case 392 * @return <code>true</code> if it is excluded, <code>false</code> 393 * otherwise 394 */ 395 private boolean excludes(FactoryType factory, SessionType session, 396 DestinationType destination, 397 DeliveryModeType delivery, ReceiverType receiver, 398 MessageType message, Test test) { 399 boolean result = false; 400 if (_excludes != null && _excludes.length != 0) { 401 for (int i = 0; i < _excludes.length; ++i) { 402 if (excludes(_excludes[i], factory, session, destination, 403 delivery, receiver, message, test)) { 404 result = true; 405 break; 406 } 407 } 408 } 409 return result; 410 } 411 412 /*** 413 * Determines if a test is excluded by the filter 414 * 415 * @param selector the filter criteria 416 * @param factory the connection factory 417 * @param session the session type 418 * @param destination the destination type 419 * @param delivery the delivery mode 420 * @param receiver the receiver type 421 * @param message the message type 422 * @param test the test case 423 * @return <code>true</code> if it is excluded, <code>false</code> 424 * otherwise 425 */ 426 private boolean excludes(Selector selector, FactoryType factory, 427 SessionType session, DestinationType destination, 428 DeliveryModeType delivery, ReceiverType receiver, 429 MessageType message, Test test) { 430 boolean result = false; 431 if (selector.getTest() != null && test != null) { 432 result = containsTest(test, selector.getTest()); 433 } 434 435 if (!result) { 436 result = excludes(selector.getFactory(), factory) 437 || excludes(selector.getSession(), session) 438 || excludes(selector.getDestination(), destination) 439 || excludes(selector.getDeliveryMode(), delivery) 440 || excludes(selector.getReceiver(), receiver) 441 || excludes(selector.getMessage(), message); 442 } 443 return result; 444 } 445 446 /*** 447 * Determines if an object is excluded 448 * 449 * @param selector the filter criteria 450 * @param object the object to compare 451 * @return <code>true</code> if it is excluded, <code>false</code> 452 * otherwise 453 */ 454 private boolean excludes(Object selector, Object object) { 455 boolean result = false; 456 if (selector != null && selector.equals(object)) { 457 result = true; 458 } 459 if (log.isDebugEnabled()) { 460 log.debug("excludes(selector=" + selector + ", object=" + object 461 + ")=" + result); 462 } 463 return result; 464 } 465 466 /*** 467 * Determines if a test is included by a regular expression, matching 468 * on its name. 469 * 470 * @param test the test 471 * @param regexp the regular expression 472 * @return <code>true</code> if the test is included, <code>false</code> 473 * otherwise 474 */ 475 private boolean containsTest(Test test, String regexp) { 476 Pattern pattern = null; 477 try { 478 Perl5Compiler compiler = new Perl5Compiler(); 479 pattern = compiler.compile(regexp); 480 } catch (MalformedPatternException exception) { 481 log.error("Invalid test case pattern: " + exception.getMessage()); 482 } 483 484 return (pattern != null) ? containsTest(test, pattern) : false; 485 } 486 487 488 /*** 489 * Determines if a test is included by a regular expression, matching 490 * on its name. 491 * If the test is a suite of tests, each child test will be examined. If 492 * there is any match, it returns true. 493 * 494 * @param test the test 495 * @param pattern the regular expression pattern 496 * @return <code>true</code> if the test is included, <code>false</code> 497 * otherwise 498 */ 499 private boolean containsTest(Test test, Pattern pattern) { 500 boolean result = false; 501 if (test instanceof TestSuite) { 502 Enumeration iterator = ((TestSuite) test).tests(); 503 while (iterator.hasMoreElements()) { 504 Test contained = (Test) iterator.nextElement(); 505 if (containsTest(contained, pattern)) { 506 result = true; 507 break; 508 } 509 } 510 } else if (test instanceof TestDecorator) { 511 Test contained = ((TestDecorator) test).getTest(); 512 result = containsTest(contained, pattern); 513 } else { 514 String name = getTestName(test); 515 result = _matcher.matches(name, pattern); 516 if (log.isDebugEnabled()) { 517 log.debug("containsTest(test=" + test + ", pattern=" 518 + pattern.getPattern() + ")=" + result); 519 } 520 } 521 return result; 522 } 523 524 /*** 525 * Helper to get the fully qualified name of a test 526 * 527 * @param test the test case 528 * @return the fully qualified name of a test 529 */ 530 private String getTestName(Test test) { 531 String name = test.getClass().getName(); 532 if (test instanceof TestCase) { 533 name += "." + ((TestCase) test).getName(); 534 } 535 return name; 536 } 537 538 static { 539 FACTORIES = new HashMap(); 540 FACTORIES.put(QueueConnectionFactory.class, 541 FactoryType.QUEUECONNECTIONFACTORY); 542 FACTORIES.put(TopicConnectionFactory.class, 543 FactoryType.TOPICCONNECTIONFACTORY); 544 FACTORIES.put(XAQueueConnectionFactory.class, 545 FactoryType.XAQUEUECONNECTIONFACTORY); 546 FACTORIES.put(XATopicConnectionFactory.class, 547 FactoryType.XATOPICCONNECTIONFACTORY); 548 549 SESSIONS = new HashMap(); 550 SESSIONS.put(AckTypes.TRANSACTED, SessionType.TRANSACTED); 551 SESSIONS.put(AckTypes.AUTO_ACKNOWLEDGE, SessionType.AUTO_ACKNOWLEDGE); 552 SESSIONS.put(AckTypes.CLIENT_ACKNOWLEDGE, 553 SessionType.CLIENT_ACKNOWLEDGE); 554 SESSIONS.put(AckTypes.DUPS_OK_ACKNOWLEDGE, 555 SessionType.DUPS_OK_ACKNOWLEDGE); 556 557 MESSAGES = new HashMap(); 558 MESSAGES.put(BytesMessage.class, MessageType.BYTESMESSAGE); 559 MESSAGES.put(MapMessage.class, MessageType.MAPMESSAGE); 560 MESSAGES.put(ObjectMessage.class, MessageType.OBJECTMESSAGE); 561 MESSAGES.put(StreamMessage.class, MessageType.STREAMMESSAGE); 562 MESSAGES.put(TextMessage.class, MessageType.TEXTMESSAGE); 563 MESSAGES.put(Message.class, MessageType.MESSAGE); 564 } 565 566 }

This page was automatically generated by Maven