1 /*
2    Copyright 2010 Sun Microsystems, Inc.
3    All rights reserved. Use is subject to license terms.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License, version 2.0,
7    as published by the Free Software Foundation.
8 
9    This program is also distributed with certain software (including
10    but not limited to OpenSSL) that is licensed under separate terms,
11    as designated in a particular file or component or in included license
12    documentation.  The authors of MySQL hereby grant you an additional
13    permission to link the program and your derivative works with the
14    separately licensed software that they have included with MySQL.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License, version 2.0, for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 */
25 
26 package testsuite.clusterj;
27 
28 import testsuite.clusterj.model.CrazyDelegate;
29 import testsuite.clusterj.model.ThrowNullPointerException;
30 
31 /**
32  * This test verifies the behavior of the core implementation to provide for
33  * loadable DomainTypeHandlerFactory implementations. This is the way to
34  * support abstract classes or concrete classes as domain types.
35  *
36  * If a file META-INF/services/com.mysql.clusterj.spi.DomainTypeHandlerFactory
37  * exists that names a loadable class, the core implementation should use it
38  * preferentially to load a DomainTypeHandler for an unregistered domain type.
39  *
40  * This test includes an implementation of DomainTypeHandlerFactory, called
41  * CrazyDomainTypeHandlerFactoryImpl, that has three modes of operation:
42  * <ol><li> if the simple domain class name begins with "Throw", then an
43  * exception is thrown immediately. This should cause clusterj to save the
44  * exception information and proceed to the next factory. The test will succeed
45  * when the standard implementation does not accept the domain class as a
46  * valid domain class.
47  * </li><li> if the simple domain class name is "CrazyDelegate", then an
48  * implementation of DomainTypeHandlerFactory is returned. The returned
49  * implementation doesn't immediately throw an exception but throws an
50  * exception when the method getProxyClass is called. This exception will be
51  * reported to clusterj and the test succeeds.
52  * </li><li> in all other cases, null is returned. This should cause clusterj
53  * to go to the next prospective factory. This case is exercised by every test
54  * case that includes the CrazyDomainTypeHandlerFactoryImpl in the services
55  * file (i.e. all other test cases).
56  * </li></ol>
57  */
58 public class DomainTypeHandlerFactoryTest extends AbstractClusterJModelTest {
59 
60     @Override
localSetUp()61     public void localSetUp() {
62         createSessionFactory();
63         session = sessionFactory.getSession();
64     }
65 
testThrowNullPointerException()66     public void testThrowNullPointerException() {
67         try {
68             ThrowNullPointerException instance = new ThrowNullPointerException();
69             // This should cause CrazyDomainTypeHandlerFactoryImpl to throw
70             // a NullPointerException which should be ignored. But the standard
71             // implementation doesn't like ThrowNullPointerException either,
72             // so it should throw an exception. But the error message should
73             // contain the original NullPointerException that was thrown by
74             // CrazyDomainTypeHandlerFactoryImpl.
75             session.makePersistent(instance);
76             error("Failed to catch RuntimeException");
77         } catch (RuntimeException e) {
78             if (!e.getMessage().contains("java.lang.NullPointerException")) {
79                 error("Failed to catch correct exception, but caught: " + e.toString());
80             }
81             // good catch
82         }
83         failOnError();
84     }
85 
testCrazyDelegate()86     public void testCrazyDelegate() {
87         try {
88             CrazyDelegate instance = new CrazyDelegate();
89             // This should fail at CrazyDomainTypeHandlerFactoryImpl.getProxyClass()
90             // It's a bit of a cheat since it relies on the internal implementation
91             // of SessionFactoryImpl.getDomainTypeHandler
92             session.makePersistent(instance);
93             error("Failed to catch UnsupportedOperationException");
94         } catch (UnsupportedOperationException ex) {
95             String message = ex.getMessage();
96             Throwable cause = ex.getCause();
97             String causeMessage =  cause==null?"null":cause.getMessage();
98             if (!message.contains("Nice Job!")) {
99                 error("Failed to catch correct exception, but caught: " + message + "; cause: " + causeMessage);
100             }
101         }
102         failOnError();
103     }
104 }
105