| 1 | | (1) | package org.jcoderz.testdata; |
| 2 | | | |
| 3 | | | import java.io.File; |
| 4 | | | import java.io.IOException; |
| 5 | | | import java.io.InputStream; |
| 6 | | | import java.sql.Connection; |
| 7 | | | import java.sql.DriverManager; |
| 8 | | | import java.sql.ResultSet; |
| 9 | | | import java.sql.SQLException; |
| 10 | | | import java.sql.SQLWarning; |
| 11 | | | import java.sql.Statement; |
| 12 | | | import java.util.ArrayList; |
| 13 | | | import java.util.Collection; |
| 14 | | | import java.util.HashMap; |
| 15 | | | import java.util.HashSet; |
| 16 | | | import java.util.Iterator; |
| 17 | | | import java.util.List; |
| 18 | | | import java.util.Locale; |
| 19 | | | import java.util.Map; |
| 20 | | | import java.util.Properties; |
| 21 | | | import java.util.Set; |
| 22 | | | import java.util.logging.Level; |
| 23 | | | import java.util.logging.Logger; |
| 24 | | | |
| 25 | | | import nu.xom.Builder; |
| 26 | | | import nu.xom.Document; |
| 27 | | | import nu.xom.Element; |
| 28 | | | import nu.xom.Node; |
| 29 | | | import nu.xom.Nodes; |
| 30 | | | import nu.xom.XPathContext; |
| 31 | | | import nu.xom.xinclude.XIncluder; |
| 32 | | | |
| 33 | | | import org.hibernate.SessionFactory; |
| 34 | | | import org.hibernate.cfg.Configuration; |
| 35 | | | import org.hibernate.mapping.Table; |
| 36 | | | |
| 37 | | | |
| 38 | | (2) | |
| 39 | | (3) | |
| 40 | | (4) | |
| 41 | | | |
| 42 | | | |
| 43 | | | @author |
| 44 | | | |
| 45 | | (5) | public class Importer { |
| 46 | | | |
| 47 | | | private static final int ERROR_EXIT_CODE = 20; |
| 48 | | | |
| 49 | | | private static final String DEFAULT_TABLE_PREFIX = "S0IR_"; |
| 50 | | | |
| 51 | | | private static final long DEFAULT_SEQUENCE_BASE = 100000L; |
| 52 | | | |
| 53 | | | private static final String SUFFIX_XML = ".xml"; |
| 54 | | | |
| 55 | | | private static final String FILE_SEPARATOR = "/"; |
| 56 | | | |
| 57 | 0 | | private static final XPathContext TD_CONTEXT = new XPathContext("td", |
| 58 | | | "http://jcoderz.org/test-data"); |
| 59 | | | |
| 60 | 0 | (6) | static final Logger logger = Logger.getLogger(Importer.class.getName()); |
| 61 | | | |
| 62 | | (7) | private String tablePrefix; |
| 63 | | (8) | private long sequenceBase; |
| 64 | | | |
| 65 | | (9) | private Connection connection; |
| 66 | | | |
| 67 | | | |
| 68 | | | |
| 69 | | | |
| 70 | | | @param |
| 71 | | | |
| 72 | | (10)(11)(12)(13) | public static void main(String[] args) { |
| 73 | | | |
| 74 | 0 | (14) | if (args.length < 1) { |
| 75 | 0 | | System.out.println("Usage: " + Importer.class.getName() |
| 76 | | | + " <sourceDirectory>"); |
| 77 | | | } |
| 78 | | | |
| 79 | 0 | (15) | String sourceDirectory = args[0]; |
| 80 | | | |
| 81 | 0 | | Properties properties = new Properties(); |
| 82 | 0 | (16) | List<String> tableNames = new ArrayList<String>(); |
| 83 | | | |
| 84 | 0 | | logger.info("Starting import ..."); |
| 85 | | | |
| 86 | 0 | | Locale.setDefault(Locale.GERMANY); |
| 87 | | | |
| 88 | | (17) | try { |
| 89 | 0 | (18) | String defaultPropertiesName = "/testdata.properties"; |
| 90 | | | |
| 91 | 0 | (19) | InputStream defaultInput = Importer.class |
| 92 | | | .getResourceAsStream(defaultPropertiesName); |
| 93 | 0 | (20) | if (defaultInput != null) { |
| 94 | 0 | (21) | logger.fine("Loading default properties (" + defaultPropertiesName + ")"); |
| 95 | 0 | | properties.load(defaultInput); |
| 96 | | (22)(23) | } else { |
| 97 | 0 | | logger.fine("Default properties not found"); |
| 98 | | | } |
| 99 | 0 | (24)(25) | String userPropertiesName = FILE_SEPARATOR + System.getProperty("user.name") |
| 100 | | | + ".properties"; |
| 101 | 0 | (26) | InputStream userInput = Importer.class |
| 102 | | | .getResourceAsStream(userPropertiesName); |
| 103 | 0 | (27) | if (userInput != null) { |
| 104 | 0 | | logger.fine("Loading user properties"); |
| 105 | 0 | | properties.load(userInput); |
| 106 | | (28)(29) | } else { |
| 107 | 0 | (30) | logger.fine("User properties (" + userPropertiesName + ") not found"); |
| 108 | | | } |
| 109 | 0 | | System.getProperties().putAll(properties); |
| 110 | 0 | | logger.warning(System.getProperties().toString()); |
| 111 | 0 | | properties = System.getProperties(); |
| 112 | | | |
| 113 | 0 | (31) | Configuration hibernateConfig = new Configuration(); |
| 114 | 0 | | hibernateConfig.addProperties(properties); |
| 115 | 0 | | hibernateConfig.configure(); |
| 116 | 0 | (32) | hibernateConfig.getProperties().remove("hibernate.connection.datasource"); |
| 117 | 0 | | hibernateConfig.getProperties().remove( |
| 118 | | | "hibernate.transaction.manager_lookup_class"); |
| 119 | 0 | (33) | hibernateConfig.getProperties().remove("hibernate.transaction.factory_class"); |
| 120 | | | |
| 121 | 0 | (34) | Iterator<?> iter = hibernateConfig.getTableMappings(); |
| 122 | 0 | (35) | while (iter.hasNext()) { |
| 123 | 0 | (36) | Table table = (Table) iter.next(); |
| 124 | 0 | (37) | tableNames.add(table.getName().toUpperCase()); |
| 125 | 0 | | } |
| 126 | 0 | (38) | SessionFactory factory = hibernateConfig.buildSessionFactory(); |
| 127 | 0 | (39)(40) | } catch (IOException e) { |
| 128 | 0 | | logger.log(Level.SEVERE, "Exception: ", e); |
| 129 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 130 | 0 | | } |
| 131 | | | |
| 132 | 0 | (41)(42) | Importer importer = new Importer(DEFAULT_TABLE_PREFIX, DEFAULT_SEQUENCE_BASE); |
| 133 | | | |
| 134 | 0 | (43) | Map<String, Document> items = new HashMap<String, Document>(); |
| 135 | | | |
| 136 | 0 | (44) | if (!importer.loadItems(sourceDirectory, items)) { |
| 137 | 0 | (45) | logger.log(Level.SEVERE, "Invalid test data set detected - aborting."); |
| 138 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 139 | | | } |
| 140 | | | |
| 141 | 0 | (46)(47) | Map<String, Set<String>> dependencyMap = importer.buildDependencyMap(items); |
| 142 | | | |
| 143 | 0 | (48) | if (importer.validateDependencies(items, dependencyMap)) { |
| 144 | 0 | (49) | List<String> result = new ArrayList<String>(); |
| 145 | 0 | (50) | List<String> leftover = new ArrayList<String>(); |
| 146 | | | |
| 147 | 0 | | importer.reOrderItems(items, dependencyMap, result, leftover); |
| 148 | | | |
| 149 | 0 | (51) | List<String> queries = new ArrayList<String>(); |
| 150 | 0 | (52) | if (importer.generateQueries(result, items, queries, null, tableNames, properties, |
| 151 | | (53) | false)) { |
| 152 | 0 | | logger.info("Execution plan for constrained inserts:"); |
| 153 | 0 | | logger.info("---------------------------------------"); |
| 154 | 0 | (54) | for (String query : queries) { |
| 155 | 0 | | logger.info(query); |
| 156 | | | } |
| 157 | 0 | | logger.info("---------------------------------------"); |
| 158 | | | |
| 159 | | (55)(56) | } else { |
| 160 | 0 | | logger |
| 161 | | (57) | .severe("No insert statements have been executed since errors have been detected."); |
| 162 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 163 | | | } |
| 164 | | | |
| 165 | 0 | (58) | List<String> leftOverQueries = new ArrayList<String>(); |
| 166 | 0 | (59) | Set<String> postQueries = new HashSet<String>(); |
| 167 | | | |
| 168 | 0 | (60) | if (importer.generateQueries(leftover, items, leftOverQueries, postQueries, tableNames, |
| 169 | | (61) | properties, true)) { |
| 170 | 0 | | logger.info("Execution plan for unconstrained inserts:"); |
| 171 | 0 | | logger.info("-----------------------------------------"); |
| 172 | 0 | (62) | for (String query : leftOverQueries) { |
| 173 | 0 | | logger.info(query); |
| 174 | | | } |
| 175 | | | |
| 176 | 0 | (63) | for (String query : postQueries) { |
| 177 | 0 | | logger.info(query); |
| 178 | | | } |
| 179 | 0 | | logger.info("---------------------------------------"); |
| 180 | | | |
| 181 | | (64)(65) | } else { |
| 182 | 0 | | logger |
| 183 | | (66) | .severe("No insert statements have been executed since errors have been detected."); |
| 184 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 185 | | | } |
| 186 | | | |
| 187 | 0 | | importer.executeQueries(properties, queries, false); |
| 188 | 0 | | importer.executeQueries(properties, leftOverQueries, false); |
| 189 | 0 | | importer.executeQueries(properties, postQueries, true); |
| 190 | | | |
| 191 | | (67) | try { |
| 192 | 0 | (68) | Connection conn = importer.getConnection(properties); |
| 193 | 0 | | conn.close(); |
| 194 | 0 | (69)(70) | } catch (ClassNotFoundException e) { |
| 195 | 0 | | logger.log(Level.SEVERE, "Exception: ", e); |
| 196 | 0 | (71)(72) | } catch (SQLException e) { |
| 197 | 0 | | logger.log(Level.SEVERE, "Exception: ", e); |
| 198 | 0 | | } |
| 199 | 0 | (73)(74) | } else { |
| 200 | 0 | | logger |
| 201 | | (75) | .severe("No insert statements have been executed since errors have been detected."); |
| 202 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 203 | | | } |
| 204 | 0 | | } |
| 205 | | | |
| 206 | 0 | (76)(77)(78)(79) | public Importer(final String prefix, final long base) { |
| 207 | | | |
| 208 | 0 | | tablePrefix = prefix; |
| 209 | 0 | | sequenceBase = base; |
| 210 | | | |
| 211 | 0 | | } |
| 212 | | | |
| 213 | | | |
| 214 | | | |
| 215 | | | |
| 216 | | | @param |
| 217 | | | @param |
| 218 | | | |
| 219 | | (80) | private void executeQueries(final Properties hibernateProperties, |
| 220 | | (81) | final Collection<String> queries, boolean delayErrors) { |
| 221 | | | |
| 222 | 0 | | boolean success = true; |
| 223 | | (82) | try { |
| 224 | 0 | (83) | Connection conn = getConnection(hibernateProperties); |
| 225 | | | |
| 226 | 0 | | for (SQLWarning warn = conn.getWarnings(); warn != null; warn = warn |
| 227 | | (84) | .getNextWarning()) { |
| 228 | 0 | | logger.warning("SQL Warning:"); |
| 229 | 0 | | logger.warning("State : " + warn.getSQLState()); |
| 230 | 0 | | logger.warning("Message: " + warn.getMessage()); |
| 231 | 0 | | logger.warning("Error : " + warn.getErrorCode()); |
| 232 | | | } |
| 233 | | | |
| 234 | 0 | (85)(86) | Statement langStmt = conn.createStatement(); |
| 235 | 0 | (87) | String alterStatement = "ALTER SESSION SET NLS_TERRITORY='AMERICA'"; |
| 236 | 0 | | langStmt.execute(alterStatement); |
| 237 | 0 | | langStmt.close(); |
| 238 | | | |
| 239 | 0 | (88) | for (String query : queries) { |
| 240 | | | |
| 241 | | (89) | try { |
| 242 | 0 | | logger.info(query); |
| 243 | 0 | (90) | Statement stmt = conn.createStatement(); |
| 244 | 0 | (91)(92)(93) | ResultSet rs = stmt.executeQuery(query); |
| 245 | | | |
| 246 | 0 | | rs.close(); |
| 247 | 0 | | stmt.close(); |
| 248 | 0 | | conn.commit(); |
| 249 | 0 | (94)(95) | } catch (SQLException e) { |
| 250 | | | |
| 251 | 0 | | logger.severe("SQL Exception:"); |
| 252 | | | |
| 253 | 0 | (96) | while (e != null) { |
| 254 | 0 | | logger.severe("State : " + e.getSQLState()); |
| 255 | 0 | | logger.severe("Message: " + e.getMessage()); |
| 256 | 0 | | logger.severe("Error : " + e.getErrorCode()); |
| 257 | | | |
| 258 | 0 | | e = e.getNextException(); |
| 259 | | | } |
| 260 | 0 | (97) | if (!delayErrors) { |
| 261 | 0 | (98) | System.exit(ERROR_EXIT_CODE); |
| 262 | | | } |
| 263 | 0 | | success = false; |
| 264 | 0 | | } |
| 265 | | | } |
| 266 | 0 | (99)(100) | } catch (SQLException e) { |
| 267 | | | |
| 268 | 0 | | logger.severe("SQL Exception:"); |
| 269 | | | |
| 270 | 0 | (101) | while (e != null) { |
| 271 | 0 | | logger.severe("State : " + e.getSQLState()); |
| 272 | 0 | | logger.severe("Message: " + e.getMessage()); |
| 273 | 0 | | logger.severe("Error : " + e.getErrorCode()); |
| 274 | | | |
| 275 | 0 | | e = e.getNextException(); |
| 276 | | | } |
| 277 | 0 | (102) | if (!delayErrors) { |
| 278 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 279 | | | } |
| 280 | 0 | | success = false; |
| 281 | | | |
| 282 | 0 | (103)(104) | } catch (Exception e) { |
| 283 | 0 | | logger.log(Level.SEVERE, "Exception: ", e); |
| 284 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 285 | 0 | | } |
| 286 | 0 | (105) | if (delayErrors && !success) { |
| 287 | 0 | | System.exit(ERROR_EXIT_CODE); |
| 288 | | | } |
| 289 | 0 | | } |
| 290 | | | |
| 291 | | | |
| 292 | | | |
| 293 | | | |
| 294 | | | @param |
| 295 | | | @param |
| 296 | | | @param |
| 297 | | | @param |
| 298 | | | @param |
| 299 | | | @param |
| 300 | | | @param |
| 301 | | | @return |
| 302 | | | |
| 303 | | (106)(107) | private boolean generateQueries(final List<String> idList, |
| 304 | | | final Map<String, Document> items, final List<String> queries, |
| 305 | | | final Set<String> postQueries, |
| 306 | | | final List<String> tableNames, final Properties hibernateProperties, |
| 307 | | (108) | final boolean disableConstraints) { |
| 308 | | | |
| 309 | 0 | | boolean valid = true; |
| 310 | | | |
| 311 | 0 | | final Set<String> preQueries = new HashSet<String>(); |
| 312 | 0 | | final List<String> insertQueries = new ArrayList<String>(); |
| 313 | | | |
| 314 | 0 | (109) | for (String id : idList) { |
| 315 | | | |
| 316 | 0 | (110) | StringBuffer query = new StringBuffer(); |
| 317 | 0 | (111) | StringBuffer names = new StringBuffer("("); |
| 318 | 0 | (112) | StringBuffer values = new StringBuffer("("); |
| 319 | | | |
| 320 | 0 | (113) | Document item = items.get(id); |
| 321 | 0 | (114) | String tableName = getTableName(item); |
| 322 | | | |
| 323 | 0 | (115) | if (!tableNames.contains(tableName)) { |
| 324 | 0 | | logger.severe("The type " + getItemType(item) + " of item " |
| 325 | | | + getItemId(item) |
| 326 | | (116) | + " has no matching table in the current configuration (" |
| 327 | | | + tableName + ")"); |
| 328 | 0 | | valid = false; |
| 329 | | | } |
| 330 | 0 | (117) | Map<String, Node> attributes = getAttributes(item); |
| 331 | | | |
| 332 | 0 | | int position = 0; |
| 333 | 0 | (118) | int end = attributes.entrySet().size(); |
| 334 | | | |
| 335 | 0 | (119) | for (Map.Entry<String, Node> attribute : attributes.entrySet()) { |
| 336 | | | |
| 337 | 0 | | position++; |
| 338 | | | |
| 339 | 0 | (120)(121) | String name = attribute.getKey().toUpperCase(); |
| 340 | 0 | (122) | Node node = attribute.getValue(); |
| 341 | | | |
| 342 | 0 | (123) | if (node instanceof Element) { |
| 343 | 0 | (124) | Element element = (Element) node; |
| 344 | 0 | (125)(126) | if (element.getLocalName().equals("value")) { |
| 345 | 0 | | names.append(name); |
| 346 | 0 | (127) | values.append("'"); |
| 347 | 0 | | values.append(element.getValue()); |
| 348 | 0 | (128) | values.append("'"); |
| 349 | 0 | (129)(130)(131) | } else if (element.getLocalName().equals("autovalue")) { |
| 350 | 0 | | names.append(name); |
| 351 | 0 | | values.append(getAsPrimaryKey(id)); |
| 352 | 0 | (132)(133)(134) | } else if (element.getLocalName().equals("ref")) { |
| 353 | 0 | (135) | String reference = element.getValue(); |
| 354 | 0 | (136) | if (reference.length() > 0) { |
| 355 | 0 | (137)(138) | if (items.containsKey(reference)) { |
| 356 | 0 | | names.append(name); |
| 357 | 0 | (139) | values.append(getAsPrimaryKey(element.getValue())); |
| 358 | | (140)(141) | } else { |
| 359 | 0 | (142) | logger.severe("ERROR! the reference " + reference |
| 360 | | | + " could not be resolved."); |
| 361 | 0 | | valid = false; |
| 362 | | | } |
| 363 | | | } |
| 364 | | | } |
| 365 | | | } |
| 366 | 0 | (143) | if (position == end) { |
| 367 | 0 | | names.append(") "); |
| 368 | 0 | | values.append(") "); |
| 369 | | (144)(145) | } else { |
| 370 | 0 | | names.append(", "); |
| 371 | 0 | | values.append(", "); |
| 372 | | | } |
| 373 | 0 | | } |
| 374 | 0 | (146) | if (attributes.size() > 0) { |
| 375 | 0 | (147) | query.append("INSERT INTO " + tableName); |
| 376 | 0 | (148) | query.append(" "); |
| 377 | 0 | | query.append(names); |
| 378 | 0 | | query.append(" VALUES "); |
| 379 | 0 | | query.append(values); |
| 380 | | | } |
| 381 | 0 | | logger.fine(query.toString()); |
| 382 | 0 | (149) | if (disableConstraints) { |
| 383 | 0 | | preQueries.addAll(buildEnableConstraints(false, tableName, |
| 384 | | | hibernateProperties)); |
| 385 | 0 | | insertQueries.add(query.toString()); |
| 386 | 0 | | postQueries.addAll(buildEnableConstraints(true, tableName, |
| 387 | | | hibernateProperties)); |
| 388 | | (150)(151) | } else { |
| 389 | 0 | | insertQueries.add(query.toString()); |
| 390 | | | } |
| 391 | 0 | | } |
| 392 | 0 | | queries.addAll(preQueries); |
| 393 | 0 | | queries.addAll(insertQueries); |
| 394 | 0 | | return valid; |
| 395 | | | } |
| 396 | | | |
| 397 | | | |
| 398 | | | |
| 399 | | | |
| 400 | | | @param |
| 401 | | | @param |
| 402 | | | @param |
| 403 | | | @param |
| 404 | | | |
| 405 | | (152) | private void reOrderItems(final Map<String, Document> items, |
| 406 | | (153) | final Map<String, Set<String>> dependencyMap, final List<String> result, |
| 407 | | (154) | final List<String> leftover) { |
| 408 | | | |
| 409 | | | boolean changed; |
| 410 | 0 | | logger.fine("Reordering " + items.size() + " items ..."); |
| 411 | 0 | (155) | final Map<String, Document> itemPool = new HashMap<String, Document>(items); |
| 412 | | (156) | do { |
| 413 | 0 | | changed = false; |
| 414 | | | |
| 415 | 0 | (157) | Iterator<Map.Entry<String, Document>> entries = itemPool.entrySet() |
| 416 | | | .iterator(); |
| 417 | 0 | (158) | while (entries.hasNext()) { |
| 418 | 0 | (159) | Map.Entry<String, Document> item = entries.next(); |
| 419 | 0 | (160) | String id = item.getKey(); |
| 420 | 0 | | boolean accepted = true; |
| 421 | | | |
| 422 | 0 | (161) | Set<String> dependencies = dependencyMap.get(id); |
| 423 | 0 | (162) | for (String dependency : dependencies) { |
| 424 | 0 | (163) | if (!result.contains(dependency)) { |
| 425 | 0 | | accepted = false; |
| 426 | 0 | | break; |
| 427 | | | } |
| 428 | | | } |
| 429 | 0 | (164) | if (accepted) { |
| 430 | 0 | (165)(166) | List<String> declaredDependencies = getDeclaredDependencies(item |
| 431 | | | .getValue()); |
| 432 | 0 | (167) | for (String declaredDependency : declaredDependencies) { |
| 433 | 0 | (168) | if (!result.contains(declaredDependency)) { |
| 434 | 0 | | accepted = false; |
| 435 | 0 | | break; |
| 436 | | | } |
| 437 | | | } |
| 438 | | | } |
| 439 | | | |
| 440 | 0 | (169) | if (accepted) { |
| 441 | 0 | | logger.fine("Accepting item: " + id); |
| 442 | 0 | | entries.remove(); |
| 443 | 0 | | result.add(id); |
| 444 | 0 | | changed = true; |
| 445 | | | } |
| 446 | 0 | | } |
| 447 | 0 | | } while (changed); |
| 448 | 0 | | logger.fine("Accepted " + result.size() + " items ..."); |
| 449 | | | |
| 450 | 0 | (170) | if (!itemPool.isEmpty()) { |
| 451 | 0 | | logger |
| 452 | | (171) | .warning("Reference loop(s) detected! The following items will be added ignoring db-constraints:"); |
| 453 | 0 | (172) | for (String id : itemPool.keySet()) { |
| 454 | 0 | | leftover.add(id); |
| 455 | 0 | (173) | StringBuffer dependencyList = new StringBuffer(); |
| 456 | 0 | (174) | Set<String> dependencies = dependencyMap.get(id); |
| 457 | 0 | (175) | for (String dependency : dependencies) { |
| 458 | 0 | | dependencyList.append(dependency); |
| 459 | 0 | (176) | dependencyList.append(" "); |
| 460 | | | } |
| 461 | | | |
| 462 | 0 | | logger.warning(id + ": [" + dependencyList.toString() + "]"); |
| 463 | 0 | | } |
| 464 | | | } |
| 465 | 0 | | } |
| 466 | | | |
| 467 | | | |
| 468 | | | |
| 469 | | | |
| 470 | | | @param |
| 471 | | | @param |
| 472 | | | @return |
| 473 | | | |
| 474 | | (177) | private boolean validateDependencies(Map<String, Document> items, |
| 475 | | (178) | Map<String, Set<String>> dependencyMap) { |
| 476 | | | |
| 477 | 0 | | boolean valid = true; |
| 478 | | | |
| 479 | 0 | (179)(180) | for (Map.Entry<String, Set<String>> dependenciesEntry : dependencyMap.entrySet()) { |
| 480 | | | |
| 481 | 0 | (181) | String id = dependenciesEntry.getKey(); |
| 482 | 0 | (182) | Set<String> dependencies = dependenciesEntry.getValue(); |
| 483 | 0 | (183) | for (String dependency : dependencies) { |
| 484 | 0 | (184) | if (!items.containsKey(dependency)) { |
| 485 | 0 | | logger.severe("Item " + id + " contains invalid reference: " |
| 486 | | (185) | + dependency + " (Note: Self references are not allowed!)"); |
| 487 | 0 | | valid = false; |
| 488 | | | } |
| 489 | | | } |
| 490 | 0 | | } |
| 491 | 0 | | return valid; |
| 492 | | | } |
| 493 | | | |
| 494 | | | |
| 495 | | | |
| 496 | | | |
| 497 | | | @param |
| 498 | | | @return |
| 499 | | | |
| 500 | | (186)(187)(188) | private Map<String, Set<String>> buildDependencyMap(final Map<String, Document> items) { |
| 501 | | | |
| 502 | 0 | (189)(190) | Map<String, Set<String>> dependencyMap = new HashMap<String, Set<String>>(); |
| 503 | | | |
| 504 | 0 | (191) | for (Map.Entry<String, Document> item : items.entrySet()) { |
| 505 | | | |
| 506 | 0 | (192) | String id = item.getKey(); |
| 507 | 0 | (193) | Document document = item.getValue(); |
| 508 | | | |
| 509 | 0 | (194) | Set<String> dependencies = new HashSet<String>(); |
| 510 | | | |
| 511 | 0 | (195)(196) | Nodes references = document.query("/td:item/td:attribute/td:ref", TD_CONTEXT); |
| 512 | | | |
| 513 | 0 | (197) | for (int j = 0; j < references.size(); j++) { |
| 514 | 0 | (198) | Node node = references.get(j); |
| 515 | 0 | (199) | String refId = node.getValue(); |
| 516 | 0 | (200) | if (refId.length() > 0) { |
| 517 | 0 | | dependencies.add(refId); |
| 518 | | (201)(202) | } else { |
| 519 | | | |
| 520 | 0 | | node.getParent().detach(); |
| 521 | | | } |
| 522 | | | } |
| 523 | | | |
| 524 | 0 | | dependencyMap.put(id, dependencies); |
| 525 | 0 | | } |
| 526 | 0 | | return dependencyMap; |
| 527 | | | } |
| 528 | | | |
| 529 | | | |
| 530 | | | |
| 531 | | | |
| 532 | | | @param |
| 533 | | | @param |
| 534 | | | |
| 535 | | (203)(204)(205) | private boolean loadItems(String dirName, Map<String, Document> itemMap) { |
| 536 | | | |
| 537 | 0 | (206) | File rootDir = new File(dirName); |
| 538 | 0 | (207) | if (!rootDir.exists()) { |
| 539 | 0 | | logger.severe("Root directory '" + dirName + "' not found."); |
| 540 | 0 | | return false; |
| 541 | | | } |
| 542 | 0 | (208) | String[] entries = rootDir.list(); |
| 543 | 0 | | boolean success = true; |
| 544 | | | |
| 545 | 0 | (209) | for (int i = 0; i < entries.length; i++) { |
| 546 | 0 | (210) | String entry = dirName + FILE_SEPARATOR + entries[i]; |
| 547 | 0 | (211) | File subFile = new File(entry); |
| 548 | 0 | (212) | if (subFile.isDirectory()) { |
| 549 | 0 | | success &= loadItems(entry, itemMap); |
| 550 | | (213)(214) | } else { |
| 551 | 0 | (215) | if (subFile.getName().endsWith(SUFFIX_XML)) { |
| 552 | 0 | (216) | Builder parser = new Builder(false); |
| 553 | | (217) | try { |
| 554 | 0 | (218) | Document raw = parser.build(entry); |
| 555 | 0 | (219) | Document document = XIncluder.resolve(raw); |
| 556 | 0 | (220) | String id = getItemId(document); |
| 557 | | | |
| 558 | 0 | (221) | if (itemMap.containsKey(id)) { |
| 559 | 0 | | logger.severe("Duplicate id detected: " + id |
| 560 | | | + " - item will be skipped"); |
| 561 | 0 | | success = false; |
| 562 | | (222)(223) | } else { |
| 563 | 0 | | itemMap.put(id, document); |
| 564 | 0 | | logger.fine("Adding item: " + id); |
| 565 | | | } |
| 566 | 0 | (224)(225) | } catch (Exception e) { |
| 567 | 0 | (226) | logger.log(Level.SEVERE, "Error parsing file " + entry + ": ", e); |
| 568 | 0 | | } |
| 569 | | | } |
| 570 | | | } |
| 571 | | | } |
| 572 | 0 | | return success; |
| 573 | | | } |
| 574 | | | |
| 575 | | | |
| 576 | | | |
| 577 | | | |
| 578 | | | @param |
| 579 | | | @return |
| 580 | | | |
| 581 | | (227)(228) | protected String getAsPrimaryKey(final String id) { |
| 582 | | | |
| 583 | 0 | (229)(230) | return "" + (sequenceBase + Long.parseLong(id.substring(3))); |
| 584 | | | } |
| 585 | | | |
| 586 | | | |
| 587 | | | |
| 588 | | | |
| 589 | | | @param |
| 590 | | | @return |
| 591 | | | |
| 592 | | (231)(232) | protected String getTableName(final Document item) { |
| 593 | | | |
| 594 | 0 | (233) | Node type = item.query("//td:item/td:type", TD_CONTEXT).get(0); |
| 595 | 0 | (234) | return tablePrefix + type.getValue().toUpperCase(); |
| 596 | | | } |
| 597 | | | |
| 598 | | | |
| 599 | | | |
| 600 | | | |
| 601 | | | @param |
| 602 | | | @return |
| 603 | | | |
| 604 | | (235)(236) | private String getItemType(final Document document) { |
| 605 | | | |
| 606 | 0 | | String type = null; |
| 607 | | | |
| 608 | 0 | (237) | Nodes nodes = document.query("//td:item/td:type", TD_CONTEXT); |
| 609 | 0 | (238) | for (int j = 0; j < nodes.size(); j++) { |
| 610 | 0 | (239) | Node node = nodes.get(j); |
| 611 | 0 | | type = node.getValue(); |
| 612 | 0 | | break; |
| 613 | | | } |
| 614 | 0 | (240) | if (type == null) { |
| 615 | 0 | | logger.severe(getItemId(document) + " contains no type element!"); |
| 616 | | | } |
| 617 | 0 | | return type; |
| 618 | | | } |
| 619 | | | |
| 620 | | | |
| 621 | | | |
| 622 | | | |
| 623 | | | @param |
| 624 | | | @return |
| 625 | | | |
| 626 | | (241)(242) | private String getItemId(final Document document) { |
| 627 | | | |
| 628 | 0 | | String id = null; |
| 629 | | | |
| 630 | 0 | (243) | Nodes nodes = document.query("//td:item/td:id", TD_CONTEXT); |
| 631 | 0 | (244) | for (int j = 0; j < nodes.size(); j++) { |
| 632 | 0 | (245) | Node node = nodes.get(j); |
| 633 | 0 | | id = node.getValue(); |
| 634 | 0 | | break; |
| 635 | | | } |
| 636 | 0 | | return id; |
| 637 | | | } |
| 638 | | | |
| 639 | | | |
| 640 | | | |
| 641 | | | |
| 642 | | | @param |
| 643 | | | @return |
| 644 | | | |
| 645 | | (246)(247) | private Map<String, Node> getAttributes(final Document document) { |
| 646 | | | |
| 647 | 0 | (248) | Map<String, Node> attributeMap = new HashMap<String, Node>(); |
| 648 | | | |
| 649 | 0 | (249) | Nodes attributes = document.query("//td:item/td:attribute", TD_CONTEXT); |
| 650 | 0 | (250) | for (int j = 0; j < attributes.size(); j++) { |
| 651 | 0 | (251) | Node attribute = attributes.get(j); |
| 652 | 0 | (252)(253) | String name = attribute.query("td:name", TD_CONTEXT).get(0).getValue(); |
| 653 | 0 | (254)(255) | Nodes values = attribute.query("td:value|td:autovalue|td:ref", TD_CONTEXT); |
| 654 | 0 | (256) | if (values.size() > 0) { |
| 655 | 0 | | attributeMap.put(name, values.get(0)); |
| 656 | | | } |
| 657 | | | } |
| 658 | 0 | | return attributeMap; |
| 659 | | | } |
| 660 | | | |
| 661 | | | |
| 662 | | | |
| 663 | | | |
| 664 | | | @param |
| 665 | | | @return |
| 666 | | | |
| 667 | | (257)(258) | private List<String> getDeclaredDependencies(final Document document) { |
| 668 | | | |
| 669 | 0 | (259) | List<String> result = new ArrayList<String>(); |
| 670 | | | |
| 671 | 0 | (260)(261) | Nodes dependencies = document.query("//td:item/td:dependency", TD_CONTEXT); |
| 672 | 0 | (262) | for (int j = 0; j < dependencies.size(); j++) { |
| 673 | 0 | (263) | Node dependency = dependencies.get(j); |
| 674 | 0 | | result.add(dependency.getValue()); |
| 675 | | | } |
| 676 | 0 | | return result; |
| 677 | | | } |
| 678 | | | |
| 679 | | | |
| 680 | | | |
| 681 | | | |
| 682 | | | @param |
| 683 | | | @param |
| 684 | | | @param |
| 685 | | | @return |
| 686 | | | |
| 687 | | (264) | private List<String> buildEnableConstraints(final boolean enabled, |
| 688 | | (265) | final String tableName, final Properties hibernateProperties) { |
| 689 | | | |
| 690 | 0 | | final List<String> queries = new ArrayList<String>(); |
| 691 | 0 | (266)(267) | List<String> constraints = getConstraints(tableName, hibernateProperties); |
| 692 | 0 | (268) | for (String constraint : constraints) { |
| 693 | | | |
| 694 | | | final String query; |
| 695 | 0 | (269) | if (enabled) { |
| 696 | 0 | (270) | query = "ALTER TABLE " + tableName + " ENABLE CONSTRAINT " + constraint; |
| 697 | | (271)(272) | } else { |
| 698 | 0 | (273) | query = "ALTER TABLE " + tableName + " DISABLE CONSTRAINT " + constraint; |
| 699 | | | } |
| 700 | 0 | | queries.add(query); |
| 701 | 0 | | } |
| 702 | 0 | | return queries; |
| 703 | | | } |
| 704 | | | |
| 705 | | (274)(275)(276) | private List<String> getConstraints(String tableName, Properties hibernateProperties) { |
| 706 | | | |
| 707 | 0 | | final List<String> constraints = new ArrayList<String>(); |
| 708 | | (277) | try { |
| 709 | 0 | (278) | Connection conn = getConnection(hibernateProperties); |
| 710 | | | |
| 711 | 0 | | for (SQLWarning warn = conn.getWarnings(); warn != null; warn = warn |
| 712 | | (279) | .getNextWarning()) { |
| 713 | 0 | | logger.warning("SQL Warning:"); |
| 714 | 0 | | logger.warning("State : " + warn.getSQLState()); |
| 715 | 0 | | logger.warning("Message: " + warn.getMessage()); |
| 716 | 0 | | logger.warning("Error : " + warn.getErrorCode()); |
| 717 | | | } |
| 718 | | | |
| 719 | 0 | (280)(281) | String query = "select constraint_name from user_constraints where table_name ='" |
| 720 | | | + tableName + "' and constraint_type='R'"; |
| 721 | | | |
| 722 | 0 | | logger.info(query); |
| 723 | 0 | (282)(283)(284) | Statement stmt = conn.createStatement(); |
| 724 | 0 | (285)(286)(287) | ResultSet rs = stmt.executeQuery(query); |
| 725 | 0 | (288) | while (rs.next()) { |
| 726 | 0 | (289) | String constraint = rs.getString(1); |
| 727 | 0 | | constraints.add(constraint); |
| 728 | 0 | | } |
| 729 | 0 | | rs.close(); |
| 730 | 0 | | stmt.close(); |
| 731 | 0 | (290)(291) | } catch (SQLException e) { |
| 732 | | | |
| 733 | 0 | | logger.severe("SQL Exception:"); |
| 734 | | | |
| 735 | 0 | (292) | while (e != null) { |
| 736 | 0 | | logger.severe("State : " + e.getSQLState()); |
| 737 | 0 | | logger.severe("Message: " + e.getMessage()); |
| 738 | 0 | | logger.severe("Error : " + e.getErrorCode()); |
| 739 | | | |
| 740 | 0 | | e = e.getNextException(); |
| 741 | | | } |
| 742 | 0 | (293)(294) | } catch (Exception e) { |
| 743 | 0 | | logger.log(Level.SEVERE, "Exception: ", e); |
| 744 | 0 | | } |
| 745 | 0 | | return constraints; |
| 746 | | | } |
| 747 | | | |
| 748 | | | |
| 749 | | | |
| 750 | | | |
| 751 | | | @param |
| 752 | | | @return |
| 753 | | | @throws |
| 754 | | | @throws |
| 755 | | | |
| 756 | | (295) | private Connection getConnection(final Properties hibernateProperties) |
| 757 | | (296) | throws ClassNotFoundException, SQLException { |
| 758 | | | |
| 759 | 0 | (297) | if (connection == null) { |
| 760 | 0 | | Class.forName(hibernateProperties |
| 761 | | | .getProperty("hibernate.connection.driver_class")); |
| 762 | | | |
| 763 | 0 | (298) | Properties info = new Properties(); |
| 764 | 0 | | info.setProperty("user", hibernateProperties |
| 765 | | | .getProperty("hibernate.connection.username")); |
| 766 | 0 | | info.setProperty("password", hibernateProperties |
| 767 | | | .getProperty("hibernate.connection.password")); |
| 768 | 0 | | info.setProperty("useUnicode", "true"); |
| 769 | 0 | | info.setProperty("characterEncoding", "UTF-8"); |
| 770 | | | |
| 771 | 0 | | connection = DriverManager.getConnection(hibernateProperties |
| 772 | | | .getProperty("hibernate.connection.url"), info); |
| 773 | | | } |
| 774 | 0 | | return connection; |
| 775 | | | } |
| 776 | | | } |