Changeset 787 for trunk/grails-app/controllers
- Timestamp:
- Aug 6, 2010, 3:13:11 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy
r778 r787 237 237 238 238 // refresh templates 239 flow.study.giveSubjectTemplates().each() { 240 it.refresh() 239 if (flow.study.subjects) { 240 flow.study.giveSubjectTemplates().each() { 241 it.refresh() 242 } 241 243 } 242 244 … … 387 389 eventPage(flow, flash, params) 388 390 389 // first find the current maximum default name "Subject xxxx" 390 def eventGroupNo = 0 391 def eventGroupMax = 0 392 flow.study.eventGroups.each() { 393 it.name.trim().eachMatch(/(\d+)$/){ 394 eventGroupNo = it[1] as int 395 if (eventGroupNo > eventGroupMax) { 396 eventGroupMax = eventGroupNo 397 } 391 // set work variables 392 def groupName = 'Group ' 393 def tempGroupIterator = 1 394 def tempGroupName = groupName + tempGroupIterator 395 396 // make sure group name is unique 397 if (flow.study.eventGroups) { 398 while (flow.study.eventGroups.find { it.name == tempGroupName }) { 399 tempGroupIterator++ 400 tempGroupName = groupName + tempGroupIterator 398 401 } 399 402 } 403 groupName = tempGroupName 400 404 401 405 // add a new eventGroup 402 406 flow.study.addToEventGroups( 403 407 new EventGroup( 404 name : 'Group ' + (eventGroupMax+1),408 name : groupName, 405 409 parent : flow.study 406 410 ) … … 456 460 // handle form data 457 461 groupPage(flow, flash, params) ? success() : error() 458 }.to " waitForSave"462 }.to "samples" 459 463 on("quickSave") { 460 464 // handle form data … … 491 495 onRender { 492 496 flow.page = 6 493 /* 494 // iterate through eventGroups 495 if (!flow.samples) { 496 println ".generating samples" 497 flow.samplesWithTemplate = 0 498 flow.samples = [] 499 flow.sampleTemplates = [:] 500 flow.eventGroups.each() { eventGroup -> 501 // iterate through events 497 498 // got samples? 499 if (!flow.study.samples) { 500 // generate samples 501 // iterate through eventGroups 502 flow.study.eventGroups.each() { eventGroup -> 503 // iterate through samplingEvents 502 504 eventGroup.samplingEvents.each() { samplingEvent -> 503 505 def samplingEventName = this.ucwords(samplingEvent.template.name) … … 506 508 eventGroup.subjects.each() { subject -> 507 509 def sampleName = (this.ucwords(subject.name) + '_' + samplingEventName + '_' + new RelTime(samplingEvent.startTime).toString()).replaceAll("([ ]{1,})", "") 508 def increment = flow.samples.size() 509 510 flow.samples[increment] = [ 511 sample: new Sample( 512 parent: flow.study, 513 parentSubject: subject, 514 parentEvent: samplingEvent, 515 name: sampleName 516 ), 517 name: sampleName, 518 eventGroup: eventGroup, 519 event: samplingEvent, 520 subject: subject 521 ] 522 523 // and add this sample to the study 524 flow.study.addToSamples(flow.samples[increment].sample) 510 def tempSampleIterator = 0 511 def tempSampleName = sampleName 512 513 // make sure sampleName is unique 514 if (flow.study.samples) { 515 while (flow.study.samples.find { it.name == tempSampleName }) { 516 tempSampleIterator++ 517 tempSampleName = sampleName + "_" + tempSampleIterator 518 } 519 sampleName = tempSampleName 520 } 521 522 // instantiate a sample 523 flow.study.addToSamples( 524 new Sample( 525 parent : flow.study, 526 parentSubject : subject, 527 parentEvent : samplingEvent, 528 name : sampleName 529 ) 530 ) 525 531 } 526 532 } 533 527 534 } 528 } else if (flash.check) { 529 println "CHECKING SAMPLE CONSISTENCY" 530 // check the consistency of the samples 531 flow.samples.each() { sampleData -> 532 println sampleData 533 println sampleData.event.template 534 } 535 } 536 537 success() 538 */ 535 } 536 537 success() 539 538 } 540 539 on("switchTemplate") { 541 // println params542 handleSamples(flow, flash, params)540 // handle form data 541 samplePage(flow, flash, params) 543 542 544 543 // ignore errors … … 548 547 }.to "samples" 549 548 on("refresh") { 550 println ".refresh ${flow.sampleTemplates.size()} sample templates (${flow.samples.size()} samples present)"551 552 // refresh templates553 flow.sampleTemplates.each() {554 println ".refresh template ["+it.value.name+"]"555 it.value.template.refresh()556 println " --> fields: "+it.value.template.fields557 }558 559 549 // handle samples 560 550 handleSamples(flow, flash, params) 561 551 552 // refresh all sample templates 553 flow.study.giveSampleTemplates().each() { 554 it.refresh() 555 } 556 562 557 // ignore errors 563 558 flash.errors = [:] … … 566 561 }.to "samples" 567 562 on("regenerate") { 568 println ".removing 'samples' and 'sampleTemplates' from the flowscope, triggering regeneration of the samples..." 569 flow.samples.each() { 570 flow.study.removeFromSamples( it.sample ) 571 } 572 flow.remove('samples') 573 flow.remove('sampleTemplates') 574 println flow.study.samples 563 // handle samples 564 handleSamples(flow, flash, params) 565 566 // remove all samples from the study 567 flow.study.samples.findAll{true}.each() { sample -> 568 flow.study.removeFromSamples(sample) 569 } 570 571 // ignore errors 572 flash.errors = [:] 573 575 574 success() 576 575 }.to "samples" … … 585 584 }.to "samplePrevious" 586 585 on("next") { 587 flash.values = params 588 flash.errors = [:] 589 590 // for now, development only! 591 if (grails.util.GrailsUtil.environment == "development") { 592 // do all samples have a template assigned? 593 if (flow.samplesWithTemplate < flow.samples.size()) { 594 // handle samples 595 this.handleSamples(flow, flash, params) 596 597 // ignore errors 598 flash.errors = [:] 599 600 // add error 601 this.appendErrorMap(['samples': 'you need to select a template for each sample'], flash.errors) 602 603 error() 604 } else if (this.handleSamples(flow, flash, params)) { 605 success() 606 } else { 607 error() 608 } 609 } else { 610 success() 611 } 586 // handle form data 587 samplePage(flow, flash, params) ? success() : error() 612 588 }.to "confirm" 613 589 on("quickSave") { 614 // handle samples 615 if (handleSamples(flow, flash, params)) { 616 success() 617 } else { 618 error() 619 } 590 // handle form data 591 samplePage(flow, flash, params) ? success() : error() 620 592 }.to "waitForSave" 621 593 } … … 723 695 } 724 696 } 725 726 /**727 * re-usable code for handling samples728 * @param Map LocalAttributeMap (the flow scope)729 * @param Map localAttributeMap (the flash scope)730 * @param Map GrailsParameterMap (the flow parameters = form data)731 * @return boolean732 */733 def handleSamples(flow, flash, params) {734 flash.errors = [:]735 def errors = false736 def id = 0737 738 // iterate through samples739 flow.samples.each() { sampleData ->740 def sample = sampleData.sample741 def sampleTemplateName = params.get('template_'+id)742 def oldSampleTemplateName = sampleData.sample.template.toString()743 744 // has the sample template for this sample changed745 if (sampleTemplateName && sampleTemplateName.size() > 0 && oldSampleTemplateName != sampleTemplateName) {746 // yes, has the template changed?747 println ".changing template for sample ${id} to ${sampleTemplateName}"748 749 // decrease previous template count750 if (oldSampleTemplateName && flow.sampleTemplates[ oldSampleTemplateName ]) {751 flow.sampleTemplates[ oldSampleTemplateName ].count--752 753 if (flow.sampleTemplates[ oldSampleTemplateName ].count < 1) {754 // no samples left, remove template altogether755 flow.sampleTemplates.remove( oldSampleTemplateName )756 }757 } else {758 // increate main template counter?759 flow.samplesWithTemplate++760 }761 762 // increase current template count763 if (!flow.sampleTemplates[ sampleTemplateName ]) {764 flow.sampleTemplates[ sampleTemplateName ] = [765 name : sampleTemplateName,766 template : Template.findByName( sampleTemplateName ),767 count : 1768 ]769 } else {770 // increase count771 flow.sampleTemplates[ sampleTemplateName ].count++772 }773 774 // change template775 sampleData.sample.template = flow.sampleTemplates[ sampleTemplateName ].template776 }777 778 // handle values779 sampleData.sample.giveFields().each() { sampleField ->780 if ( params.containsKey( 'sample_'+id+'_'+sampleField.escapedName() ) ) {781 sampleData.sample.setFieldValue( sampleField.name, params.get( 'sample_'+id+'_'+sampleField.escapedName() ) )782 }783 }784 785 // validate sample786 if (!sampleData.sample.validate()) {787 errors = true788 this.appendErrors(sampleData.sample, flash.errors, 'sample_' + id + '_' )789 }790 791 // increase counter792 id++793 }794 795 return !errors796 }797 798 /**799 * groovy / java equivalent of php's ucwords function800 *801 * Capitalize all first letters of seperate words802 *803 * @param String804 * @return String805 */806 def ucwords(String text) {807 def newText = ''808 809 // change case to lowercase810 text = text.toLowerCase()811 812 // iterate through words813 text.split(" ").each() {814 newText += it[0].toUpperCase() + it.substring(1) + " "815 }816 817 return newText.substring(0, newText.size()-1)818 }819 820 /**821 * return the object from a map of objects by searching for a name822 * @param String name823 * @param Map map of objects824 * @return Object825 */826 def getObjectByName(name, map) {827 def result = null828 map.each() {829 if (it.name == name) {830 result = it831 }832 }833 834 return result835 }836 837 /**838 * transform domain class validation errors into a human readable839 * linked hash map840 * @param object validated domain class841 * @return object linkedHashMap842 */843 def getHumanReadableErrors(object) {844 def errors = [:]845 object.errors.getAllErrors().each() {846 def message = it.toString()847 848 //errors[it.getArguments()[0]] = it.getDefaultMessage()849 errors[it.getArguments()[0]] = message.substring(0, message.indexOf(';'))850 }851 852 return errors853 }854 855 /**856 * append errors of a particular object to a map857 * @param object858 * @param map linkedHashMap859 * @void860 */861 def appendErrors(object, map) {862 this.appendErrorMap(this.getHumanReadableErrors(object), map)863 }864 865 def appendErrors(object, map, prepend) {866 this.appendErrorMap(this.getHumanReadableErrors(object), map, prepend)867 }868 869 /**870 * append errors of one map to another map871 * @param map linkedHashMap872 * @param map linkedHashMap873 * @void874 */875 def appendErrorMap(map, mapToExtend) {876 map.each() {key, value ->877 mapToExtend[key] = ['key': key, 'value': value, 'dynamic': false]878 }879 }880 881 def appendErrorMap(map, mapToExtend, prepend) {882 map.each() {key, value ->883 mapToExtend[prepend + key] = ['key': key, 'value': value, 'dynamic': true]884 }885 }886 887 /**888 * Parses a RelTime string and returns a nice human readable string889 *890 * @return Human Readable string or a HTTP response code 400 on error891 */892 def ajaxParseRelTime = {893 if (params.reltime == null) {894 response.status = 400895 render('reltime parameter is expected')896 }897 898 try {899 def reltime = RelTime.parseRelTime(params.reltime)900 render reltime.toPrettyString()901 } catch (IllegalArgumentException e) {902 response.status = 400903 render(e.getMessage())904 }905 }906 907 /**908 * Proxy for searching PubMed articles (or other articles from the Entrez DB).909 *910 * This proxy is needed because it is not allowed to fetch XML directly from a different911 * domain using javascript. So we have the javascript call a function on our own domain912 * and the proxy will fetch the data from Entrez913 *914 * @since 20100609915 * @param _utility The name of the utility, without the complete path. Example: 'esearch.fcgi'916 * @return XML917 */918 def entrezProxy = {919 // Remove unnecessary parameters920 params.remove( "action" )921 params.remove( "controller" )922 923 def url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils";924 def util = params.remove( "_utility" )925 def paramString = params.collect { k, v -> k + '=' + v.encodeAsURL() }.join( '&' );926 927 def fullUrl = url + '/' + util + '?' + paramString;928 929 // Return the output of the request930 // render fullUrl;931 render(932 text: new URL( fullUrl ).getText(),933 contentType: "text/xml",934 encoding: "UTF-8"935 );936 }937 938 939 /****** REFACTORED METHODS OVER HERE! ******/940 697 941 698 /** … … 1160 917 def species = Term.findByName(params.get('species')) 1161 918 def template = Template.findByName(params.get('template')) 1162 def subjectNo = 01163 def subjectMax = 01164 919 1165 920 // can we add subjects? 1166 921 if (number > 0 && species && template) { 1167 // first find the current maximum default name "Subject xxxx"1168 flow.study.subjects.each() {1169 it.name.trim().eachMatch(/(\d+)$/){1170 subjectNo = it[1] as int1171 if (subjectNo > subjectMax) {1172 subjectMax = subjectNo1173 }1174 }1175 }1176 1177 922 // add subjects to study 1178 923 number.times { 1179 subjectMax++ 924 // work variables 925 def subjectName = 'Subject ' 926 def subjectIterator = 1 927 def tempSubjectName = subjectName + subjectIterator 928 929 // make sure subject name is unique 930 if (flow.study.subjects) { 931 while (flow.study.subjects.find { it.name == tempSubjectName }) { 932 subjectIterator++ 933 tempSubjectName = subjectName + subjectIterator 934 } 935 } 936 subjectName = tempSubjectName 1180 937 1181 938 // create a subject instance 1182 939 def subject = new Subject( 1183 name : 'Subject ' + subjectMax,940 name : subjectName, 1184 941 species : species, 1185 942 template : template, … … 1292 1049 } 1293 1050 1294 // handle eventGroup names1295 flow.study.eventGroups.each() { eventGroup ->1296 1297 }1298 1299 1051 return !errors 1300 1052 } … … 1345 1097 flash.values = params 1346 1098 1099 // iterate through samples 1100 flow.study.samples.each() { sample -> 1101 // iterate through sample fields 1102 sample.giveFields().each() { field -> 1103 def value = params.get('sample_'+sample.getIdentifier()+'_'+field.escapedName()) 1104 1105 // set field value 1106 if (!(field.name == 'name' && !value)) { 1107 println "setting "+field.name+" to "+value 1108 sample.setFieldValue(field.name, value) 1109 } 1110 } 1111 1112 // has the template changed? 1113 def templateName = params.get('template_' + sample.getIdentifier()) 1114 if (templateName && sample.template?.name != templateName) { 1115 sample.template = Template.findByName(templateName) 1116 } 1117 1118 // validate sample 1119 if (!sample.validate()) { 1120 errors = true 1121 this.appendErrors(sample, flash.errors) 1122 println 'error-> sample_'+sample.getIdentifier() 1123 } 1124 } 1125 1347 1126 return !errors 1348 1127 } 1128 1129 /** 1130 * groovy / java equivalent of php's ucwords function 1131 * 1132 * Capitalize all first letters of separate words 1133 * 1134 * @param String 1135 * @return String 1136 */ 1137 def ucwords(String text) { 1138 def newText = '' 1139 1140 // change case to lowercase 1141 text = text.toLowerCase() 1142 1143 // iterate through words 1144 text.split(" ").each() { 1145 newText += it[0].toUpperCase() + it.substring(1) + " " 1146 } 1147 1148 return newText.substring(0, newText.size()-1) 1149 } 1150 1151 /** 1152 * return the object from a map of objects by searching for a name 1153 * @param String name 1154 * @param Map map of objects 1155 * @return Object 1156 */ 1157 def getObjectByName(name, map) { 1158 def result = null 1159 map.each() { 1160 if (it.name == name) { 1161 result = it 1162 } 1163 } 1164 1165 return result 1166 } 1167 1168 /** 1169 * transform domain class validation errors into a human readable 1170 * linked hash map 1171 * @param object validated domain class 1172 * @return object linkedHashMap 1173 */ 1174 def getHumanReadableErrors(object) { 1175 def errors = [:] 1176 object.errors.getAllErrors().each() { 1177 def message = it.toString() 1178 1179 //errors[it.getArguments()[0]] = it.getDefaultMessage() 1180 errors[it.getArguments()[0]] = message.substring(0, message.indexOf(';')) 1181 } 1182 1183 return errors 1184 } 1185 1186 /** 1187 * append errors of a particular object to a map 1188 * @param object 1189 * @param map linkedHashMap 1190 * @void 1191 */ 1192 def appendErrors(object, map) { 1193 this.appendErrorMap(this.getHumanReadableErrors(object), map) 1194 } 1195 1196 def appendErrors(object, map, prepend) { 1197 this.appendErrorMap(this.getHumanReadableErrors(object), map, prepend) 1198 } 1199 1200 /** 1201 * append errors of one map to another map 1202 * @param map linkedHashMap 1203 * @param map linkedHashMap 1204 * @void 1205 */ 1206 def appendErrorMap(map, mapToExtend) { 1207 map.each() {key, value -> 1208 mapToExtend[key] = ['key': key, 'value': value, 'dynamic': false] 1209 } 1210 } 1211 1212 def appendErrorMap(map, mapToExtend, prepend) { 1213 map.each() {key, value -> 1214 mapToExtend[prepend + key] = ['key': key, 'value': value, 'dynamic': true] 1215 } 1216 } 1217 1218 /** 1219 * Parses a RelTime string and returns a nice human readable string 1220 * 1221 * @return Human Readable string or a HTTP response code 400 on error 1222 */ 1223 def ajaxParseRelTime = { 1224 if (params.reltime == null) { 1225 response.status = 400 1226 render('reltime parameter is expected') 1227 } 1228 1229 try { 1230 def reltime = RelTime.parseRelTime(params.reltime) 1231 render reltime.toPrettyString() 1232 } catch (IllegalArgumentException e) { 1233 response.status = 400 1234 render(e.getMessage()) 1235 } 1236 } 1237 1238 /** 1239 * Proxy for searching PubMed articles (or other articles from the Entrez DB). 1240 * 1241 * This proxy is needed because it is not allowed to fetch XML directly from a different 1242 * domain using javascript. So we have the javascript call a function on our own domain 1243 * and the proxy will fetch the data from Entrez 1244 * 1245 * @since 20100609 1246 * @param _utility The name of the utility, without the complete path. Example: 'esearch.fcgi' 1247 * @return XML 1248 */ 1249 def entrezProxy = { 1250 // Remove unnecessary parameters 1251 params.remove( "action" ) 1252 params.remove( "controller" ) 1253 1254 def url = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils"; 1255 def util = params.remove( "_utility" ) 1256 def paramString = params.collect { k, v -> k + '=' + v.encodeAsURL() }.join( '&' ); 1257 1258 def fullUrl = url + '/' + util + '?' + paramString; 1259 1260 // Return the output of the request 1261 // render fullUrl; 1262 render( 1263 text: new URL( fullUrl ).getText(), 1264 contentType: "text/xml", 1265 encoding: "UTF-8" 1266 ); 1267 } 1349 1268 }
Note: See TracChangeset
for help on using the changeset viewer.