Changeset 4822
- Timestamp:
- Mar 19, 2009, 2:06:45 PM (15 years ago)
- Location:
- trunk/src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/core/net/sf/basedb/core/Annotation.java
r4743 r4822 420 420 { 421 421 converter = getUnitConverter(unit); 422 if (converter != null && value instanceof Number) 422 Type valueType = getValueType(); 423 if (value instanceof Number) 423 424 { 424 value = converter.convertToReferenceUnit(((Number)value).doubleValue()); 425 Number numericValue = (Number)value; 426 if (converter != null) 427 { 428 numericValue = converter.convertToReferenceUnit(numericValue.doubleValue()); 429 } 430 value = valueType.convertNumber(numericValue); 425 431 } 426 432 } … … 472 478 for (Object value : values) 473 479 { 474 if ( converter != null && value instanceof Number)480 if (value instanceof Number) 475 481 { 476 value = valueType.convertNumber(converter.convertToReferenceUnit(((Number)value).doubleValue())); 482 Number numericValue = (Number)value; 483 if (converter != null) 484 { 485 numericValue = converter.convertToReferenceUnit(numericValue.doubleValue()); 486 } 487 value = valueType.convertNumber(numericValue); 477 488 } 478 489 annotationType.validateAnnotationValue(value); -
trunk/src/core/net/sf/basedb/core/AnnotationType.java
r4696 r4822 1233 1233 1234 1234 /** 1235 Validate an annotation value. We check the following: 1235 Validate an annotation value assuming that the value 1236 is in the default unit. 1237 @param value The object to be validated 1238 @throws InvalidDataException If the value object can not be used. 1239 @see #validateAnnotationValue(Object, Unit) 1240 @see #getDefaultUnit() 1241 */ 1242 public void validateAnnotationValue(Object value) 1243 throws InvalidDataException 1244 { 1245 validateAnnotationValue(value, null); 1246 } 1247 1248 /** 1249 Validate an annotation value that can be in a different unit than 1250 the default unit. We check the following: 1236 1251 <ul> 1237 <li>The object is of the correct type, ie. <code>Float</code> if {@link #getValueType()} 1238 returns {@link Type#FLOAT}, etc. 1252 <li>The object is of the correct type, ie. <code>Float</code> 1253 if {@link #getValueType()} returns {@link Type#FLOAT}, etc. 1254 NOTE! If a unit is specified it is only required that the 1255 value is a {@link Number}. It will automatically be converted 1256 to the correct class after unit conversion has taken place. 1239 1257 <li>The value is within the min and max bouds if specified 1240 1258 <li>A string value is not too long … … 1243 1261 </ul> 1244 1262 @param value The object to be validated 1263 @param unit The unit if the value, this parameter is ignored if 1264 the value type doesn't support units (eg. strings) or if the 1265 no default unit has been set for this annotation type 1266 @return The validated value which may have been converted to the 1267 default unit 1245 1268 @throws InvalidDataException If the value object can not be used. 1246 */ 1247 public void validateAnnotationValue(Object value) 1269 @since 2.11 1270 */ 1271 public Object validateAnnotationValue(Object value, Unit unit) 1248 1272 throws InvalidDataException 1249 1273 { 1250 1274 if (value == null) throw new InvalidUseOfNullException("value"); 1251 1275 Type valueType = getValueType(); 1276 1277 if (supportUnits() && unit != null && value instanceof Number) 1278 { 1279 Unit defaultUnit = getDefaultUnit(); 1280 value = valueType.convertNumber( 1281 defaultUnit.fromOther(((Number)value).doubleValue(), unit)); 1282 } 1252 1283 valueType.validate(value); 1284 1253 1285 if (valueType == Type.INT) 1254 1286 { … … 1361 1393 } 1362 1394 } 1395 return value; 1363 1396 } 1364 1397 -
trunk/src/plugins/core/net/sf/basedb/plugins/AnnotationFlatFileImporter.java
r4669 r4822 64 64 import net.sf.basedb.core.StringTooLongException; 65 65 import net.sf.basedb.core.Type; 66 import net.sf.basedb.core.Unit; 66 67 import net.sf.basedb.core.Version; 67 68 import net.sf.basedb.core.plugin.About; … … 88 89 import net.sf.basedb.util.parser.Mapper; 89 90 import net.sf.basedb.util.parser.FlatFileParser.Data; 91 import net.sf.basedb.util.units.UnitCache; 92 import net.sf.basedb.util.units.UnitUtil; 90 93 91 94 /** … … 345 348 permissions.add(new Permissions(Item.FILE, null, EnumSet.of(Permission.READ))); 346 349 permissions.add(new Permissions(Item.ANNOTATIONTYPE, null, EnumSet.of(Permission.READ))); 347 350 permissions.add(new Permissions(Item.UNIT, EnumSet.of(Permission.READ), null)); 351 permissions.add(new Permissions(Item.QUANTITY, EnumSet.of(Permission.READ), null)); 348 352 for (GuiContext ctx : getGuiContexts()) 349 353 { … … 591 595 private List<String> columnHeaders; 592 596 private DbControl dc; 597 private UnitCache unitCache; 593 598 private FlatFileParser ffp; 594 599 private NumberFormat numberFormat; … … 694 699 { 695 700 this.dc = sc.newDbControl(); 701 this.unitCache = new UnitCache(dc); 696 702 697 703 // Mapper to get name or external ID … … 786 792 787 793 Object annotationValue = null; 794 Unit unit = null; 795 Unit defaultUnit = at.getDefaultUnit(); 788 796 try 789 797 { … … 794 802 if (enumValue != null) sValue = enumValue; 795 803 } 796 annotationValue = at.getValueType().parseString(sValue, numberFormat, false); 804 if (at.supportUnits()) 805 { 806 // Check if the value is followed by a unit 807 String[] valueAndUnit = UnitUtil.splitValueWithUnit(sValue); 808 if (valueAndUnit != null) 809 { 810 String unitSymbol = valueAndUnit[1]; 811 if (unitSymbol != null) 812 { 813 // Yes.. there is a unit, look it up 814 unit = unitCache.findUnit(at.getQuantity(), unitSymbol); 815 if (unit == null) 816 { 817 // The unit doesn't exists 818 throw new NumberFormatException("Unknown unit for value: " + sValue); 819 } 820 } 821 else 822 { 823 // No unit specified, use the default unit 824 unit = at.getDefaultUnit(); 825 } 826 sValue = valueAndUnit[0]; 827 } 828 } 829 if (unit != null) 830 { 831 annotationValue = Type.DOUBLE.parseString(sValue, numberFormat, false); 832 } 833 else 834 { 835 annotationValue = at.getValueType().parseString(sValue, numberFormat, false); 836 } 797 837 if (annotationValue != null) 798 838 { 799 at.validateAnnotationValue(annotationValue );839 at.validateAnnotationValue(annotationValue, unit); 800 840 } 801 841 for (NewAnnotations item : items) 802 842 { 803 843 // Add annotation value to the cache 804 item.addValue(at, annotationValue );844 item.addValue(at, annotationValue, unit); 805 845 } 806 846 } … … 1177 1217 } 1178 1218 1219 private static class AnnotationValue 1220 { 1221 final Object value; 1222 final Unit unit; 1223 AnnotationValue(Object value, Unit unit) 1224 { 1225 this.value = value; 1226 this.unit = unit; 1227 } 1228 } 1229 1179 1230 /** 1180 1231 Internal cache for storing annotation values from the file … … 1185 1236 { 1186 1237 private final Annotatable item; 1187 private final Map<AnnotationType, List< Object>> values;1238 private final Map<AnnotationType, List<AnnotationValue>> values; 1188 1239 private int numAnnotations; 1189 1240 private int numSet; … … 1198 1249 { 1199 1250 this.item = item; 1200 this.values = new HashMap<AnnotationType, List< Object>>();1251 this.values = new HashMap<AnnotationType, List<AnnotationValue>>(); 1201 1252 this.numAnnotations = 0; 1202 1253 } … … 1206 1257 error before calling this method. 1207 1258 */ 1208 void addValue(AnnotationType at, Object value )1209 { 1210 List< Object> listOfValues = values.get(at);1259 void addValue(AnnotationType at, Object value, Unit unit) 1260 { 1261 List<AnnotationValue> listOfValues = values.get(at); 1211 1262 if (listOfValues == null) 1212 1263 { 1213 listOfValues = new LinkedList< Object>();1264 listOfValues = new LinkedList<AnnotationValue>(); 1214 1265 values.put(at, listOfValues); 1215 1266 } 1216 1267 if (value != null) 1217 1268 { 1218 listOfValues.add( value);1269 listOfValues.add(new AnnotationValue(value, unit)); 1219 1270 numAnnotations++; 1220 1271 } … … 1244 1295 int numAnnotations = 0; 1245 1296 AnnotationSet as = item.getAnnotationSet(); 1246 for (Map.Entry<AnnotationType, List< Object>> entry : values.entrySet())1297 for (Map.Entry<AnnotationType, List<AnnotationValue>> entry : values.entrySet()) 1247 1298 { 1248 1299 AnnotationType at = entry.getKey(); 1249 List< Object> newValues = entry.getValue();1300 List<AnnotationValue> newValues = entry.getValue(); 1250 1301 int size = newValues.size(); 1251 1302 int multiplicity = at.getMultiplicity(); 1252 1303 boolean hasAnnotation = as.hasAnnotation(at); 1253 1304 boolean merge = addToUnlimited && hasAnnotation && multiplicity == 0; 1254 boolean tooManyValues = multiplicity > 0 && newValues.size()> multiplicity;1305 boolean tooManyValues = multiplicity > 0 && size > multiplicity; 1255 1306 if (size == 0) 1256 1307 { … … 1268 1319 { 1269 1320 Annotation a = as.getAnnotation(at); 1270 if (merge) newValues.addAll(0, a.getValues()); 1271 a.setValues(newValues); 1321 List<Object> theValues = new ArrayList<Object>(newValues.size()); 1322 // Make sure all annotation values are converted to the same unit 1323 final Unit unit = merge ? a.getUnit() : newValues.get(0).unit; 1324 if (merge) 1325 { 1326 theValues.addAll(a.getValues(unit)); 1327 } 1328 for (AnnotationValue value : newValues) 1329 { 1330 Object theValue = value.value; 1331 if (unit != null && !unit.equals(value.unit)) 1332 { 1333 theValue = unit.fromOther(((Number)value.value).doubleValue(), value.unit); 1334 } 1335 theValues.add(theValue); 1336 } 1337 a.setValues(theValues, unit); 1272 1338 numSet += size; 1273 1339 if (hasAnnotation && !merge) numReplaced += size; -
trunk/src/test/TestAnnotationFlatFileImporter.java
r4544 r4822 33 33 import net.sf.basedb.core.PluginParameter; 34 34 import net.sf.basedb.core.PluginResponse; 35 import net.sf.basedb.core.Quantity; 35 36 import net.sf.basedb.core.RequestInformation; 37 import net.sf.basedb.core.SystemItems; 36 38 import net.sf.basedb.core.Type; 37 39 import net.sf.basedb.core.plugin.GuiContext; … … 56 58 // Create annotation types, samples and upload file 57 59 58 int timeId = TestAnnotationType.test_create("Time (hours)", Type.INT, 0, null, 25, Item.SAMPLE, 1, null, false); 60 int timeQuantityId = SystemItems.getId(Quantity.TIME); 61 int hoursId = TestUnit.test_load_by_symbol(timeQuantityId, "h"); 62 63 int timeId = TestAnnotationType.test_create("Time (hours)", Type.INT, hoursId, null, 25, Item.SAMPLE, 1, null, false); 59 64 int ageId = TestAnnotationType.test_create("Age (years)", Type.INT, 0, null, 100, Item.SAMPLE, 1, null, false); 60 65 int commentId = TestAnnotationType.test_create("Comment", Type.STRING, 0, null, 20, Item.SAMPLE, 0, null, false); … … 69 74 int sampleDup2 = TestSample.test_create(0, "Sample dup", false); 70 75 71 TestAnnotation.test_annotatate(Item.SAMPLE, sample4, timeId, 0, 12);72 76 TestAnnotation.test_annotatate(Item.SAMPLE, sample4, ageId, 0, 2); 73 77 TestAnnotation.test_annotatate(Item.SAMPLE, sample4, enumId, 0, "gamma"); … … 87 91 TestAnnotation.test_list_annotations(Item.SAMPLE, sample2, 2); 88 92 TestAnnotation.test_list_annotations(Item.SAMPLE, sample3, 2); 89 TestAnnotation.test_list_annotations(Item.SAMPLE, sample4, 1);93 TestAnnotation.test_list_annotations(Item.SAMPLE, sample4, 2); 90 94 TestAnnotation.test_list_annotations(Item.SAMPLE, sampleDup1, 4); 91 95 TestAnnotation.test_list_annotations(Item.SAMPLE, sampleDup2, 4); -
trunk/src/test/data/test.annotation.import.txt
r4599 r4822 12 12 # Test: item not found 13 13 NoSample 0 0 alfa Good Very good 14 # Test: remove annotations; add value to existing 15 Sample #4 A comment from file14 # Test: remove annotations; add value to existing; value with unit (120min=2h) 15 Sample #4 120min A comment from file
Note: See TracChangeset
for help on using the changeset viewer.