1   package org.musicontroller.test;
2   
3   import java.io.InputStream;
4   import java.sql.Connection;
5   import java.sql.SQLException;
6   
7   import javax.sql.DataSource;
8   
9   import org.acegisecurity.Authentication;
10  import org.acegisecurity.context.SecurityContextHolder;
11  import org.acegisecurity.context.SecurityContextImpl;
12  import org.acegisecurity.providers.AuthenticationProvider;
13  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
14  import org.apache.log4j.Logger;
15  import org.dbunit.database.DatabaseConnection;
16  import org.dbunit.database.IDatabaseConnection;
17  import org.dbunit.dataset.DataSetException;
18  import org.dbunit.dataset.IDataSet;
19  import org.dbunit.dataset.xml.XmlDataSet;
20  import org.dbunit.operation.DatabaseOperation;
21  import org.hibernate.Session;
22  import org.hibernate.SessionFactory;
23  import org.junit.After;
24  import org.junit.Before;
25  import org.musicontroller.core.Song;
26  import org.musicontroller.dao.BagAndKeywordUtils;
27  import org.musicontroller.dao.Dao;
28  import org.springframework.context.ApplicationContext;
29  import org.springframework.context.support.ClassPathXmlApplicationContext;
30  import org.springframework.orm.hibernate3.SessionHolder;
31  import org.springframework.transaction.support.TransactionSynchronizationManager;
32  
33  public abstract class HSQLTestCase {		
34  		
35  		/**
36  		 * Id van de band aanwezig in de test dataset
37  		 */
38  		protected static final long TestBandId = 1L;
39  		protected static final String TestBandName = "The Clash";
40  		protected static final long AnotherTestBandId = 2L;
41  		protected static final String AnotherTestBandName = "Shockabilly";
42  		
43  		/**
44  		 * Id van de playlist aanwezig in de test dataset.
45  		 */
46  		protected static final long TestPlaylistId = 1L;
47  
48  		/**
49  		 * Id van twee songs aanwezig in de test playlist. Beide
50  		 * songs maken deel uit van de testplaylist.
51  		 */
52  		protected static final long TestSongId1 = 1L;
53  		protected static final long TestSongId2 = 2L;
54  		protected static final String TestSongName1 = "Rebel Waltz";
55  
56  		/**
57  		 * De testdatabase bevat een aantal keywords.
58  		 */
59  		protected static final long TestKeywordId1 = 1214L;
60  		protected static final long TestKeywordId2 = 1215L;
61  		
62  		protected static final long TestArtistId = 1L;
63  		protected static final long TestInstrumentId = 1L;
64  		
65  		/**
66  		 * User t.b.v. unit tests
67  		 */
68  		final protected static String usernameForUnitTest = "UnitTest";
69  		final protected static String userPassForUnitTest = "";
70  		final protected static long persistentUserId = 300L;
71  		
72  		private static ClassPathXmlApplicationContext _ctx = null;
73  		private static SessionFactory _sessionFactory;
74  		private static DataSource _mc_dataSource;
75  		private static Dao _dao;
76  		private static BagAndKeywordUtils _BagAndKeywordUtils;
77  		
78  		/* Zie onderstaande website voor "t voorbeeld.
79  		 * http://affy.blogspot.com/2005/10/acegi-tutorial-example-of-method-based.html
80  		 */
81  		@Before
82  		public void setUp() throws Exception {
83  			try {
84  				if (_dao==null) {
85  					_ctx = new ClassPathXmlApplicationContext(new String[]{"servlet-test.xml"});
86  					_dao = (Dao) getBean("dao");
87  					_mc_dataSource = (DataSource) getBean("dataSource");
88  					_sessionFactory = (SessionFactory) getBean("sessionFactory");
89  					_BagAndKeywordUtils = (BagAndKeywordUtils) getBean("bagAndKeywordUtils");
90  				}
91  				initializeDatabase();
92  			    Session s = _sessionFactory.openSession();
93  			    TransactionSynchronizationManager.bindResource(_sessionFactory, new SessionHolder(s));
94  				createSecureContext(_ctx,"user","user");
95  			} catch (Exception e) {
96  				e.printStackTrace();
97  				throw e;
98  			}
99  		}
100 
101 		protected void initializeDatabase() throws Exception {
102 			IDatabaseConnection cmc = new DatabaseConnection(_mc_dataSource.getConnection());
103 			InputStream is = Song.class.getClassLoader().getResourceAsStream("mc_dataset.xml");
104 			if(is == null) {
105 				throw new Exception("Can't open the test dataset.");
106 			} else {
107 		        IDataSet mcDataset = new XmlDataSet(is);
108 		        try {
109 		        	deleteFromAllTables(cmc.getConnection());
110 		            DatabaseOperation.CLEAN_INSERT.execute(cmc,mcDataset);
111 		        } catch (DataSetException de) {
112 		        	Logger.getLogger(this.getClass()).error("Could not read the MusiController database test set: " + de.getLocalizedMessage());
113 		        	de.printStackTrace();
114 		        } catch (Exception e) {
115 		        	e.printStackTrace();
116 		        } finally {
117 		            cmc.close();
118 		        }
119 			}
120 		}
121 
122 		/**
123 		 * Because CLEAN-INSERT falls over a few foreign-key constraints, this
124 		 * method clears all such tables.
125 		 * @param connection The Connection to the Database.
126 		 * @throws SQLException When something goes wrong.
127 		 */
128 		private void deleteFromAllTables(Connection connection) throws SQLException {
129 			connection.prepareStatement("delete from b_a_contract").execute();
130 			connection.prepareStatement("delete from event").execute();
131 			connection.prepareStatement("delete from p_s_contract").execute();
132 			connection.prepareStatement("delete from song").execute();
133 			connection.prepareStatement("delete from keywordbag").execute();
134 			connection.prepareStatement("delete from s_kb_relation").execute();
135 			while (connection.prepareStatement("delete from keyword where id not in (select keyword_id from keyword)").executeUpdate()!=0) {};
136 		}
137 
138 		@After
139 		public void tearDown() throws Exception {
140 	        SecurityContextHolder.setContext(new SecurityContextImpl());
141 		    SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(_sessionFactory);
142 		    if(holder!=null) {
143 		    	Session s = holder.getSession(); 
144 		    	s.flush();
145 		    	s.close();
146 		    }
147 		    TransactionSynchronizationManager.unbindResource(_sessionFactory);
148 		}
149 
150 		protected Object getBean(String beanname) {
151 			return _ctx.getBean(beanname);
152 		}
153 		
154 		protected Dao getDao() {
155 			return _dao;
156 		}
157 		
158 		protected static void createSecureContext(final ApplicationContext ctx, final String username, final String password) {
159 	        AuthenticationProvider provider = (AuthenticationProvider) ctx.getBean("testAuthenticationProvider");
160 	        Authentication auth = provider.authenticate(new UsernamePasswordAuthenticationToken(username, password));
161 	        SecurityContextHolder.getContext().setAuthentication(auth);
162 	    }
163 		
164 		public static SessionFactory getSessionFactory() {
165 			return _sessionFactory;
166 		}
167 		
168 		public static BagAndKeywordUtils getBagAndKeywordUtils() {
169 			return _BagAndKeywordUtils;
170 		}
171 
172 }