Changeset 540
- Timestamp:
- Jun 8, 2010, 1:04:08 PM (11 years ago)
- Location:
- trunk/grails-app
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy
r539 r540 228 228 success() 229 229 }.to "study" 230 230 on("switchTemplate") { 231 231 flash.values = params 232 232 … … 583 583 flow.bla = "samples" 584 584 585 // iterate through subjects 586 flow.subjects.each() { subject -> 587 println subject.value.name 588 585 // iterate through eventGroups 586 flow.eventGroups.each() { eventGroup -> 589 587 // iterate through events 590 flow.events.each() { event -> 591 if (event instanceof SamplingEvent) { 592 println event.template.name 593 println event.startTime 594 println event.endTime 595 def sampleName = (this.ucwords(subject.value.name) + '_' + this.ucwords(event.template.name) + ((event.startTime) ? '_' + event.startTime : '')).replaceAll("([ ]{1,})", "") 596 //.replaceAll("([^A-Za-z0-9_])", "") 597 println sampleName 588 eventGroup.events.each() { event -> 589 if (event.isSamplingEvent()) { 590 def eventName = this.ucwords(event.template.name) 591 592 // iterate through subjects 593 eventGroup.subjects.each() { subject -> 594 def sampleName = (this.ucwords(subject.name) + '_' + eventName + '_' + new RelTime( event.startTime ).toString()).replaceAll("([ ]{1,})", "") 595 596 println sampleName 597 } 598 598 } 599 599 } 600 601 /* 602 println it 603 println it.events 604 println it.subjects 605 */ 600 606 } 601 607 -
trunk/grails-app/domain/dbnp/data/FeatureBase.groovy
r496 r540 1 1 package dbnp.data 2 2 /** 3 * 888 888 888 888 8888888888 8888888b. 8888888888 4 * 888 o 888 888 888 888 888 Y88b 888 5 * 888 d8b 888 888 888 888 888 888 888 6 * 888 d888b 888 8888888888 8888888 888 d88P 8888888 7 * 888d88888b888 888 888 888 8888888P" 888 8 * 88888P Y88888 888 888 888 888 T88b 888 9 * 8888P Y8888 888 888 888 888 T88b 888 10 * 888P Y888 888 888 8888888888 888 T88b 8888888888 11 * 12 * 8888888 .d8888b. 88888888888 888 888 8888888888 13 * 888 d88P Y88b 888 888 888 888 14 * 888 Y88b. 888 888 888 888 15 * 888 "Y888b. 888 8888888888 8888888 16 * 888 "Y88b. 888 888 888 888 17 * 888 "888 888 888 888 888 18 * 888 Y88b d88P 888 888 888 888 19 * 8888888 "Y8888P" 888 888 888 8888888888 20 * 21 * 888888 d8888 888 888 d8888 8888888b. .d88888b. .d8888b. 22 * "88b d88888 888 888 d88888 888 "Y88b d88P" "Y88b d88P Y88b 23 * 888 d88P888 888 888 d88P888 888 888 888 888 888 888 24 * 888 d88P 888 Y88b d88P d88P 888 888 888 888 888 888 25 * 888 d88P 888 Y88b d88P d88P 888 888 888 888 888 888 26 * 888 d88P 888 Y88o88P d88P 888 888 888 888 888 888 888 27 * 88P d8888888888 Y888P d8888888888 888 .d88P Y88b. .d88P Y88b d88P 28 * 888 d88P 888 Y8P d88P 888 8888888P" "Y88888P" "Y8888P" 29 * .d88P 30 * .d88P" 31 * 888P" 32 * 33 * .d8888b. 888 .d8888b. 888 .d8888b. 888 34 * d88P Y88b 888 d88P Y88b 888 d88P Y88b 888 35 * .d88P 888 .d88P 888 .d88P 888 36 * .d88P" 888 .d88P" 888 .d88P" 888 37 * 888" 888 888" 888 888" 888 38 * 888 Y8P 888 Y8P 888 Y8P 39 * " " " 40 * 888 888 888 888 888 888 41 * 42 * 43 * TODO: add PROPER class and method documentation, just like have 44 * agreed upon hundreds of times!!!! 45 */ 3 46 class FeatureBase { 4 47 -
trunk/grails-app/domain/dbnp/data/FeatureType.groovy
r496 r540 5 5 */ 6 6 public enum FeatureType { 7 8 9 10 7 QUANTITATIVE('Quantitative'), 8 QUALITATIVE('Qualitative'), 9 PAIRED('Paired'), 10 DIFFERENTIAL('Differential') 11 11 12 12 String name 13 13 14 15 16 14 FeatureType(String name) { 15 this.name = name 16 } 17 17 18 static list() { 19 [QUANTITATIVE, QUALITATIVE, PAIRED, DIFFERENTIAL] 20 } 21 22 /*def String toString() { 23 return this.name 24 }*/ 25 18 static list() { 19 [QUANTITATIVE, QUALITATIVE, PAIRED, DIFFERENTIAL] 20 } 26 21 } -
trunk/grails-app/domain/dbnp/data/Term.groovy
r496 r540 30 30 return name 31 31 } 32 33 32 } -
trunk/grails-app/domain/dbnp/studycapturing/Assay.groovy
r514 r540 7 7 */ 8 8 class Assay { 9 10 9 String name 11 10 AssayModule module -
trunk/grails-app/domain/dbnp/studycapturing/AssayModule.groovy
r496 r540 5 5 */ 6 6 class AssayModule { 7 8 7 String name 9 8 AssayType type -
trunk/grails-app/domain/dbnp/studycapturing/Compound.groovy
r496 r540 46 46 * agreed upon hundreds of times!!!! 47 47 */ 48 class Compound { 49 48 class Compound implements Serializable { 50 49 String name 51 50 Term compound -
trunk/grails-app/domain/dbnp/studycapturing/Event.groovy
r536 r540 44 44 */ 45 45 static List<TemplateField> giveDomainFields() { return Event.domainFields } 46 static final List<TemplateField> domainFields = 47 [ 48 new TemplateField( 49 name: 'startTime', 50 type: TemplateFieldType.RELTIME), 51 new TemplateField( 52 name: 'endTime', 53 type: TemplateFieldType.RELTIME) 54 ] 46 static final List<TemplateField> domainFields = [ 47 new TemplateField( 48 name: 'startTime', 49 type: TemplateFieldType.RELTIME), 50 new TemplateField( 51 name: 'endTime', 52 type: TemplateFieldType.RELTIME) 53 ] 55 54 56 55 def getDuration() { -
trunk/grails-app/domain/dbnp/studycapturing/Person.groovy
r527 r540 46 46 */ 47 47 48 class Person implements java.io.Serializable { 48 class Person implements Serializable { 49 String title 50 String gender 51 String lastName 52 String prefix 53 String firstName 54 String initials 55 String email 56 String fax 57 String phone 58 String mobile 59 String address 49 60 50 String title 51 String gender 52 String lastName 53 String prefix 54 String firstName 55 String initials 56 String email 57 String fax 58 String phone 59 String mobile 60 String address 61 static hasMany = [affiliations: PersonAffiliation] 61 62 62 static hasMany = [affiliations: PersonAffiliation] 63 64 static constraints = { 65 title(nullable:true,blank:true) 66 gender(nullable:true,blank:true) 67 firstName(nullable:true,blank:true) 68 initials(nullable:true,blank:true) 69 prefix(nullable:true,blank:true) 70 lastName(nullable:true,blank:true) 71 email(nullable:true,blank:true) 72 fax(nullable:true,blank:true) 73 phone(nullable:true,blank:true) 74 address(nullable:true,blank:true) 75 mobile(nullable:true,blank:true) 76 } 63 static constraints = { 64 title(nullable: true, blank: true) 65 gender(nullable: true, blank: true) 66 firstName(nullable: true, blank: true) 67 initials(nullable: true, blank: true) 68 prefix(nullable: true, blank: true) 69 lastName(nullable: true, blank: true) 70 email(nullable: true, blank: true) 71 fax(nullable: true, blank: true) 72 phone(nullable: true, blank: true) 73 address(nullable: true, blank: true) 74 mobile(nullable: true, blank: true) 75 } 77 76 } -
trunk/grails-app/domain/dbnp/studycapturing/PersonAffiliation.groovy
r527 r540 46 46 */ 47 47 48 class PersonAffiliation implements java.io.Serializable { 48 class PersonAffiliation implements Serializable { 49 String institute 50 String department 49 51 50 String institute 51 String department 52 String toString() { "${institute} / ${department}" } 52 53 53 String toString() { "${institute} / ${department}" } 54 55 static constraints = { 56 } 54 static constraints = { 55 } 57 56 } -
trunk/grails-app/domain/dbnp/studycapturing/PersonRole.groovy
r527 r540 46 46 */ 47 47 48 class PersonRole implements java.io.Serializable { 48 class PersonRole implements Serializable { 49 String name 49 50 50 String name 51 52 static constraints = { 53 } 51 static constraints = { 52 } 54 53 } -
trunk/grails-app/domain/dbnp/studycapturing/Publication.groovy
r518 r540 47 47 48 48 class Publication implements Serializable { 49 String title 50 String pubMedID 51 String DOI 52 String authorsList 53 String comments 49 54 50 String title 51 String pubMedID 52 String DOI 53 String authorsList 54 String comments 55 56 static constraints = { 57 pubMedID(nullable:true,blank:true) 58 DOI(nullable:true,blank:true) 59 authorsList(nullable:true,blank:true) 60 comments(nullable:true,blank:true) 61 } 55 static constraints = { 56 pubMedID(nullable: true, blank: true) 57 DOI(nullable: true, blank: true) 58 authorsList(nullable: true, blank: true) 59 comments(nullable: true, blank: true) 60 } 62 61 } -
trunk/grails-app/domain/dbnp/studycapturing/RelTime.groovy
r500 r540 4 4 * Contains useful functions for the RelTime templatefield 5 5 * 6 * @author 7 * @since 8 * @package 6 * @author Robert Horlings 7 * @since 20100529 8 * @package dbnp.studycapturing 9 9 * 10 10 * Revision information: … … 16 16 17 17 class RelTime { 18 final static long s = 1L; 19 final static long m = 60L * s; 20 final static long h = 60L * m; 21 final static long d = 24L * h; 22 final static long w = 7L * d; 23 24 private long reltimeValue; 25 26 public RelTime() { 27 this( 0L ); 28 } 29 30 public RelTime( long reltime ) { 31 setValue( reltime); 32 } 33 34 public RelTime( String reltime ) { 35 parse( reltime ); 36 } 37 38 /** 39 * Constructor to create a relative time from two given dates 40 * 41 * The reltime will be the second date, with the first date as reference, 42 * i.e. date2 - date1 43 */ 44 public RelTime( Date date1, Date date2 ) { 45 computeDifference( date1, date2 ); 46 } 47 48 /** 49 * Constructor to create a relative time from two given relative times 50 * 51 * The reltime will be the second date, with the first date as reference, 52 * i.e. date2 - date1 53 */ 54 public RelTime( RelTime date1, RelTime date2 ) { 55 this( date1.getValue(), date2.getValue() ); 56 } 57 58 /** 59 * Constructor to create a relative time from two given relative times 60 * 61 * The reltime will be the second date, with the first date as reference, 62 * i.e. date2 - date1 63 */ 64 public RelTime( long date1, long date2 ) { 65 setValue( date2 - date1 ); 66 } 67 68 /** 69 * Return simple string version of this reltime 70 */ 71 public String toString() { 72 def negative = this.reltimeValue < 0; 73 def reltime = this.reltimeValue.abs(); 74 75 def seconds = Math.floor( (reltime % m) / s ).toInteger(); 76 def minutes = Math.floor( (reltime % h) / m ).toInteger(); 77 def hours = Math.floor( (reltime % d) / h ).toInteger(); 78 def days = Math.floor( (reltime % w) / d ).toInteger(); 79 def weeks = Math.floor( reltime / w ).toInteger(); 80 81 def stringValue = negative ? "-" : "" ; 82 if( weeks > 0 ) { stringValue += weeks + "w "; } 83 if( days > 0 ) { stringValue += days + "d "; } 84 if( hours > 0 ) { stringValue += hours + "h "; } 85 if( minutes > 0 ) { stringValue += minutes + "m "; } 86 if( seconds > 0 ) { stringValue += seconds + "s "; } 87 88 return stringValue.trim(); 89 } 90 91 /** 92 * Return pretty human readable string of this reltime 93 */ 94 public String toPrettyString() { 95 // Method to handle the difference between 1 day and 2 dayS 96 def handleNumerus = {number, string -> 97 return number.toString() + (number == 1 ? string : string + 's') 98 } 99 100 def negative = this.reltimeValue < 0; 101 def reltime = this.reltimeValue.abs(); 102 103 def seconds = Math.floor( (reltime % m) / s ).toInteger(); 104 def minutes = Math.floor( (reltime % h) / m ).toInteger(); 105 def hours = Math.floor( (reltime % d) / h ).toInteger(); 106 def days = Math.floor( (reltime % w) / d ).toInteger(); 107 def weeks = Math.floor( reltime / w ).toInteger(); 108 109 def stringValue = negative ? "-" : "" ; 110 def values = []; 111 if( weeks > 0 ) { values << handleNumerus( weeks, " week" ) } 112 if( days > 0 ) { values << handleNumerus( days, " day" ) } 113 if( hours > 0 ) { values << handleNumerus( hours, " hour" ) } 114 if( minutes > 0 ) { values << handleNumerus( minutes, " minute" ) } 115 if( seconds > 0 ) { values << handleNumerus( seconds, " second" ) } 116 117 return stringValue + values.join( ', ' ).trim(); 118 } 119 120 /** 121 * Return pretty human readable string of this reltime 122 */ 123 public String toPrettyRoundedString() { 124 // Method to handle the difference between 1 day and 2 dayS 125 def handleNumerus = {number, string -> 126 return number.toString() + (number == 1 ? string : string + 's') 127 } 128 129 def negative = this.reltimeValue < 0; 130 def reltime = this.reltimeValue.abs(); 131 132 def seconds = Math.floor( (reltime % m) / s ).toInteger(); 133 def minutes = Math.floor( (reltime % h) / m ).toInteger(); 134 def hours = Math.floor( (reltime % d) / h ).toInteger(); 135 def days = Math.floor( (reltime % w) / d ).toInteger(); 136 def weeks = Math.floor( reltime / w ).toInteger(); 137 138 def stringValue = negative ? "-" : "" ; 139 if( weeks > 0 ) { return stringValue + handleNumerus( weeks, " week" ) } 140 if( days > 0 ) { return stringValue + handleNumerus( days, " day" ) } 141 if( hours > 0 ) { return stringValue + handleNumerus( hours, " hour" ) } 142 if( minutes > 0 ) { return stringValue + handleNumerus( minutes, " minute" ) } 143 if( seconds > 0 ) { return stringValue + handleNumerus( seconds, " second" ) } 144 145 return ""; 146 } 147 148 149 /** 150 * Returns the value in seconds 151 */ 152 public long getValue() { 153 return reltimeValue; 154 } 155 156 /** 157 * Sets the value in seconds 158 */ 159 public void setValue( long value ) { 160 reltimeValue = value; 161 } 162 163 /** 164 * Sets the value as a string. 165 */ 166 public void setValue( String value ) { 167 parse( value ); 168 } 169 170 /** 171 * Parses a string into a RelTime long 172 * 173 * The relative time may be set as a string, using the following format 174 * 175 * #w #d #h #m #s 176 * 177 * Where w = weeks, d = days, h = hours, m = minutes, s = seconds 178 * 179 * The spaces between the values are optional. Every timespan 180 * (w, d, h, m, s) must appear at most once. You can also omit 181 * timespans if needed or use a different order. 182 * Other characters are disregarded, allthough results may not 183 * always be as expected. 184 * 185 * If an incorrect format is used, which can't be parsed 186 * an IllegalArgumentException is thrown. 187 * 188 * An empty span is treated as zero seconds. 189 * 190 * Examples: 191 * --------- 192 * 5d 3h 20m // 5 days, 3 hours and 20 minutes 193 * 6h 2d // 2 days, 6 hours 194 * 10m 200s // 13 minutes, 20 seconds (200s == 3m + 20s) 195 * 5w4h15m // 5 weeks, 4 hours, 15 minutes 196 * 197 * 16x14w10d // Incorrect. 16x is disregarded, so the 198 * // result is 15 weeks, 3 days 199 * 13days // Incorrect: days should be d, but this is 200 * // parsed as 13d, 0 seconds 201 */ 202 public void parse( String value ) { 203 long newvalue; 204 205 // An empty string should be parsed as 0 206 if( value == null || value.trim() == "" || value.trim() == "-" ) { 207 newvalue = 0L; 208 } else { 209 // Check whether it is a negative number 210 // this is indicated by a dash in front 211 def multiplier = 1L; 212 if( value.trim()[0] == '-' ) 213 { 214 multiplier = -1L; 215 } 216 217 // Find all parts that contain numbers with 218 // a character w, d, h, m or s after it 219 def periodMatch = value =~ /([0-9]+)\s*([wdhms])/ 220 if (periodMatch.size() > 0 ) { 221 def seconds = 0L; 222 223 // Now check if every part contains data for 224 // the time interval 225 periodMatch.each { 226 def partValue 227 228 if( it[1].isLong() ) { 229 partValue = Long.parseLong( it[1] ); 230 } else { 231 partValue = 0; 232 } 233 234 switch( it[ 2 ] ) { 235 case 'w': 236 seconds += w * partValue; 237 break; 238 case 'd': 239 seconds += d * partValue; 240 break; 241 case 'h': 242 seconds += h * partValue; 243 break; 244 case 'm': 245 seconds += m * partValue; 246 break; 247 case 's': 248 seconds += s * partValue; 249 break; 250 default: 251 adf.error.warn( 'Parsing relative time: ' + it[0] + it[1] + ' is not understood and disregarded' ); 252 break; 253 } 254 } 255 256 // Continue with the computed value 257 newvalue = multiplier * seconds; 258 } else { 259 throw new IllegalArgumentException( "String " + value + " cannot be parsed as a relative time. Use format #w #d #h #m #s." ); 260 return; 261 } 262 } 263 264 setValue( newvalue ); 265 } 266 267 public void computeDifference( Date start, Date end ) { 268 println( [ start, end ] ); 269 println( [ start.getTime(), end.getTime() ]); 270 271 if( start && end ) { 272 long seconds = (end.getTime() - start.getTime()) / 1000L; 273 setValue( seconds ); 274 } else { 275 setValue( 0 ); 276 } 277 } 278 279 static RelTime parseRelTime( String value ) { 280 RelTime reltime = new RelTime(); 281 reltime.parse( value ); 282 return reltime; 283 } 18 final static long s = 1L; 19 final static long m = 60L * s; 20 final static long h = 60L * m; 21 final static long d = 24L * h; 22 final static long w = 7L * d; 23 24 private long reltimeValue; 25 26 public RelTime() { 27 this(0L); 28 } 29 30 public RelTime(long reltime) { 31 setValue(reltime); 32 } 33 34 public RelTime(String reltime) { 35 parse(reltime); 36 } 37 38 /** 39 * Constructor to create a relative time from two given dates 40 * 41 * The reltime will be the second date, with the first date as reference, 42 * i.e. date2 - date1 43 */ 44 public RelTime(Date date1, Date date2) { 45 computeDifference(date1, date2); 46 } 47 48 /** 49 * Constructor to create a relative time from two given relative times 50 * 51 * The reltime will be the second date, with the first date as reference, 52 * i.e. date2 - date1 53 */ 54 public RelTime(RelTime date1, RelTime date2) { 55 this(date1.getValue(), date2.getValue()); 56 } 57 58 /** 59 * Constructor to create a relative time from two given relative times 60 * 61 * The reltime will be the second date, with the first date as reference, 62 * i.e. date2 - date1 63 */ 64 public RelTime(long date1, long date2) { 65 setValue(date2 - date1); 66 } 67 68 /** 69 * Return simple string version of this reltime 70 */ 71 public String toString() { 72 def negative = this.reltimeValue < 0; 73 def reltime = this.reltimeValue.abs(); 74 75 def seconds = Math.floor((reltime % m) / s).toInteger(); 76 def minutes = Math.floor((reltime % h) / m).toInteger(); 77 def hours = Math.floor((reltime % d) / h).toInteger(); 78 def days = Math.floor((reltime % w) / d).toInteger(); 79 def weeks = Math.floor(reltime / w).toInteger(); 80 81 def stringValue = negative ? "-" : ""; 82 if (weeks > 0) { stringValue += weeks + "w "; } 83 if (days > 0) { stringValue += days + "d "; } 84 if (hours > 0) { stringValue += hours + "h "; } 85 if (minutes > 0) { stringValue += minutes + "m "; } 86 if (seconds > 0) { stringValue += seconds + "s "; } 87 88 return stringValue.trim(); 89 } 90 91 /** 92 * Return pretty human readable string of this reltime 93 */ 94 public String toPrettyString() { 95 // Method to handle the difference between 1 day and 2 dayS 96 def handleNumerus = {number, string -> 97 return number.toString() + (number == 1 ? string : string + 's') 98 } 99 100 def negative = this.reltimeValue < 0; 101 def reltime = this.reltimeValue.abs(); 102 103 def seconds = Math.floor((reltime % m) / s).toInteger(); 104 def minutes = Math.floor((reltime % h) / m).toInteger(); 105 def hours = Math.floor((reltime % d) / h).toInteger(); 106 def days = Math.floor((reltime % w) / d).toInteger(); 107 def weeks = Math.floor(reltime / w).toInteger(); 108 109 def stringValue = negative ? "-" : ""; 110 def values = []; 111 if (weeks > 0) { values << handleNumerus(weeks, " week") } 112 if (days > 0) { values << handleNumerus(days, " day") } 113 if (hours > 0) { values << handleNumerus(hours, " hour") } 114 if (minutes > 0) { values << handleNumerus(minutes, " minute") } 115 if (seconds > 0) { values << handleNumerus(seconds, " second") } 116 117 return stringValue + values.join(', ').trim(); 118 } 119 120 /** 121 * Return pretty human readable string of this reltime 122 */ 123 public String toPrettyRoundedString() { 124 // Method to handle the difference between 1 day and 2 dayS 125 def handleNumerus = {number, string -> 126 return number.toString() + (number == 1 ? string : string + 's') 127 } 128 129 def negative = this.reltimeValue < 0; 130 def reltime = this.reltimeValue.abs(); 131 132 def seconds = Math.floor((reltime % m) / s).toInteger(); 133 def minutes = Math.floor((reltime % h) / m).toInteger(); 134 def hours = Math.floor((reltime % d) / h).toInteger(); 135 def days = Math.floor((reltime % w) / d).toInteger(); 136 def weeks = Math.floor(reltime / w).toInteger(); 137 138 def stringValue = negative ? "-" : ""; 139 if (weeks > 0) { return stringValue + handleNumerus(weeks, " week") } 140 if (days > 0) { return stringValue + handleNumerus(days, " day") } 141 if (hours > 0) { return stringValue + handleNumerus(hours, " hour") } 142 if (minutes > 0) { return stringValue + handleNumerus(minutes, " minute") } 143 if (seconds > 0) { return stringValue + handleNumerus(seconds, " second") } 144 145 return ""; 146 } 147 148 /** 149 * Returns the value in seconds 150 */ 151 public long getValue() { 152 return reltimeValue; 153 } 154 155 /** 156 * Sets the value in seconds 157 */ 158 public void setValue(long value) { 159 reltimeValue = value; 160 } 161 162 /** 163 * Sets the value as a string. 164 */ 165 public void setValue(String value) { 166 parse(value); 167 } 168 169 /** 170 * Parses a string into a RelTime long 171 * 172 * The relative time may be set as a string, using the following format 173 * 174 * #w #d #h #m #s 175 * 176 * Where w = weeks, d = days, h = hours, m = minutes, s = seconds 177 * 178 * The spaces between the values are optional. Every timespan 179 * (w, d, h, m, s) must appear at most once. You can also omit 180 * timespans if needed or use a different order. 181 * Other characters are disregarded, allthough results may not 182 * always be as expected. 183 * 184 * If an incorrect format is used, which can't be parsed 185 * an IllegalArgumentException is thrown. 186 * 187 * An empty span is treated as zero seconds. 188 * 189 * Examples: 190 * --------- 191 * 5d 3h 20m // 5 days, 3 hours and 20 minutes 192 * 6h 2d // 2 days, 6 hours 193 * 10m 200s // 13 minutes, 20 seconds (200s == 3m + 20s) 194 * 5w4h15m // 5 weeks, 4 hours, 15 minutes 195 * 196 * 16x14w10d // Incorrect. 16x is disregarded, so the 197 * // result is 15 weeks, 3 days 198 * 13days // Incorrect: days should be d, but this is 199 * // parsed as 13d, 0 seconds 200 */ 201 public void parse(String value) { 202 long newvalue; 203 204 // An empty string should be parsed as 0 205 if (value == null || value.trim() == "" || value.trim() == "-") { 206 newvalue = 0L; 207 } else { 208 // Check whether it is a negative number 209 // this is indicated by a dash in front 210 def multiplier = 1L; 211 if (value.trim()[0] == '-') { 212 multiplier = -1L; 213 } 214 215 // Find all parts that contain numbers with 216 // a character w, d, h, m or s after it 217 def periodMatch = value =~ /([0-9]+)\s*([wdhms])/ 218 if (periodMatch.size() > 0) { 219 def seconds = 0L; 220 221 // Now check if every part contains data for 222 // the time interval 223 periodMatch.each { 224 def partValue 225 226 if (it[1].isLong()) { 227 partValue = Long.parseLong(it[1]); 228 } else { 229 partValue = 0; 230 } 231 232 switch (it[2]) { 233 case 'w': 234 seconds += w * partValue; 235 break; 236 case 'd': 237 seconds += d * partValue; 238 break; 239 case 'h': 240 seconds += h * partValue; 241 break; 242 case 'm': 243 seconds += m * partValue; 244 break; 245 case 's': 246 seconds += s * partValue; 247 break; 248 default: 249 adf.error.warn('Parsing relative time: ' + it[0] + it[1] + ' is not understood and disregarded'); 250 break; 251 } 252 } 253 254 // Continue with the computed value 255 newvalue = multiplier * seconds; 256 } else { 257 throw new IllegalArgumentException("String " + value + " cannot be parsed as a relative time. Use format #w #d #h #m #s."); 258 return; 259 } 260 } 261 262 setValue(newvalue); 263 } 264 265 public void computeDifference(Date start, Date end) { 266 println([start, end]); 267 println([start.getTime(), end.getTime()]); 268 269 if (start && end) { 270 long seconds = (end.getTime() - start.getTime()) / 1000L; 271 setValue(seconds); 272 } else { 273 setValue(0); 274 } 275 } 276 277 static RelTime parseRelTime(String value) { 278 RelTime reltime = new RelTime(); 279 reltime.parse(value); 280 return reltime; 281 } 284 282 } -
trunk/grails-app/domain/dbnp/studycapturing/Sample.groovy
r506 r540 12 12 SamplingEvent parentEvent 13 13 14 String name // should be unique with respect to the parent study (which can be inferred)14 String name // should be unique with respect to the parent study (which can be inferred) 15 15 Term material // a member that describes the quantity of the sample? --> should be in the templates 16 16 … … 20 20 */ 21 21 static List<TemplateField> giveDomainFields() { return Sample.domainFields } 22 static List<TemplateField> domainFields = 23 [ 24 new TemplateField( 25 name: 'name', 26 type: TemplateFieldType.STRING, 27 preferredIdentifier: true), 28 new TemplateField( 29 name: 'material', 30 type: TemplateFieldType.ONTOLOGYTERM ) 31 ] 22 static List<TemplateField> domainFields = [ 23 new TemplateField( 24 name: 'name', 25 type: TemplateFieldType.STRING, 26 preferredIdentifier: true 27 ), 28 new TemplateField( 29 name: 'material', 30 type: TemplateFieldType.ONTOLOGYTERM 31 ) 32 ] 32 33 33 34 static constraints = { … … 36 37 37 38 static getSamplesFor( event ) { 38 39 return Sample.findAll( 'from Sample s where s.parentEvent =:event', [event:event] ) 39 40 } 40 41 41 } -
trunk/grails-app/domain/dbnp/studycapturing/SamplingEvent.groovy
r496 r540 56 56 class SamplingEvent extends Event { 57 57 58 59 58 static constraints = { 59 } 60 60 61 61 def getSamples() { 62 62 63 def samples = Sample.findAll("from Sample as s where s.parentEvent.id = ${this.id}")64 samples.collect{ it.class==SamplingEvent.class }65 samples.collect{ it!=null }66 return samples==null ? [] : samples67 63 def samples = Sample.findAll("from Sample as s where s.parentEvent.id = ${this.id}") 64 samples.collect { it.class == SamplingEvent.class } 65 samples.collect { it != null } 66 return samples == null ? [] : samples 67 } 68 68 69 69 } -
trunk/grails-app/domain/dbnp/studycapturing/Study.groovy
r536 r540 16 16 Date lastUpdated 17 17 Date startDate 18 long externalStudyID // enables referring to studies outside of GSCF, e.g., in the Simple Assay Module18 long externalStudyID // enables referring to studies outside of GSCF, e.g., in the Simple Assay Module 19 19 20 20 /** … … 24 24 static List<TemplateField> giveDomainFields() { return Study.domainFields } 25 25 26 static final List<TemplateField> domainFields = 27 [ 26 static final List<TemplateField> domainFields = [ 28 27 new TemplateField( 29 28 name: 'title', … … 63 62 */ 64 63 def String toString() { 65 return title ;64 return title 66 65 } 67 66 68 /** 69 * returns all events and sampling events that do not belong to a group 70 */ 71 def Set<Event> getOrphanEvents() { 72 def orphans = 73 events.findAll{ event -> !event.belongsToGroup( eventGroups ) } + 74 samplingEvents.findAll { event -> !event.belongsToGroup( eventGroups ) }; 67 /** 68 * returns all events and sampling events that do not belong to a group 69 */ 70 def Set<Event> getOrphanEvents() { 71 def orphans = events.findAll { event -> !event.belongsToGroup(eventGroups) } + 72 samplingEvents.findAll { event -> !event.belongsToGroup(eventGroups) } 75 73 76 return orphans; 77 74 return orphans 75 } 78 76 79 77 /** … … 81 79 */ 82 80 def Set<Template> giveSubjectTemplates() { 83 TemplateEntity.giveTemplates(subjects) ;81 TemplateEntity.giveTemplates(subjects) 84 82 } 85 83 … … 91 89 // gives trouble when asking .size() to the result 92 90 // So we also use giveTemplates here 93 TemplateEntity.giveTemplates(events + samplingEvents) ;91 TemplateEntity.giveTemplates(events + samplingEvents) 94 92 } 95 93 … … 98 96 */ 99 97 Set<Template> giveEventTemplates() { 100 TemplateEntity.giveTemplates(events) ;98 TemplateEntity.giveTemplates(events) 101 99 } 102 100 … … 105 103 */ 106 104 Set<Template> giveSamplingEventTemplates() { 107 TemplateEntity.giveTemplates(samplingEvents) ;105 TemplateEntity.giveTemplates(samplingEvents) 108 106 } 109 107 … … 112 110 */ 113 111 Set<Template> giveSampleTemplates() { 114 TemplateEntity.giveTemplates(samples) ;112 TemplateEntity.giveTemplates(samples) 115 113 } 116 114 /** … … 118 116 */ 119 117 Template giveStudyTemplate() { 120 return this.template ;118 return this.template 121 119 } 122 120 } -
trunk/grails-app/domain/dbnp/studycapturing/StudyPerson.groovy
r527 r540 49 49 * Link table which couples studies with persons and the role they have within the study 50 50 */ 51 class StudyPerson implements java.io.Serializable {51 class StudyPerson implements Serializable { 52 52 Person person 53 53 PersonRole role -
trunk/grails-app/domain/dbnp/studycapturing/Subject.groovy
r506 r540 16 16 String name 17 17 Term species 18 18 19 19 /** 20 20 * return the domain fields for this domain class … … 23 23 static List<TemplateField> giveDomainFields() { return Subject.domainFields; } 24 24 25 static List<TemplateField> domainFields = 26 [ 27 new TemplateField( 28 name: 'name', 29 type: TemplateFieldType.STRING, 30 preferredIdentifier: true, 31 comment: 'Use the local subject name or the pre-defined name'), 32 new TemplateField( 33 name: 'species', 34 type: TemplateFieldType.ONTOLOGYTERM, 35 comment: "The species name is based on the NEWT ontology; if a species is missing, please add it to the ontology using 'add more'") 36 ] 25 static List<TemplateField> domainFields = [ 26 new TemplateField( 27 name: 'name', 28 type: TemplateFieldType.STRING, 29 preferredIdentifier: true, 30 comment: 'Use the local subject name or the pre-defined name'), 31 new TemplateField( 32 name: 'species', 33 type: TemplateFieldType.ONTOLOGYTERM, 34 comment: "The species name is based on the NEWT ontology; if a species is missing, please add it to the ontology using 'add more'") 35 ] 37 36 } -
trunk/grails-app/domain/dbnp/studycapturing/Template.groovy
r513 r540 36 36 /** 37 37 * Look up the type of a certain template subject field 38 * @param StringfieldName The name of the template field39 * @return 38 * @param String fieldName The name of the template field 39 * @return String The type (static member of TemplateFieldType) of the field, or null of the field does not exist 40 40 */ 41 41 def TemplateFieldType getFieldType(String fieldName) { 42 42 def field = fields.find { 43 it.name == fieldName 43 it.name == fieldName 44 44 } 45 45 field?.type … … 48 48 /** 49 49 * get all field of a particular type 50 * @param ClassfieldType51 * @return Set<TemplateField>50 * @param Class fieldType 51 * @return Set < TemplateField > 52 52 */ 53 53 def getFieldsByType(TemplateFieldType fieldType) { … … 60 60 /** 61 61 * get all required fields 62 * @param ClassfieldType63 * @return Set<TemplateField>62 * @param Class fieldType 63 * @return Set < TemplateField > 64 64 */ 65 65 def getRequiredFields() { … … 72 72 /** 73 73 * overloading the findAllByEntity method to make it function as expected 74 * @param Classentity (for example: dbnp.studycapturing.Subject)75 * @return 74 * @param Class entity (for example: dbnp.studycapturing.Subject) 75 * @return ArrayList 76 76 */ 77 77 public static findAllByEntity(java.lang.Class entity) { … … 80 80 Template.findAll().each() { 81 81 if (entity.equals(it.entity)) { 82 results[ results.size()] = it82 results[results.size()] = it 83 83 } 84 84 } -
trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy
r538 r540 22 22 Map templateDateFields = [:] 23 23 24 25 // N.B. If you try to set Long.MIN_VALUE for a reltime field, an error will occur 26 // However, this will never occur in practice: this value represents 3 bilion centuries 27 Map templateRelTimeFields = [:] // Contains relative times in seconds 24 // N.B. If you try to set Long.MIN_VALUE for a reltime field, an error will occur 25 // However, this will never occur in practice: this value represents 3 bilion centuries 26 Map templateRelTimeFields = [:] // Contains relative times in seconds 28 27 Map templateFileFields = [:] // Contains filenames 29 28 Map templateTermFields = [:] … … 39 38 templateTermFields: Term, 40 39 templateRelTimeFields: long, 41 40 templateFileFields: String, 42 41 systemFields: TemplateField 43 42 ] … … 49 48 } 50 49 51 50 def fileService 52 51 53 52 /** … … 213 212 def error = false 214 213 fields.each { key, value -> 215 if( value && value == Long.MIN_VALUE) {216 217 218 219 220 221 222 223 214 if (value && value == Long.MIN_VALUE) { 215 error = true 216 errors.rejectValue( 217 'templateRelTimeFields', 218 'templateEntity.typeMismatch.reltime', 219 [key, value] as Object[], 220 'Value cannot be parsed for property {0}' 221 ) 222 } else if (value && value.class != long) { 224 223 try { 225 224 fields[key] = (value as long) … … 273 272 fields[key] = (value as String) 274 273 275 276 277 278 274 // Find the file on the system 275 // if it does not exist, the filename can 276 // not be entered 277 279 278 } catch (Exception e) { 280 279 // could not typecast properly, value is of improper type … … 435 434 // 436 435 if (field.type == TemplateFieldType.RELTIME && value != null && value.class == String) { 437 438 439 440 441 442 443 444 445 } catch( IllegalArgumentException e) {446 447 448 } 449 450 451 if( !fileService) {452 453 436 // A string was given, attempt to transform it into a timespan 437 // If it cannot be parsed, set the lowest possible value of Long. 438 // The validator method will raise an error 439 // 440 // N.B. If you try to set Long.MIN_VALUE itself, an error will occur 441 // However, this will never occur: this value represents 3 bilion centuries 442 try { 443 value = RelTime.parseRelTime(value).getValue(); 444 } catch (IllegalArgumentException e) { 445 value = Long.MIN_VALUE; 446 } 447 } 448 449 // Sometimes the fileService is not created yet 450 if (!fileService) { 451 fileService = new FileService(); 452 } 454 453 455 454 // Magic setter for files: handle values for file fields 456 457 458 459 460 461 462 463 455 // 456 // If NULL is given, the field value is emptied and the old file is removed 457 // If an empty string is given, the field value is kept as was 458 // If a file is given, it is moved to the right directory. Old files are deleted. If 459 // the file does not exist, the field is kept 460 // If a string is given, it is supposed to be a file in the upload directory. If 461 // it is different from the old one, the old one is deleted. If the file does not 462 // exist, the old one is kept. 464 463 if (field.type == TemplateFieldType.FILE) { 465 def currentFile = getFieldValue( field.name ); 466 467 if( value == null ) { 468 // If NULL is given, the field value is emptied and the old file is removed 469 value = ""; 470 if( currentFile ) 471 { 472 fileService.delete( currentFile ) 473 } 474 } else if( value.class == File ) { 475 // a file was given. Attempt to move it to the upload directory, and 476 // afterwards, store the filename. If the file doesn't exist 477 // or can't be moved, "" is returned 478 value = fileService.moveFileToUploadDir( value ); 479 480 if( value ) { 481 if( currentFile ) 482 { 483 fileService.delete( currentFile ) 484 } 485 } else { 486 value = currentFile; 487 } 488 } else if ( value == "" ) { 489 value = currentFile; 490 } else { 491 if( value != currentFile ) { 492 if( fileService.fileExists( value ) ) { 493 // When a FILE field is filled, and a new file is set 494 // the existing file should be deleted 495 if( currentFile ) 496 { 497 fileService.delete( currentFile ) 498 } 499 } else { 500 // If the file does not exist, the field is kept 501 value = currentFile; 502 } 503 } 504 } 505 } 506 464 def currentFile = getFieldValue(field.name); 465 466 if (value == null) { 467 // If NULL is given, the field value is emptied and the old file is removed 468 value = ""; 469 if (currentFile) { 470 fileService.delete(currentFile) 471 } 472 } else if (value.class == File) { 473 // a file was given. Attempt to move it to the upload directory, and 474 // afterwards, store the filename. If the file doesn't exist 475 // or can't be moved, "" is returned 476 value = fileService.moveFileToUploadDir(value); 477 478 if (value) { 479 if (currentFile) { 480 fileService.delete(currentFile) 481 } 482 } else { 483 value = currentFile; 484 } 485 } else if (value == "") { 486 value = currentFile; 487 } else { 488 if (value != currentFile) { 489 if (fileService.fileExists(value)) { 490 // When a FILE field is filled, and a new file is set 491 // the existing file should be deleted 492 if (currentFile) { 493 fileService.delete(currentFile) 494 } 495 } else { 496 // If the file does not exist, the field is kept 497 value = currentFile; 498 } 499 } 500 } 501 } 507 502 508 503 // Magic setter for ontology terms: handle string values … … 606 601 /** 607 602 * Convenience method. Returns all unique templates used within a collection of TemplateEntities. 608 609 610 603 * 604 * If the collection is empty, an empty set is returned. If none of the entities contains 605 * a template, also an empty set is returned. 611 606 */ 612 607 static Set<Template> giveTemplates(Set<TemplateEntity> entityCollection) { 613 614 615 616 617 608 def set = entityCollection*.template.unique(); 609 610 // If one or more entities does not have a template, the resulting 611 // set contains null. That is not what is meant. 612 return set.findAll { it != null }; 618 613 } 619 614 -
trunk/grails-app/domain/dbnp/studycapturing/TemplateField.groovy
r496 r540 20 20 boolean preferredIdentifier 21 21 22 23 listEntries 24 ontologies: Ontology // to store the ontologies to choose from when the type is 'ontology term'22 static hasMany = [ 23 listEntries: TemplateFieldListItem, // to store the entries to choose from when the type is 'item from predefined list' 24 ontologies: Ontology // to store the ontologies to choose from when the type is 'ontology term' 25 25 ] 26 26 27 27 static constraints = { 28 28 // TODO: verify that TemplateField names are unique within templates of each super entity 29 29 unit(nullable: true, blank: true) 30 comment(nullable: true, blank: true)30 comment(nullable: true, blank: true) 31 31 required(default: false) 32 32 preferredIdentifier(default: false) … … 34 34 35 35 static mapping = { 36 36 // TODO: this doesn't seem to work in Postgres 37 37 comment type: 'text' 38 38 } … … 47 47 */ 48 48 def String escapedName() { 49 return name.toLowerCase().replaceAll("([^a-z0-9])", "_")49 return name.toLowerCase().replaceAll("([^a-z0-9])", "_") 50 50 } 51 51 } -
trunk/grails-app/domain/dbnp/studycapturing/TemplateFieldType.groovy
r507 r540 8 8 * $Date$ 9 9 */ 10 public enum TemplateFieldType implements Serializable 10 public enum TemplateFieldType implements Serializable { 11 11 STRING('String'), 12 12 TEXT('Long string'), … … 18 18 DATE('Date'), 19 19 RELTIME('Relative time'), // relative date, e.g. days since start of study 20 20 FILE('File') 21 21 22 22 String name … … 48 48 case RELTIME: 49 49 return null 50 51 50 case FILE: 51 return "" 52 52 default: 53 53 throw new NoSuchFieldException("Field type ${fieldType} not recognized") -
trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy
r539 r540 964 964 name: prependName + it.escapedName(), 965 965 value: new RelTime( fieldValue ).toString(), 966 967 966 addExampleElement: true, 967 onBlur: 'showExampleReltime(this)' 968 968 ){helpText} 969 969 break … … 974 974 name: prependName + it.escapedName(), 975 975 value: fieldValue ? fieldValue : "", 976 976 addExampleElement: true 977 977 ){helpText} 978 978 break
Note: See TracChangeset
for help on using the changeset viewer.