1 | /** |
2 | * Copyright 2007 ATG DUST Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * |
7 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
8 | * |
9 | * Unless required by applicable law or agreed to in writing, software |
10 | * distributed under the License is distributed on an "AS IS" BASIS, |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | * See the License for the specific language governing permissions and limitations under the License. |
13 | */ |
14 | |
15 | package atg.adapter.gsa; |
16 | |
17 | import java.io.File; |
18 | import java.io.FileNotFoundException; |
19 | import java.io.FileOutputStream; |
20 | import java.io.FileWriter; |
21 | import java.io.IOException; |
22 | import java.io.InputStream; |
23 | import java.io.OutputStream; |
24 | import java.io.PrintWriter; |
25 | import java.sql.Connection; |
26 | import java.sql.PreparedStatement; |
27 | import java.sql.ResultSet; |
28 | import java.sql.SQLException; |
29 | import java.util.ArrayList; |
30 | import java.util.Collection; |
31 | import java.util.HashMap; |
32 | import java.util.HashSet; |
33 | import java.util.Iterator; |
34 | import java.util.List; |
35 | import java.util.Map; |
36 | import java.util.Properties; |
37 | |
38 | import javax.sql.DataSource; |
39 | |
40 | import junit.framework.Assert; |
41 | |
42 | import org.apache.log4j.Logger; |
43 | |
44 | import atg.adapter.gsa.xml.TemplateParser; |
45 | import atg.adapter.gsa.xml.VersioningContextUtil; |
46 | import atg.adapter.version.VersionRepository; |
47 | import atg.naming.NameContext; |
48 | import atg.nucleus.Configuration; |
49 | import atg.nucleus.GenericService; |
50 | import atg.nucleus.Nucleus; |
51 | import atg.nucleus.NucleusNameResolver; |
52 | import atg.nucleus.NucleusTestUtils; |
53 | import atg.nucleus.ServiceEvent; |
54 | import atg.nucleus.ServiceException; |
55 | import atg.repository.Repository; |
56 | import atg.repository.RepositoryException; |
57 | import atg.test.util.DBUtils; |
58 | import atg.versionmanager.VersionManager; |
59 | import atg.versionmanager.Workspace; |
60 | import atg.versionmanager.exceptions.VersionException; |
61 | |
62 | /** |
63 | * A utility class to simplify testing with GSARepositories inside of junit |
64 | * tests. |
65 | * |
66 | * @author adamb |
67 | * @version $Revision: #28 $ |
68 | */ |
69 | public class GSATestUtils { |
70 | public static List<File> mFilesCreated = new ArrayList<File>(); |
71 | public static String sClassName = "atg.adapter.gsa.InitializingGSA"; |
72 | public static String sVersionedClassName = "atg.adapter.gsa.InitializingVersionRepository"; |
73 | private boolean mVersioned = false; |
74 | private static GSATestUtils SINGLETON_DEFAULT = null; |
75 | private static GSATestUtils SINGLETON_VERSIONED = null; |
76 | |
77 | private static Logger log = Logger.getLogger(GSATestUtils.class); |
78 | |
79 | /** |
80 | * @param pB |
81 | */ |
82 | public GSATestUtils(boolean pB) { |
83 | mVersioned = pB; |
84 | |
85 | } |
86 | /** |
87 | * Duplicates the given array of repositories. |
88 | * This method first binds the repositories into nucleus under the name XXXX-Shadow, |
89 | * where XXXX is the original name. |
90 | * After all repositories are bound, then they are started. |
91 | * This allows for repositories with circular references to each other to be deplicated. |
92 | * The pRepositories array and pDS array should be in sync. That is the first item in the |
93 | * repository array, pRepositories, will use the first data source in the pDS array and so on. |
94 | * @param pRepositories |
95 | * @param pDS |
96 | * @return |
97 | */ |
98 | public static Repository [] duplicateRepositories(GSARepository [] pRepositories, DataSource [] pDS) throws ServiceException { |
99 | GSARepository [] newReps = new GSARepository[pRepositories.length]; |
100 | for (int i = 0 ; i < pRepositories.length; i++ ) { |
101 | newReps[i] = (GSARepository)duplicateRepository(pRepositories[i],pDS[i],false); |
102 | } |
103 | for (int i = 0 ; i < newReps.length; i++ ) { |
104 | startRepository(pRepositories[i], pRepositories[i].getServiceConfiguration(), pRepositories[i].getNucleus(), newReps[i]); |
105 | } |
106 | return newReps; |
107 | } |
108 | public static Repository duplicateRepository(GSARepository pRepository,DataSource pDS) throws ServiceException{ |
109 | return duplicateRepository(pRepository, pDS,true); |
110 | } |
111 | /** |
112 | * Duplicates the given repository, binds it into nucleus with the suffix "-Shadow" |
113 | * @param pStart If true, also starts the repository |
114 | */ |
115 | public static Repository duplicateRepository(GSARepository pRepository,DataSource pDS,boolean pStart) throws ServiceException{ |
116 | Configuration c = pRepository.getServiceConfiguration(); |
117 | Nucleus n = pRepository.getNucleus(); |
118 | NucleusNameResolver r = new NucleusNameResolver(n, n, |
119 | pRepository.getNameContext(), true); |
120 | GSARepository newRepository = null; |
121 | if(pRepository instanceof VersionRepository) { |
122 | newRepository = (GSARepository) c.createNewInstance(((VersionRepository)pRepository).getWrappedRepository()); |
123 | c.configureService(newRepository, r, ((VersionRepository)pRepository).getWrappedRepository()); |
124 | } |
125 | else { |
126 | newRepository = (GSARepository) c.createNewInstance(pRepository); |
127 | c.configureService(newRepository, r, pRepository); |
128 | } |
129 | newRepository.setDataSource(pDS); |
130 | newRepository.setForeignRepositorySuffix("-Shadow"); |
131 | |
132 | /* |
133 | // Fool this new repository into thinking that it has been |
134 | // bound to the same name context as the original repository |
135 | // This changes will make sure that getAbsoluteName() returns |
136 | // a correct value. |
137 | NameContext nc = ((GenericService) pRepository).getNameContext(); |
138 | NameContextBindingEvent bindingEvent = new NameContextBindingEvent(pRepository |
139 | .getName()+"-Shadow", newRepository, pRepository.getNameContext()); |
140 | newRepository.nameContextElementBound(bindingEvent); |
141 | */ |
142 | NameContext nc = ((GenericService) pRepository).getNameContext(); |
143 | nc.putElement(pRepository.getName()+"-Shadow", newRepository); |
144 | |
145 | if (pStart) |
146 | startRepository(pRepository, c, n, newRepository); |
147 | return newRepository; |
148 | } |
149 | /** |
150 | * @param pRepository |
151 | * @param c |
152 | * @param n |
153 | * @param newRepository |
154 | * @throws ServiceException |
155 | */ |
156 | private static void startRepository(GSARepository pRepository, Configuration c, Nucleus n, GSARepository newRepository) throws ServiceException { |
157 | ServiceEvent ev = new ServiceEvent(pRepository, newRepository, n, c); |
158 | /* |
159 | * We are purposefully not putting the new repository into the parent's name |
160 | * context. The existing repository is always the valid one. We're starting |
161 | * this new guy, then we're going to synchronize on the repository and get |
162 | * all of its info into us. |
163 | */ |
164 | |
165 | // we have to set the new repository as temporary so it won't call |
166 | // restart and start an infinite recursion |
167 | // newRepository.setIsTemporaryInstantiation(true); |
168 | |
169 | // But don't load data |
170 | if (newRepository instanceof InitializingGSA) |
171 | ((InitializingGSA)newRepository).setImportFiles(null); |
172 | |
173 | |
174 | newRepository.startService(ev); |
175 | if (newRepository.isRunning()) { |
176 | synchronized (pRepository) { |
177 | // newRepository.copyFromOtherRepository(pRepository); |
178 | newRepository.invalidateCaches(); |
179 | } |
180 | } |
181 | } |
182 | /** |
183 | * Given a directory, pRoot, this method creates the minimal .properties files |
184 | * required to startup a GSA Repository from Nucleus. |
185 | * |
186 | * The pJDBCProperties parameter should contain the JDBC properties used to |
187 | * create a FakeXADataSource. Required Properties are: driver URL user |
188 | * password |
189 | * |
190 | * For example, driver=solid.jdbc.SolidDriver URL=jdbc:solid://localhost:1313 |
191 | * user=admin password=admin |
192 | * |
193 | * <BR> |
194 | * One should call the <code>cleanup()</code> method to remove any files |
195 | * created by this method call. |
196 | * |
197 | * @param pRoot |
198 | * The root directory of the testing configpath |
199 | * @param pRepositoryPath |
200 | * The Nucleus path of your testing repository |
201 | * @param pDefinitionFiles |
202 | * Array of Nucleus paths to definition files |
203 | * @param pJDBCProperties |
204 | * properties object containing JDBC connection information |
205 | * @param pImportFile |
206 | * @throws IOException |
207 | * @throws Exception |
208 | * @see GSATestUtils.cleanup |
209 | */ |
210 | public void initializeMinimalConfigpath(File pRoot, |
211 | String pRepositoryPath, String[] pDefinitionFiles, |
212 | Properties pJDBCProperties, String pCreateSQLAbsolutePath, String pDropSQLAbsolutePath, String[] pImportFile) throws IOException, Exception { |
213 | initializeMinimalConfigpath(pRoot, pRepositoryPath, pDefinitionFiles, pJDBCProperties, pCreateSQLAbsolutePath, pDropSQLAbsolutePath, pImportFile, true); |
214 | } |
215 | |
216 | /** |
217 | * Given a directory, pRoot, this method creates the minimal .properties files |
218 | * required to startup a GSA Repository from Nucleus. |
219 | * |
220 | * The pJDBCProperties parameter should contain the JDBC properties used to |
221 | * create a FakeXADataSource. Required Properties are: driver URL user |
222 | * password |
223 | * |
224 | * For example, driver=solid.jdbc.SolidDriver URL=jdbc:solid://localhost:1313 |
225 | * user=admin password=admin |
226 | * |
227 | * <BR> |
228 | * One should call the <code>cleanup()</code> method to remove any files |
229 | * created by this method call. |
230 | * |
231 | * @param pRoot |
232 | * The root directory of the testing configpath |
233 | * @param pRepositoryPath |
234 | * The Nucleus path of your testing repository |
235 | * @param pDefinitionFiles |
236 | * Array of Nucleus paths to definition files |
237 | * @param pJDBCProperties |
238 | * properties object containing JDBC connection information |
239 | * @param pImportFile |
240 | * @param pLogging if true log to stdout, else logging is disabled |
241 | * @throws IOException |
242 | * @throws Exception |
243 | * @see GSATestUtils.cleanup |
244 | */ |
245 | public void initializeMinimalConfigpath(File pRoot, |
246 | String pRepositoryPath, String[] pDefinitionFiles, |
247 | Properties pJDBCProperties, String pCreateSQLAbsolutePath, String pDropSQLAbsolutePath, String[] pImportFile, boolean pLogging) throws IOException, Exception { |
248 | initializeMinimalConfigpath(pRoot, pRepositoryPath, pDefinitionFiles, pJDBCProperties, pCreateSQLAbsolutePath, pDropSQLAbsolutePath, pImportFile, pLogging, null, null); |
249 | |
250 | } |
251 | |
252 | |
253 | public void initializeMinimalConfigpath(File pRoot, |
254 | String pRepositoryPath, String[] pDefinitionFiles, |
255 | Properties pJDBCProperties, String pCreateSQLAbsolutePath, String pDropSQLAbsolutePath, String[] pImportFile, boolean pLogging, String pFakeXADataSourceComponentName, String pJTDataSourceComponentName) throws IOException, Exception { |
256 | if (pRepositoryPath != null) |
257 | createRepositoryPropertiesFile(pRoot, pRepositoryPath, |
258 | pDefinitionFiles, pCreateSQLAbsolutePath, pDropSQLAbsolutePath, pImportFile, pJTDataSourceComponentName); |
259 | createTransactionManager(pRoot); |
260 | createUserTransaction(pRoot); |
261 | createXMLToolsFactory(pRoot); |
262 | createIdGenerator(pRoot); |
263 | createClientLockManager(pRoot); |
264 | DBUtils.createJTDataSource(pRoot); |
265 | if(pJDBCProperties != null) |
266 | GSATestUtils.createFakeXADataSource(pRoot, pJDBCProperties,pFakeXADataSourceComponentName); |
267 | else |
268 | GSATestUtils.createFakeXADataSource(pRoot,DBUtils.getHSQLDBInMemoryDBConnection(), pFakeXADataSourceComponentName); |
269 | if(pFakeXADataSourceComponentName == null && pJTDataSourceComponentName == null) |
270 | DBUtils.createJTDataSource(pRoot); |
271 | else |
272 | DBUtils.createJTDataSource(pRoot, pJTDataSourceComponentName, pFakeXADataSourceComponentName); |
273 | createGlobal(pRoot); |
274 | createScreenLog(pRoot, pLogging); |
275 | createIdSpaces(pRoot); |
276 | if(pJDBCProperties != null) |
277 | createIDGeneratorTables(new DBUtils(pJDBCProperties)); |
278 | else |
279 | createIDGeneratorTables(new DBUtils(DBUtils.getHSQLDBInMemoryDBConnection())); |
280 | createSQLRepositoryEventServer(pRoot); |
281 | createNucleus(pRoot); |
282 | |
283 | } |
284 | |
285 | // --------------------------- |
286 | /** |
287 | * Deletes any files created by initializing the configpath |
288 | * |
289 | */ |
290 | public void cleanup() { |
291 | Iterator<File> iter = mFilesCreated.iterator(); |
292 | while (iter.hasNext()) { |
293 | File f = iter.next(); |
294 | f.delete(); |
295 | } |
296 | mFilesCreated.clear(); |
297 | } |
298 | |
299 | // --------------------------- |
300 | /** |
301 | * Writes the idspaces.xml file |
302 | */ |
303 | public File createIdSpaces(File pRoot) throws IOException { |
304 | String idspaces = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE id-spaces SYSTEM \"http://www.atg.com/dtds/idgen/idgenerator_1.0.dtd\"><id-spaces><id-space name=\"__default__\" seed=\"1\" batch-size=\"100000\"/><id-space name=\"jms_msg_ids\" seed=\"0\" batch-size=\"10000\"/><id-space name=\"layer\" seed=\"0\" batch-size=\"100\"/></id-spaces>"; |
305 | File idspacesFile = new File(pRoot.getAbsolutePath() |
306 | + "/atg/dynamo/service/idspaces.xml"); |
307 | if (idspacesFile.exists()) |
308 | idspacesFile.delete(); |
309 | idspacesFile.getParentFile().mkdirs(); |
310 | idspacesFile.createNewFile(); |
311 | FileWriter out = new FileWriter(idspacesFile); |
312 | try { |
313 | out.write(idspaces); |
314 | out.write("\n"); |
315 | } |
316 | catch (IOException e) { |
317 | e.printStackTrace(); |
318 | |
319 | } |
320 | finally { |
321 | out.flush(); |
322 | out.close(); |
323 | } |
324 | return idspacesFile; |
325 | } |
326 | |
327 | // --------------------------------- |
328 | /** Creates Nucleus' Nucleus.properties |
329 | * |
330 | */ |
331 | public File createNucleus(File pRoot) throws IOException { |
332 | Properties prop = new Properties(); |
333 | prop.put("initialServiceName","/Initial"); |
334 | return NucleusTestUtils.createProperties("Nucleus", pRoot, "atg.nucleus.Nucleus", prop); |
335 | } |
336 | |
337 | |
338 | //--------------------------- |
339 | public static File createFakeXADataSource(File pRoot, |
340 | Properties pJDBCProperties, String pName) throws IOException { |
341 | /*---- # |
342 | * @version $Id: |
343 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/service/jdbc/FakeXADataSource.properties#3 |
344 | * $$Change: 410369 $ |
345 | * #------------------------------------------------------------------- |
346 | * #------------------------------------------------------------------- # |
347 | * This is a non-XA DataSource that creates simulated |
348 | * XAConnections. # It is useful when a true XADataSource cannot be |
349 | * obtained. Note that # the behaviour of the Connections will not |
350 | * be that of normal # XAConnections, i.e. they will not be able to |
351 | * participate in # two-phase commits in the true two-phase commit |
352 | * style. |
353 | * #------------------------------------------------------------------- |
354 | * |
355 | * $class=atg.service.jdbc.FakeXADataSource |
356 | * |
357 | * driver=solid.jdbc.SolidDriver URL=jdbc:solid://localhost:1313 user=admin |
358 | * password=admin |
359 | * |
360 | */ |
361 | String name = pName; |
362 | if (name == null) |
363 | name = "FakeXADataSource"; |
364 | pJDBCProperties.put("transactionManager", |
365 | "/atg/dynamo/transaction/TransactionManager"); |
366 | return NucleusTestUtils.createProperties(name, new File(pRoot |
367 | .getAbsolutePath() |
368 | + "/atg/dynamo/service/jdbc"), "atg.service.jdbc.FakeXADataSource", |
369 | pJDBCProperties); |
370 | } |
371 | |
372 | // --------------------------------- |
373 | /** |
374 | * @param pRoot |
375 | * @throws IOException |
376 | */ |
377 | public static File createJTDataSource(File pRoot) throws IOException { |
378 | return createJTDataSource(pRoot, null,null); |
379 | } |
380 | |
381 | // ------------------------------------ |
382 | /** |
383 | * Creates a new JTDataSource component. The name of the component may |
384 | * be specified by passing in a non null value for pName. |
385 | * Also the name of the FakeXADataSource may be specified by passing in a non null name. |
386 | * Otherwise the defaults are JTDataSource and FakeXADataSource. |
387 | * |
388 | * @param pRoot |
389 | * @param pName |
390 | * @param pFakeXAName |
391 | * @return |
392 | * @throws IOException |
393 | */ |
394 | public static File createJTDataSource(File pRoot, String pName, String pFakeXAName) |
395 | throws IOException { |
396 | /* |
397 | * ---- # |
398 | * |
399 | * @version $Id: |
400 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/service/jdbc/JTDataSource.properties#3 |
401 | * $$Change: 410369 $ |
402 | * #------------------------------------------------------------------- |
403 | * #------------------------------------------------------------------- # |
404 | * This is a pooling DataSource that creates Connections registered # |
405 | * with the calling threads current Transaction. It must always be # |
406 | * given a TransactionManager and an XADataSource. |
407 | * #------------------------------------------------------------------- |
408 | * |
409 | * $class=atg.service.jdbc.MonitoredDataSource # only use this data source |
410 | * if you do not have an JDBC driver # which provides true XA data sources |
411 | * dataSource=/atg/dynamo/service/jdbc/FakeXADataSource # Minimum and |
412 | * maximum number of connections to keep in the pool min=10 max=10 |
413 | * blocking=true |
414 | * |
415 | * #maxBlockTime= #maxCreateTime= #maxCreateAttempts= # # This will log any |
416 | * SQLWarnings that are generated. By default, we turn # these off since |
417 | * they tend to be informational, not really warnings. If # you want the |
418 | * full traceback for where these messages are generated, # set |
419 | * loggingWarning to true. # loggingSQLWarning=false # # The monitored |
420 | * connection by default logs all sql through the log info # path. # |
421 | * loggingSQLInfo=false |
422 | */ |
423 | String name = pName; |
424 | if (name == null) |
425 | name = "JTDataSource"; |
426 | |
427 | String fakeXAName = pFakeXAName; |
428 | if (fakeXAName == null) fakeXAName = |
429 | "FakeXADataSource"; |
430 | |
431 | Properties props = new Properties(); |
432 | props.put("dataSource", "/atg/dynamo/service/jdbc/" + fakeXAName); |
433 | props.put("transactionManager", |
434 | "/atg/dynamo/transaction/TransactionManager"); |
435 | props.put("min", "10"); |
436 | props.put("max", "20"); |
437 | props.put("blocking", "true"); |
438 | props.put("loggingSQLWarning", "false"); |
439 | props.put("loggingSQLInfo", "false"); |
440 | props.put("loggingSQLDebug", "false"); |
441 | |
442 | |
443 | return NucleusTestUtils.createProperties(name, new File(pRoot |
444 | .getAbsolutePath() |
445 | + "/atg/dynamo/service/jdbc"), "atg.service.jdbc.MonitoredDataSource", |
446 | props); |
447 | } |
448 | |
449 | // --------------------------------- |
450 | /** |
451 | * Creates a SQLRepositoryEventServer |
452 | * |
453 | * @param pRoot |
454 | * @return |
455 | */ |
456 | public File createSQLRepositoryEventServer(File pRoot) |
457 | throws IOException { |
458 | |
459 | Properties prop = new Properties(); |
460 | prop.put("handlerCount", "0"); |
461 | return NucleusTestUtils.createProperties("SQLRepositoryEventServer", |
462 | new File(pRoot.getAbsolutePath() + "/atg/dynamo/server"), |
463 | "atg.adapter.gsa.event.GSAEventServer", prop); |
464 | } |
465 | |
466 | // --------------------------- |
467 | /** |
468 | * Creates a ScreenLog component |
469 | * |
470 | * @param pRoot |
471 | * @param pLogging TODO |
472 | * @return |
473 | * @throws IOException |
474 | */ |
475 | public File createScreenLog(File pRoot, boolean pLogging) throws IOException { |
476 | Properties prop = new Properties(); |
477 | prop.put("cropStackTrace", "false"); |
478 | prop.put("loggingEnabled", String.valueOf(pLogging)); |
479 | return NucleusTestUtils.createProperties("ScreenLog", new File(pRoot |
480 | .getAbsolutePath() |
481 | + "/atg/dynamo/service/logging"), |
482 | "atg.nucleus.logging.PrintStreamLogger", prop); |
483 | } |
484 | |
485 | // --------------------------- |
486 | /** |
487 | * Creates a GLOBAL.properties |
488 | * |
489 | * @param pRoot |
490 | * @param pJDBCProperties |
491 | * @return |
492 | * @throws IOException |
493 | */ |
494 | public File createGlobal(File pRoot) throws IOException { |
495 | Properties prop = new Properties(); |
496 | prop.put("logListeners", "atg/dynamo/service/logging/ScreenLog"); |
497 | prop.put("loggingDebug","false"); |
498 | return NucleusTestUtils.createProperties("GLOBAL", new File(pRoot |
499 | .getAbsolutePath() |
500 | + "/"), null, prop); |
501 | |
502 | } |
503 | |
504 | // --------------------------------- |
505 | /** |
506 | * @param pRoot |
507 | * @throws IOException |
508 | */ |
509 | public File createClientLockManager(File pRoot) throws IOException { |
510 | /* |
511 | * @version $Id: |
512 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/service/ClientLockManager.properties#3 |
513 | * $$Change: 410369 $ |
514 | * $class=atg.service.lockmanager.ClientLockManager |
515 | * lockServerAddress=localhost lockServerPort=9010 |
516 | * useLockServer=false |
517 | */ |
518 | Properties props = new Properties(); |
519 | props.put("lockServerAddress", "localhost"); |
520 | props.put("lockServerPort", "9010"); |
521 | props.put("useLockServer", "false"); |
522 | return NucleusTestUtils.createProperties("ClientLockManager", new File( |
523 | pRoot.getAbsolutePath() + "/atg/dynamo/service"), |
524 | "atg.service.lockmanager.ClientLockManager", props); |
525 | } |
526 | // --------------------------------- |
527 | /** |
528 | * @param pRoot |
529 | * @throws IOException |
530 | */ |
531 | public File createIdGenerator(File pRoot) throws IOException { |
532 | /* |
533 | * @version $Id: |
534 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/service/IdGenerator.properties#3 |
535 | * $$Change: 410369 $ |
536 | * #------------------------------------------------------------------- |
537 | * #------------------------------------------------------------------- # |
538 | * Default id generator service. This service generates ids using |
539 | * an # SQL database table. The ids are suitable for use with |
540 | * persistent # objects. |
541 | * #------------------------------------------------------------------- |
542 | * |
543 | * $class=atg.service.idgen.SQLIdGenerator |
544 | * |
545 | * dataSource=/atg/dynamo/service/jdbc/JTDataSource |
546 | * transactionManager=/atg/dynamo/transaction/TransactionManager |
547 | * XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory # all properties |
548 | * of type XMLFile *MUST* use an absolute # component path. Applications |
549 | * should append generally # append to this property. |
550 | * initialIdSpaces=/atg/dynamo/service/idspaces.xml |
551 | * |
552 | * ---- # |
553 | */ |
554 | Properties props = new Properties(); |
555 | props.put("dataSource", "/atg/dynamo/service/jdbc/JTDataSource"); |
556 | props.put("transactionManager", |
557 | "/atg/dynamo/transaction/TransactionManager"); |
558 | props.put("XMLToolsFactory", "/atg/dynamo/service/xml/XMLToolsFactory"); |
559 | // props.put("initialIdSpaces", "/atg/dynamo/service/idspaces.xml "); |
560 | return NucleusTestUtils.createProperties("IdGenerator", new File(pRoot |
561 | .getAbsolutePath() |
562 | + "/atg/dynamo/service/"), "atg.service.idgen.SQLIdGenerator", props); |
563 | } |
564 | // --------------------------------- |
565 | /** |
566 | * @param pRoot |
567 | * @throws IOException |
568 | */ |
569 | public File createXMLToolsFactory(File pRoot) throws IOException { |
570 | /* |
571 | * ---- # |
572 | * |
573 | * @version $Id: |
574 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/service/xml/XMLToolsFactory.properties#3 |
575 | * $$Change: 410369 $ |
576 | * $class=atg.xml.tools.apache.ApacheXMLToolsFactory $scope=global |
577 | * parserFeatures= |
578 | * |
579 | * ---- # |
580 | */ |
581 | File root = new File(pRoot.getAbsolutePath() + "/atg/dynamo/service/xml"); |
582 | return NucleusTestUtils.createProperties("XMLToolsFactory", root, |
583 | "atg.xml.tools.apache.ApacheXMLToolsFactory", new Properties()); |
584 | } |
585 | // --------------------------------- |
586 | /** |
587 | * @param pRoot |
588 | * @throws IOException |
589 | */ |
590 | public File createTransactionManager(File pRoot) throws IOException { |
591 | /* |
592 | * * |
593 | * |
594 | * @version $Id: |
595 | * //product/DAS/main/templates/DAS/config/config/atg/dynamo/transaction/TransactionManager.properties#3 |
596 | * $$Change: 410369 $ ############################## # # The Dynamo |
597 | * implementation of javax.transaction.TransactionManager # |
598 | * |
599 | * $class=atg.dtm.TransactionManagerImpl |
600 | */ |
601 | Properties props = new Properties(); |
602 | props.put("loggingDebug","false"); |
603 | File root = new File(pRoot, "/atg/dynamo/transaction"); |
604 | root.mkdirs(); |
605 | NucleusTestUtils.createProperties("TransactionDemarcationLogging", root, |
606 | "atg.dtm.TransactionDemarcationLogging", props); |
607 | |
608 | return NucleusTestUtils.createProperties("TransactionManager", root, |
609 | "atg.dtm.TransactionManagerImpl", props); |
610 | } |
611 | // --------------------------------- |
612 | /** |
613 | * Creates the UserTransaction component |
614 | */ |
615 | public File createUserTransaction(File pRoot) throws IOException { |
616 | Properties props = new Properties(); |
617 | props.put("transactionManager","/atg/dynamo/transaction/TransactionManager"); |
618 | return NucleusTestUtils.createProperties("UserTransaction",new File(pRoot,"/atg/dynamo/transaction"),"atg.dtm.UserTransactionImpl",props); |
619 | } |
620 | |
621 | // --------------------------------- |
622 | /** |
623 | * Creates a .properties file for the given repository. |
624 | * The actual repository implementation is a |
625 | * <code>atg.adapter.gsa.InitializingGSA</code> class. |
626 | * This implementation is used instead because it has the ability |
627 | * to create tables and import data before the repository starts. |
628 | * @param pRoot |
629 | * @param pRepositoryPath |
630 | * @param pDefinitionFiles |
631 | * @param pSQLAbsolutePath |
632 | * @param pDropSQLAbsolutePath |
633 | * @param pImportFiles |
634 | * @throws IOException |
635 | */ |
636 | public File createRepositoryPropertiesFile(File pRoot, |
637 | String pRepositoryPath, String[] pDefinitionFiles, String pCreateSQLAbsolutePath, String pDropSQLAbsolutePath, String[] pImportFiles) throws IOException { |
638 | return createRepositoryPropertiesFile(pRoot, pRepositoryPath, pDefinitionFiles, pCreateSQLAbsolutePath, pDropSQLAbsolutePath, pImportFiles, null); |
639 | } |
640 | // --------------------------------- |
641 | /** |
642 | * Creates a .properties file for the given repository. |
643 | * The actual repository implementation is a |
644 | * <code>atg.adapter.gsa.InitializingGSA</code> class. |
645 | * This implementation is used instead because it has the ability |
646 | * to create tables and import data before the repository starts. |
647 | * @param pRoot |
648 | * @param pRepositoryPath |
649 | * @param pDefinitionFiles |
650 | * @param pSQLAbsolutePath |
651 | * @param pDropSQLAbsolutePath |
652 | * @param pImportFiles |
653 | * @throws IOException |
654 | */ |
655 | public File createRepositoryPropertiesFile(File pRoot, |
656 | String pRepositoryPath, String[] pDefinitionFiles, String pCreateSQLAbsolutePath, String pDropSQLAbsolutePath, String[] pImportFiles, String pJTDataSourceName) throws IOException { |
657 | /* |
658 | * # |
659 | * |
660 | * @version $Id: //test/UnitTests/base/main/src/Java/atg/adapter/gsa/GSATestUtils.java#28 $$Change: 410369 $ $class=atg.adapter.gsa.GSARepository |
661 | * |
662 | * repositoryName=RefRepository definitionFiles=/atg/repository/lv/ref.xml |
663 | * XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory |
664 | * transactionManager=/atg/dynamo/transaction/TransactionManager |
665 | * idGenerator=/atg/dynamo/service/IdGenerator |
666 | * dataSource=/atg/dynamo/service/jdbc/JTDataSource |
667 | * lockManager=/atg/dynamo/service/ClientLockManager |
668 | * groupContainerPath=/atg/registry/RepositoryGroups |
669 | * useSetUnicodeStream=true ---- # |
670 | */ |
671 | // String clazz = "atg.adapter.gsa.GSARepository"; |
672 | String clazz = sClassName; |
673 | if(mVersioned) |
674 | clazz = sVersionedClassName; |
675 | |
676 | Properties props = new Properties(); |
677 | props.put("repositoryName", "TestRepository"+System.currentTimeMillis()); |
678 | StringBuffer definitionFiles = new StringBuffer(); |
679 | for (int i = 0; i < pDefinitionFiles.length; i++) { |
680 | Object obj = this.getClass().getClassLoader().getResource(pDefinitionFiles[i]); |
681 | if (obj != null) { |
682 | log.debug("Repository definition file " |
683 | + pDefinitionFiles[i] |
684 | + " Does not exist in configpath. But it does in classpath. Copying over to configpath"); |
685 | copyToConfigpath(pRoot, pDefinitionFiles[i]); |
686 | } else if(obj == null && !new File(pRoot, pDefinitionFiles[i]).exists()){ |
687 | throw new AssertionError("ERROR: Repository definition file " |
688 | + pDefinitionFiles[i] + " not found in classpath or configpath: " + pRoot); |
689 | } |
690 | |
691 | definitionFiles.append("/"+pDefinitionFiles[i]); |
692 | if (i < (pDefinitionFiles.length - 1)) |
693 | definitionFiles.append(","); |
694 | } |
695 | props.put("definitionFiles", definitionFiles.toString()); |
696 | if(pImportFiles != null){ |
697 | StringBuffer importFiles = new StringBuffer(); |
698 | for (int i = 0; i < pImportFiles.length; i++) { |
699 | Object obj = this.getClass().getClassLoader().getResource( |
700 | pDefinitionFiles[i]); |
701 | if (obj != null) { |
702 | System.out |
703 | .println("DEBUG: import file " |
704 | + pDefinitionFiles[i] |
705 | + " Does not exist in configpath. But it does in classpath. Copying over to configpath"); |
706 | copyToConfigpath(pRoot, pImportFiles[i]); |
707 | } else if (obj == null && !new File(pRoot, pImportFiles[i]).exists()) { |
708 | throw new AssertionError("ERROR: Repository definition file " |
709 | + pDefinitionFiles[i] + " not found in classpath or configpath."); |
710 | } |
711 | |
712 | importFiles.append(new File(pRoot, pImportFiles[i]).getAbsolutePath()); |
713 | if (i < (pImportFiles.length - 1)) |
714 | importFiles.append(","); |
715 | } |
716 | props.put("importFiles", importFiles.toString()); |
717 | props.put("importEveryStartup", "true"); |
718 | } |
719 | props.put("XMLToolsFactory", "/atg/dynamo/service/xml/XMLToolsFactory"); |
720 | props.put("transactionManager", |
721 | "/atg/dynamo/transaction/TransactionManager"); |
722 | props.put("idGenerator", "/atg/dynamo/service/IdGenerator"); |
723 | if(pJTDataSourceName == null) |
724 | props.put("dataSource", "/atg/dynamo/service/jdbc/JTDataSource"); |
725 | else |
726 | props.put("dataSource", "/atg/dynamo/service/jdbc/"+pJTDataSourceName); |
727 | props.put("lockManager", "/atg/dynamo/service/ClientLockManager"); |
728 | props.put("idspaces", "/atg/dynamo/service/idspaces.xml"); |
729 | props.put("groupContainerPath", "/atg/registry/RepositoryGroups"); |
730 | props.put("restartingAfterTableCreation", "false"); |
731 | props.put("createTables", "true"); |
732 | props.put("loggingError", "true"); |
733 | if(pCreateSQLAbsolutePath != null) |
734 | props.put("sqlCreateFiles","default="+pCreateSQLAbsolutePath); |
735 | |
736 | if(pDropSQLAbsolutePath != null) |
737 | props.put("sqlDropFiles","default="+pDropSQLAbsolutePath); |
738 | props.put("loggingDebug", "false"); |
739 | props.put("loggingCreateTables", "false"); |
740 | // props.put("debugLevel", "7"); |
741 | |
742 | // InitializingGSA specific properties |
743 | props.put("dropTablesIfExist", "true"); |
744 | props.put("dropTablesAtShutdown", "false"); |
745 | props.put("stripReferences","true"); |
746 | int endIndex = pRepositoryPath.lastIndexOf("/"); |
747 | String repositoryDir = pRepositoryPath.substring(0, endIndex); |
748 | String repositoryName = pRepositoryPath.substring(endIndex + 1, |
749 | pRepositoryPath.length()); |
750 | File root = new File(pRoot, repositoryDir); |
751 | root.mkdirs(); |
752 | |
753 | if(mVersioned) props.putAll(additionalVersionProperties(pRoot,pRepositoryPath, repositoryName)); |
754 | return NucleusTestUtils |
755 | .createProperties(repositoryName, root, clazz, props); |
756 | } |
757 | |
758 | /** |
759 | * @param pRoot |
760 | * @param pRepositoryPath |
761 | * @param pRepositoryName |
762 | * @return |
763 | * @throws IOException |
764 | */ |
765 | protected Map<String, String> additionalVersionProperties(File pRoot, String pRepositoryPath, String pRepositoryName) throws IOException { |
766 | |
767 | copyToConfigpath(pRoot, "atg/adapter/version/versionmanager/versionManagerRepository.xml"); |
768 | GSATestUtils.getGSATestUtils() |
769 | .createRepositoryPropertiesFile( |
770 | pRoot, |
771 | "/atg/adapter/version/versionmanager/VersionManagerRepository", |
772 | new String[] { "/atg/adapter/version/versionmanager/versionManagerRepository.xml" }, null, null, null); |
773 | // create the AssetFactory |
774 | NucleusTestUtils |
775 | .createProperties("/atg/adapter/version/versionmanager/AssetFactory", pRoot, "atg.versionmanager.impl.AssetFactoryRepositoryImpl", null); |
776 | // create the AssetVersionFactory |
777 | NucleusTestUtils |
778 | .createProperties("/atg/adapter/version/versionmanager/AssetVersionFactory", pRoot, "atg.versionmanager.impl.AssetVersionFactoryRepositoryImpl", null); |
779 | |
780 | NucleusTestUtils |
781 | .createProperties("/atg/adapter/version/versionmanager/BranchFactory", pRoot, "atg.versionmanager.impl.BranchFactoryRepositoryImpl", null); |
782 | |
783 | NucleusTestUtils |
784 | .createProperties("/atg/adapter/version/versionmanager/DevelopmentLineFactory", pRoot, "atg.versionmanager.impl.DevelopmentLineFactoryRepositoryImpl", null); |
785 | |
786 | NucleusTestUtils |
787 | .createProperties("/atg/adapter/version/versionmanager/SnapshotFactory", pRoot, "atg.versionmanager.impl.SnapshotFactoryRepositoryImpl", null); |
788 | |
789 | NucleusTestUtils |
790 | .createProperties("/atg/adapter/version/versionmanager/WorkspaceFactory", pRoot, "atg.versionmanager.impl.WorkspaceFactoryRepositoryImpl", null); |
791 | Properties props = new Properties(); |
792 | |
793 | props.put("assetFactory","AssetFactory"); |
794 | props.put("repository","VersionManagerRepository"); |
795 | props.put("branchFactory","BranchFactory"); |
796 | props.put("developmentLineFactory","DevelopmentLineFactory"); |
797 | props.put("snapshotFactory","SnapshotFactory"); |
798 | props.put("assetVersionFactory","AssetVersionFactory"); |
799 | props.put("workspaceFactory","WorkspaceFactory"); |
800 | props.put("versionedRepositories",pRepositoryName+"="+pRepositoryPath); |
801 | props.put("sendCheckinEvents","false"); |
802 | props.put("clientLockManager","/atg/dynamo/service/ClientLockManager"); |
803 | |
804 | NucleusTestUtils |
805 | .createProperties("/atg/adapter/version/versionmanager/VersionManagerService", pRoot, "atg.versionmanager.VersionManager", props); |
806 | |
807 | //create a version manager and version manager repository |
808 | //createVersionManager(); |
809 | Map<String, String> extraProps= new HashMap<String, String>(); |
810 | props.put("versionManager", "/atg/adapter/version/versionmanager/VersionManagerService"); |
811 | props.put("versionItemsByDefault", "true"); |
812 | return extraProps; |
813 | } |
814 | |
815 | /** |
816 | * @param prop |
817 | * @throws FileNotFoundException |
818 | * @throws IOException |
819 | */ |
820 | public void copyToConfigpath(File pConfigRoot, String pString) throws FileNotFoundException, IOException { |
821 | copyToConfigpath(pConfigRoot, pString, null); |
822 | } |
823 | |
824 | /** |
825 | * @param prop |
826 | * @param configPath where in config path the file must be copied. |
827 | * @throws FileNotFoundException |
828 | * @throws IOException |
829 | */ |
830 | public void copyToConfigpath(File pConfigRoot, String pString, String configPath) throws FileNotFoundException, IOException { |
831 | // create the version manager repository |
832 | pConfigRoot.mkdirs(); |
833 | String path = pString; |
834 | if(configPath == null) |
835 | configPath = path.substring(0, path.lastIndexOf('/')); |
836 | File dir = new File(pConfigRoot, configPath); |
837 | dir.mkdirs(); |
838 | File prop = new File(dir, path.substring(path.lastIndexOf('/'))); |
839 | if (prop.exists()) prop.delete(); |
840 | prop.createNewFile(); |
841 | OutputStream os = new FileOutputStream(prop); |
842 | InputStream dataStream = this.getClass().getClassLoader().getResourceAsStream(pString); |
843 | while(dataStream.available() != 0){ |
844 | byte[] buff = new byte[1024]; |
845 | int available = dataStream.available(); |
846 | dataStream.read(buff); |
847 | os.write(buff, 0, available >= 1024 ? 1024: available); |
848 | } |
849 | os.flush(); |
850 | } |
851 | |
852 | //--------------------------------- |
853 | /** |
854 | * Creates a .properties file for the given repository. |
855 | * The actual repository implementation is a |
856 | * <code>atg.adapter.gsa.InitializingGSA</code> class. |
857 | * This implementation is used instead because it has the ability |
858 | * to create tables and import data before the repository starts. |
859 | * @param pRoot |
860 | * @param pRepositoryPath |
861 | * @param pDefinitionFiles |
862 | * @throws IOException |
863 | */ |
864 | public File createVersionRepositoryPropertiesFile(File pRoot, |
865 | String pRepositoryPath, String[] pDefinitionFiles) throws IOException { |
866 | /* |
867 | * # |
868 | * |
869 | * @version $Id: //test/UnitTests/base/main/src/Java/atg/adapter/gsa/GSATestUtils.java#28 $$Change: 410369 $ $class=atg.adapter.gsa.GSARepository |
870 | * |
871 | * repositoryName=RefRepository definitionFiles=/atg/repository/lv/ref.xml |
872 | * XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory |
873 | * transactionManager=/atg/dynamo/transaction/TransactionManager |
874 | * idGenerator=/atg/dynamo/service/IdGenerator |
875 | * dataSource=/atg/dynamo/service/jdbc/JTDataSource |
876 | * lockManager=/atg/dynamo/service/ClientLockManager |
877 | * groupContainerPath=/atg/registry/RepositoryGroups |
878 | * useSetUnicodeStream=true ---- # |
879 | */ |
880 | // String clazz = "atg.adapter.gsa.GSARepository"; |
881 | String clazz = "atg.adapter.gsa.InitializingVersionRepository"; |
882 | Properties props = new Properties(); |
883 | props.put("repositoryName", "TestRepository"); |
884 | StringBuffer definitionFiles = new StringBuffer(); |
885 | for (int i = 0; i < pDefinitionFiles.length; i++) { |
886 | definitionFiles.append(pDefinitionFiles[i]); |
887 | if (i < (pDefinitionFiles.length - 1)) |
888 | definitionFiles.append(","); |
889 | } |
890 | props.put("definitionFiles", definitionFiles.toString()); |
891 | props.put("XMLToolsFactory", "/atg/dynamo/service/xml/XMLToolsFactory"); |
892 | props.put("transactionManager", |
893 | "/atg/dynamo/transaction/TransactionManager"); |
894 | props.put("idGenerator", "/atg/dynamo/service/IdGenerator"); |
895 | props.put("dataSource", "/atg/dynamo/service/jdbc/JTDataSource"); |
896 | props.put("lockManager", "/atg/dynamo/service/ClientLockManager"); |
897 | props.put("groupContainerPath", "/atg/registry/RepositoryGroups"); |
898 | props.put("versionManager", "/atg/test/version/VersionManager"); |
899 | props.put("versionItemByDefault", "true"); |
900 | props.put("loggingDebug", "true"); |
901 | // props.put("debugLevel", "7"); |
902 | |
903 | // InitializingGSA specific properties |
904 | props.put("dropTablesIfExist", "true"); |
905 | props.put("dropTablesAtShutdown", "false"); |
906 | props.put("stripReferences","true"); |
907 | int endIndex = pRepositoryPath.lastIndexOf("/"); |
908 | String repositoryDir = pRepositoryPath.substring(0, endIndex); |
909 | String repositoryName = pRepositoryPath.substring(endIndex + 1, |
910 | pRepositoryPath.length()); |
911 | File root = new File(pRoot, repositoryDir); |
912 | root.mkdirs(); |
913 | |
914 | ; |
915 | |
916 | return NucleusTestUtils |
917 | .createProperties(repositoryName, root, clazz, props); |
918 | } |
919 | |
920 | // --------------------------------- |
921 | /** |
922 | * Returns all the tables names used for the given repository. |
923 | */ |
924 | public String [] getTableNames(GSARepository pRepository) throws Exception { |
925 | ArrayList<String> names = new ArrayList<String>(); |
926 | String[] descriptorNames = pRepository.getItemDescriptorNames(); |
927 | |
928 | GSAItemDescriptor itemDescriptors[]; |
929 | |
930 | int i, length = descriptorNames.length; |
931 | |
932 | itemDescriptors = new GSAItemDescriptor[length]; |
933 | for (i=0; i<length; i++) { |
934 | itemDescriptors[i] = (GSAItemDescriptor)pRepository.getItemDescriptor(descriptorNames[i]); |
935 | } |
936 | |
937 | // String create = null; |
938 | // String index = null; |
939 | for (i=0; i<length; i++) { |
940 | GSAItemDescriptor desc = itemDescriptors[i]; |
941 | Table[] tables = desc.getTables(); |
942 | if ( tables != null ) { |
943 | for (int j = 0; j < tables.length; j++) { |
944 | String name = tables[j].getName(); |
945 | names.add(name); |
946 | } |
947 | } |
948 | } |
949 | return (String[])names.toArray(new String[0]); |
950 | } |
951 | // --------------------------------- |
952 | /** |
953 | * Given a repository, and the DBUtils object used to create the connection for that |
954 | * Repository, this method asserts that all the tables are empty |
955 | * @param dbTwo |
956 | * @param storeRepository |
957 | * @throws Exception |
958 | * @throws SQLException |
959 | */ |
960 | public void assertEmptyRepository(DBUtils dbTwo, GSARepository storeRepository) throws Exception, SQLException { |
961 | String [] namesAfter = getTableNames(storeRepository); |
962 | for (int i = 0 ; i < namesAfter.length; i++) { |
963 | log.info(namesAfter[i] + ":" + dbTwo.getRowCount(namesAfter[i])); |
964 | Assert.assertEquals(0,dbTwo.getRowCount(namesAfter[i])); |
965 | } |
966 | } |
967 | // --------------------------------- |
968 | /** |
969 | * Creates the das_id_generator tables using the given database |
970 | * @param db |
971 | * @throws SQLException |
972 | */ |
973 | public void createIDGeneratorTables(DBUtils db) throws SQLException { |
974 | try { |
975 | if(!db.isDB2()) |
976 | db |
977 | .update(" create table das_id_generator (id_space_name varchar(60) not null," |
978 | + "seed numeric(19,0) not null, batch_size integer not null, prefix varchar(10) null," |
979 | + " suffix varchar(10) null, primary key (id_space_name)) "); |
980 | else |
981 | db |
982 | .update(" create table das_id_generator (id_space_name varchar(60) not null," |
983 | + "seed numeric(19,0) not null, batch_size integer not null, prefix varchar(10) default null," |
984 | + " suffix varchar(10) default null, primary key (id_space_name)) "); |
985 | } |
986 | catch (SQLException e) { |
987 | // drop and try again |
988 | log.info("DROPPING DAS_ID_GENERATOR"); |
989 | db.update("drop table das_id_generator"); |
990 | if(!db.isDB2()) |
991 | db |
992 | .update(" create table das_id_generator (id_space_name varchar(60) not null," |
993 | + "seed numeric(19,0) not null, batch_size integer not null, prefix varchar(10) null," |
994 | + " suffix varchar(10) null, primary key (id_space_name)) "); |
995 | else |
996 | db |
997 | .update(" create table das_id_generator (id_space_name varchar(60) not null," |
998 | + "seed numeric(19,0) not null, batch_size integer not null, prefix varchar(10) default null," |
999 | + " suffix varchar(10) default null, primary key (id_space_name)) "); |
1000 | |
1001 | |
1002 | } |
1003 | } |
1004 | |
1005 | /** |
1006 | * @param pVerRep |
1007 | * @param pImportFiles |
1008 | * @param pWorkspaceName |
1009 | * @param pDoWithoutTransaction |
1010 | * @param pWorkspaceComment |
1011 | * @throws VersionException |
1012 | */ |
1013 | public static void importFiles(VersionRepository pVerRep, |
1014 | String[] pImportFiles, String pWorkspaceName, boolean pDoWithoutTransaction, |
1015 | String pWorkspaceComment, boolean pCheckin) throws VersionException { |
1016 | VersionManager vm = pVerRep.getVersionManager(); |
1017 | Workspace ws = vm.getWorkspaceByName(pWorkspaceName); |
1018 | if (ws == null) |
1019 | throw new IllegalArgumentException("No such workspace " + pWorkspaceName); |
1020 | |
1021 | if(TemplateParser.importFiles(pVerRep, pImportFiles, new PrintWriter( |
1022 | System.out), pDoWithoutTransaction, VersioningContextUtil.createVersioningContext(ws |
1023 | .getName(), pWorkspaceComment, pCheckin)) != 0) |
1024 | throw new AssertionError("Versioned import failed"); |
1025 | } |
1026 | |
1027 | /** |
1028 | * @return |
1029 | */ |
1030 | public static GSATestUtils getGSATestUtils() { |
1031 | if(SINGLETON_DEFAULT == null) |
1032 | SINGLETON_DEFAULT = new GSATestUtils(false); |
1033 | return SINGLETON_DEFAULT; |
1034 | } |
1035 | |
1036 | /** |
1037 | * @return |
1038 | */ |
1039 | public static GSATestUtils getVersionedGSATestUtils() { |
1040 | if(SINGLETON_VERSIONED == null) |
1041 | SINGLETON_VERSIONED = new GSATestUtils(true); |
1042 | return SINGLETON_VERSIONED; |
1043 | |
1044 | } |
1045 | |
1046 | |
1047 | /** |
1048 | * Dump all the data from a table to the console |
1049 | * @param pTable |
1050 | * @throws SQLException |
1051 | */ |
1052 | public static void dumpTable(Table pTable, Collection<String> pPrintColumnNames) throws SQLException { |
1053 | GSARepository gsa = pTable.getItemDescriptor().getGSARepository(); |
1054 | Connection c = null; |
1055 | PreparedStatement st = null; |
1056 | try { |
1057 | c = gsa.getConnection(); |
1058 | pTable.loadColumnInfo(c); |
1059 | Collection<?> colNames = pPrintColumnNames; |
1060 | Map<?, ?> map = ((Map<?, ?>) gsa.getColumnInfoCache().get( |
1061 | pTable.mName)); |
1062 | if(map == null) |
1063 | map = ((Map<?, ?>) gsa.getColumnInfoCache().get( |
1064 | pTable.mName.toUpperCase())); |
1065 | if(pPrintColumnNames.isEmpty()) |
1066 | colNames = map.keySet(); |
1067 | Iterator<?> iter0 = colNames.iterator(); |
1068 | String sql = "SELECT "; |
1069 | while (iter0.hasNext()) { |
1070 | Object obj = iter0.next(); |
1071 | if (iter0.hasNext()) |
1072 | sql += obj + ","; |
1073 | else |
1074 | sql += obj; |
1075 | } |
1076 | sql += " FROM " + pTable.getBaseName(); |
1077 | st = c.prepareStatement(sql); |
1078 | ResultSet rs = st.executeQuery(); |
1079 | System.out.print("DUMP FOR TABLE: " + pTable.getBaseName().toUpperCase() |
1080 | + "\n"); |
1081 | Iterator<?> iter1 = colNames.iterator(); |
1082 | int truncateThreshold = 20; |
1083 | while (iter1.hasNext()) { |
1084 | String colname = (String)iter1.next(); |
1085 | System.out.print( colname.substring(0, colname.length() > 18 ? 18:colname.length())); |
1086 | for (int i = 0; i < truncateThreshold-colname.length(); i++) { |
1087 | System.out.print(" "); |
1088 | } |
1089 | System.out.print(" "); |
1090 | } |
1091 | System.out.print("\n"); |
1092 | while (rs.next()) { |
1093 | int i = 1; |
1094 | Iterator<?> iter = colNames.iterator(); |
1095 | while (iter.hasNext()) { |
1096 | //String columnName = iter.next(); |
1097 | iter.next(); |
1098 | Object obj = rs.getObject(i++); |
1099 | if(obj == null) obj = "NULL"; |
1100 | System.out.print( obj.toString().substring(0, obj.toString().length() > truncateThreshold ? truncateThreshold:obj.toString().length())); |
1101 | for (int j = 0; j < truncateThreshold-obj.toString().length(); j++) { |
1102 | System.out.print(" "); |
1103 | } |
1104 | System.out.print(" "); |
1105 | // for (int j = 0; j < columnName.length() - obj.toString().length(); j++) { |
1106 | // System.out.print(" "); |
1107 | // } |
1108 | // System.out.print(obj.toString().substring(0, (obj.toString().length() > columnName.length()+18 ? columnName.length(): obj.toString().length()) ) + " "); |
1109 | } |
1110 | } |
1111 | } finally { |
1112 | if (st != null) |
1113 | st.close(); |
1114 | } |
1115 | } |
1116 | |
1117 | /** |
1118 | * @param pVersionRepository |
1119 | * @param pString |
1120 | */ |
1121 | public static void dumpTables(GSARepository pRepository, String pItemDescriptorName) throws RepositoryException, SQLException { |
1122 | GSAItemDescriptor itemdesc = (GSAItemDescriptor) pRepository.getItemDescriptor(pItemDescriptorName); |
1123 | Table[] tables = itemdesc.getTables(); |
1124 | HashSet<String> doneTables = new HashSet<String>(); |
1125 | for (int i = 0; tables != null && i < tables.length; i++) { |
1126 | Table table = tables[i]; |
1127 | if(doneTables.contains(table.getName())) continue; |
1128 | dumpTable(table, new ArrayList<String>()); |
1129 | doneTables.add(table.getName()); |
1130 | } |
1131 | } |
1132 | } |