Changeset 1609 for trunk/grails-app/services/dbnp
- Timestamp:
- Mar 9, 2011, 5:28:45 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/services/dbnp/importer/ImporterService.groovy
r1608 r1609 69 69 try { 70 70 formatValue(datamatrix_celldata, TemplateFieldType.DOUBLE) 71 } catch (NumberFormatException nfe) { doubleBoolean = false } 71 } catch (NumberFormatException nfe) { 72 doubleBoolean = false 73 } 72 74 finally { 73 75 if (doubleBoolean) fieldtype = TemplateFieldType.DOUBLE … … 89 91 try { 90 92 Long.valueOf(datamatrix_celldata) 91 } catch (NumberFormatException nfe) { longBoolean = false } 93 } catch (NumberFormatException nfe) { 94 longBoolean = false 95 } 92 96 finally { 93 97 if (longBoolean) fieldtype = TemplateFieldType.LONG … … 98 102 try { 99 103 formatValue(datamatrix_celldata, TemplateFieldType.DOUBLE) 100 } catch (NumberFormatException nfe) { doubleBoolean = false } 104 } catch (NumberFormatException nfe) { 105 doubleBoolean = false 106 } 101 107 finally { 102 108 if (doubleBoolean) fieldtype = TemplateFieldType.DOUBLE … … 187 193 } 188 194 189 195 190 196 /** 191 197 * Retrieves records with sample, subject, samplingevent etc. from a study … … 195 201 protected def getRecords( Study s ) { 196 202 def records = []; 197 203 198 204 s.samples?.each { 199 205 def record = [ 'objects': retrieveEntitiesBySample( it ) ]; 200 206 201 207 def templates = [:] 202 208 def templateCombination = []; … … 206 212 templateCombination << entity.key + ": " + entity.value?.template?.name; 207 213 } 208 214 209 215 record.templates = templates; 210 216 record.templateCombination = templateCombination.join( ', ' ) 211 217 212 218 records << record 213 219 } 214 220 215 221 return records; 216 222 } 217 223 218 224 /** 219 225 * Returns a subject, event and samplingEvent that belong to this sample … … 229 235 ] 230 236 } 231 237 232 238 /** 233 239 * Imports data from a workbook into a list of ImportRecords. If some entities are already in the database, … … 252 258 if( !mcmap ) 253 259 return; 254 260 255 261 // Check whether the rows should be imported in one or more entities 256 262 def entities … … 260 266 entities = mcmap.findAll{ !it.dontimport }.entityclass.unique(); 261 267 } 262 268 263 269 def sheet = wb.getSheetAt(sheetindex) 264 270 def table = [] 265 271 def failedcells = [] // list of cells that have failed to import 266 267 272 // First check for each record whether an entity in the database should be updated, 268 273 // or a new entity should be added. This is done before any new object is created, since … … 274 279 existingEntities[i] = findExistingEntities( entities, sheet.getRow(i), mcmap, parent ); 275 280 } 276 281 277 282 // walk through all rows and fill the table with records 278 283 for( int i = rowindex; i <= sheet.getLastRowNum(); i++ ) { 279 284 // Create an entity record based on a row read from Excel and store the cells which failed to be mapped 280 285 def (record, failed) = importOrUpdateRecord( templates, entities, sheet.getRow(i), mcmap, parent, table, existingEntities[i] ); 281 286 282 287 // Setup the relationships between the imported entities 283 288 relateEntities( record ); 284 289 285 290 // Add record with entities and its values to the table 286 291 table.add(record) … … 289 294 if (failed?.importcells?.size() > 0) failedcells.add(failed) 290 295 } 291 296 292 297 return [ "table": table, "failedCells": failedcells ] 293 298 } 294 299 295 300 /** 296 * Checks whether entities in the given row already exist in the database297 * they are updated.298 *299 * @param entities Entities that have to be imported for this row300 * @param excelRow Excel row to import into this record301 * @param mcmap Hashmap of mappingcolumns, with the first entry in the hashmap containing information about the first column, etc.302 * @return Map Map with entities that have been found for this row. The key for the entities is the entity name (e.g.: [Sample: null, Subject: <subject object>]303 */304 305 306 307 308 309 310 311 301 * Checks whether entities in the given row already exist in the database 302 * they are updated. 303 * 304 * @param entities Entities that have to be imported for this row 305 * @param excelRow Excel row to import into this record 306 * @param mcmap Hashmap of mappingcolumns, with the first entry in the hashmap containing information about the first column, etc. 307 * @return Map Map with entities that have been found for this row. The key for the entities is the entity name (e.g.: [Sample: null, Subject: <subject object>] 308 */ 309 def findExistingEntities(def entities, Row excelRow, mcmap, parent ) { 310 DataFormatter df = new DataFormatter(); 311 312 // Find entities based on sample identifier 313 def sample = findEntityByRow( dbnp.studycapturing.Sample, excelRow, mcmap, parent, [], df ); 314 return retrieveEntitiesBySample( sample ); 315 } 316 312 317 /** 313 318 * Imports a records from the excelsheet into the database. If the entities are already in the database … … 332 337 def record = [] // list of entities and the read values 333 338 def failed = new ImportRecord() // map with entity identifier and failed mappingcolumn 334 339 335 340 // Check whether this record mentions a sample that has been imported before. In that case, 336 341 // we update that record, in order to prevent importing the same sample multiple times … … 341 346 def importedSample = null // findEntityInImportedEntities( dbnp.studycapturing.Sample, excelRow, mcmap, importedEntities, df ) 342 347 def imported = [] // retrieveEntitiesBySample( importedSample ); 343 344 348 for( entity in entities ) { 345 349 // Check whether this entity should be added or updated … … 348 352 def entityName = entity.name[ entity.name.lastIndexOf( '.' ) + 1..-1]; 349 353 def template = templates[ entityName ]; 350 354 351 355 // If no template is specified for this entity, continue with the next 352 356 if( !template ) 353 357 continue; 354 358 355 359 // Check whether the object exists in the list of already imported entities 356 360 def entityObject = imported[ entityName ] 357 361 358 362 // If it doesn't, search for the entity in the database 359 363 if( !entityObject && existingEntities ) 360 364 entityObject = existingEntities[ entityName ]; 361 365 362 366 // Otherwise, create a new object 363 367 if( !entityObject ) 364 368 entityObject = entity.newInstance(); 365 369 366 370 // Update the template 367 371 entityObject.template = template; 368 372 369 373 // Go through the Excel row cell by cell 370 374 for (Cell cell: excelRow) { … … 372 376 def mc = mcmap[cell.getColumnIndex()] 373 377 def value 374 378 375 379 // Check if column must be imported 376 380 if (mc != null && !mc.dontimport && mc.entityclass == entity) { … … 380 384 value = "" 381 385 } 382 386 383 387 try { 384 388 entityObject.setFieldValue(mc.property, value) … … 388 392 // store the mapping column and value which failed 389 393 def identifier = entityName.toLowerCase() + "_" + entityObject.getIdentifier() + "_" + mc.property 390 394 391 395 def mcInstance = new MappingColumn() 392 396 mcInstance.properties = mc.properties … … 395 399 } // end if 396 400 } // end for 397 401 398 402 // If a Study is entered, use it as a 'parent' for other entities 399 403 if( entity == Study ) 400 404 parent = entityObject; 401 405 402 406 record << entityObject; 403 407 } 404 408 405 409 // a failed column means that using the entity.setFieldValue() threw an exception 406 410 return [record, failed] 407 411 } 408 412 409 413 /** 410 414 * Looks into the database to find an object of the given entity that should be updated, given the excel row. … … 424 428 if( df == null ) 425 429 df = new DataFormatter(); 426 430 427 431 def identifierField = givePreferredIdentifier( entity ); 428 432 429 433 if( identifierField ) { 430 434 // Check whether the identifierField is chosen in the column matching 431 435 def identifierColumn = mcmap.find { it.entityclass == entity && it.property == identifierField.name }; 432 436 433 437 // If it is, find the identifier and look it up in the database 434 438 if( identifierColumn ) { … … 440 444 identifier = null 441 445 } 442 446 443 447 // Search for an existing object with the same identifier. 444 448 if( identifier ) { … … 449 453 return imported; 450 454 } 451 455 452 456 def c = entity.createCriteria(); 453 457 454 458 // If the entity has a field 'parent', the search should be limited to 455 459 // objects with the same parent. The method entity.hasProperty( "parent" ) doesn't … … 458 462 // If the entity requires a parent, but none is given, no 459 463 // results are given from the database. This prevents the user 460 // of changing data in another study 464 // of changing data in another study 461 465 if( parent && parent.id ) { 462 466 println "Searching (with parent ) for " + entity.name + " with " + identifierField.name + " = " + identifier … … 475 479 } 476 480 } 477 481 478 482 // No object is found 479 483 return null; 480 484 } 481 482 /** 483 * Looks into the list of already imported entities to find an object of the given entity that should be484 * updated, given the excel row. This is done by looking at the 'preferredIdentifier' field of the object.485 * If it exists in the row, and the list of imported entities contains an object with the same486 * identifier, the existing object is returned. Otherwise, null is returned487 *488 * @param entity Entity to search489 * @param excelRow Excelrow to search for490 * @param mcmap Map with MappingColumns491 * @param importedRows List of entities that have been imported before. The function will first look through this list to find492 * a matching entity.493 * @return An entity that has the same identifier as entered in the excelRow. The entity is first sought in the importedRows. If it494 * is not found there, the database is queried. If no entity is found at all, null is returned.495 */496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 485 486 /** 487 * Looks into the list of already imported entities to find an object of the given entity that should be 488 * updated, given the excel row. This is done by looking at the 'preferredIdentifier' field of the object. 489 * If it exists in the row, and the list of imported entities contains an object with the same 490 * identifier, the existing object is returned. Otherwise, null is returned 491 * 492 * @param entity Entity to search 493 * @param excelRow Excelrow to search for 494 * @param mcmap Map with MappingColumns 495 * @param importedRows List of entities that have been imported before. The function will first look through this list to find 496 * a matching entity. 497 * @return An entity that has the same identifier as entered in the excelRow. The entity is first sought in the importedRows. If it 498 * is not found there, the database is queried. If no entity is found at all, null is returned. 499 */ 500 def findEntityInImportedEntities( Class entity, Row excelRow, def mcmap, List importedEntities = [], DataFormatter df = null ) { 501 if( df == null ) 502 df = new DataFormatter(); 503 504 def allFields = entity.giveDomainFields(); 505 def identifierField = allFields.find { it.preferredIdentifier } 506 507 if( identifierField ) { 508 // Check whether the identifierField is chosen in the column matching 509 def identifierColumn = mcmap.find { it.entityclass == entity && it.property == identifierField.name }; 510 511 // If it is, find the identifier and look it up in the database 512 if( identifierColumn ) { 513 def identifierCell = excelRow.getCell( identifierColumn.index ); 514 def identifier; 515 try { 516 identifier = formatValue(df.formatCellValue(identifierCell), identifierColumn.templatefieldtype) 517 } catch (NumberFormatException nfe) { 518 identifier = null 519 } 520 521 // Search for an existing object with the same identifier. 522 if( identifier ) { 519 523 // First search the already imported rows 520 524 if( importedEntities ) { … … 526 530 else 527 531 return fieldValue == identifier 528 529 532 }; 530 531 532 533 534 535 536 537 538 539 540 541 533 if( imported ) 534 return imported; 535 } 536 } 537 } 538 } 539 540 // No object is found 541 return null; 542 } 543 544 542 545 /** 543 546 * Creates relation between multiple entities that have been imported. The entities are … … 551 554 def samplingEvent = entities.find { it instanceof SamplingEvent } 552 555 def assay = entities.find { it instanceof Assay } 553 556 554 557 // A study object is found in the entity list 555 558 if( study ) { … … 563 566 } 564 567 if( event ) { 565 event.parent = study 568 event.parent = study 566 569 study.addToEvents( event ); 567 570 } … … 584 587 if( subject ) evGroup.addToSubjects( subject ); 585 588 if( samplingEvent ) evGroup.addToSamplingEvents( samplingEvent ); 586 589 587 590 sample.parentEventGroup = evGroup; 588 591 } 589 592 590 593 if( assay ) assay.addToSamples( sample ); 591 594 } … … 610 613 def table = [] 611 614 def failedcells = [] // list of records 612 613 615 // walk through all rows and fill the table with records 614 616 (rowindex..sheet.getLastRowNum()).each { i -> … … 665 667 def getFieldNameInTableEditor(entity, field) { 666 668 def entityName = entity?.class.name[ entity?.class.name.lastIndexOf(".") + 1..-1] 667 669 668 670 if( field instanceof TemplateField ) 669 671 field = field.escapedName(); 670 672 671 return entityName.toLowerCase() + "_" + entity.getIdentifier() + "_" + field 673 return entityName.toLowerCase() + "_" + entity.getIdentifier() + "_" + field.toLowerCase() 672 674 } 673 675 … … 928 930 // store the mapping column and value which failed 929 931 def identifier 930 932 def fieldName = mc.property?.toLowerCase() 933 931 934 switch (mc.entityclass) { 932 case Study: identifier = "entity_" + study.getIdentifier() + "_" + mc.property933 break 934 case Subject: identifier = "entity_" + subject.getIdentifier() + "_" + mc.property935 break 936 case SamplingEvent: identifier = "entity_" + samplingEvent.getIdentifier() + "_" + mc.property937 break 938 case Event: identifier = "entity_" + event.getIdentifier() + "_" + mc.property939 break 940 case Sample: identifier = "entity_" + sample.getIdentifier() + "_" + mc.property935 case Study: identifier = "entity_" + study.getIdentifier() + "_" + fieldName 936 break 937 case Subject: identifier = "entity_" + subject.getIdentifier() + "_" + fieldName 938 break 939 case SamplingEvent: identifier = "entity_" + samplingEvent.getIdentifier() + "_" + fieldName 940 break 941 case Event: identifier = "entity_" + event.getIdentifier() + "_" + fieldName 942 break 943 case Sample: identifier = "entity_" + sample.getIdentifier() + "_" + fieldName 941 944 break 942 945 case Object: // don't import … … 972 975 } 973 976 } 974 977 975 978 /** 976 979 * Returns the preferred identifier field for a given entity or
Note: See TracChangeset
for help on using the changeset viewer.