# invariants of datatypes.quantity.DvOrdered **Category:** [Reference Implementation: Java (archive)](https://discourse.openehr.org/c/reference-implementation-java-archive/154) **Created:** 2007-11-15 21:19 UTC **Views:** 2 **Replies:** 2 **URL:** https://discourse.openehr.org/t/invariants-of-datatypes-quantity-dvordered/15999 --- ## Post #1 by @system Hi Sergio, Thanks for the report, please find my comments below. > Hi, > > I have the following observations regarding class DvOrdered: > > 1) Method isNormal() checks only if normalRange contains current DvOrdered, but omits the situation where normalStatus is present. > > One possibility is to change the method implementation to: > > public boolean isNormal() { > > return ((normalRange == null) ? false : getNormalRange().has(this)) || > > ((normalStatus == null) ? false : normalStatus.getCodeString().equals("N")); > > } Yes, the current isNormal() implementation isn't complete according to the specification. The pre-condition for this method is (normal_range != null || normal_status !=null). So I think the method shouldn't just return false when both are null. Maybe should throw some kind of exception to indicate the pre-condition is not met. > 2) Method isSimple() checks only if otherReferenceRanges is null. It should also check if normalRange is null. Yes, it will be fixed. > 3) The invariants **Normal_status_validity** and **Normal_range_and_status**_**consistency** are not warranted. > > You could add a method like validateNormalStatus (see below) and call it in the constructor. To do this you should get a reference to a terminologyService. If you do this in the constructor, you'll have to propagate it all the way down the hierarchy. > > private void validateNormalStatus(CodePhrase status) { > > if (status != null) { > > if (terminologyService == null) { > > throw new IllegalArgumentException("null terminologyService"); > > } > > if (!terminologyService.codeSetForID( > > "normal statuses").hasCode(status)) { > > throw new IllegalArgumentException( > > "unknown code for normalStatus: " + status.getCodeString()); > > } > > } > > } > > For normal range and status consistency, one possibility is to have a method like that below that should be called in the constructors of the concrete classes. > > private void checkNormalRangeAndStatusConsistency(DvInterval normalRange) { > > if ((normalRange != null) && (normalStatus() != null)) { > > if (normalStatus.getCodeString().equals("N") ^ (normalRange.has(this)) { > > throw new IllegalStateException("normal status not consistent with normal range"); > > } > > } > > } These look alright. I will probably add a testcase for this. > These checks should also be done in the corresponding setters, unless you make the attributes final. That's right. Cheers, Rong --- ## Post #2 by @system Hi Rong, I am sending this e-mail direct to you because I am away from work and I could not post to the list using the e-mail I subscribed to it. I agree with your remarks regarding method isNormal(). In relation to the invariant **Normal_range_and_status**_**consistency**, I added the following test to class DvQuantityTest: public void testNormalStatusAndNormalRangeConsistency() { CodePhrase normalStatusN = new CodePhrase(new TerminologyID("mock"), "N"); CodePhrase normalStatusOther = new CodePhrase(new TerminologyID("mock"), "A"); DvQuantity lowerLimit1 = new DvQuantity("mg", 10, 2, ms); DvQuantity lowerLimit2 = new DvQuantity("mg", 30, 2, ms); DvQuantity upperLimit = new DvQuantity("mg", 50, 2, ms); DvInterval normalRangeHas = new DvInterval(lowerLimit1, upperLimit); DvInterval normalRangeHasNot = new DvInterval(lowerLimit2, upperLimit); DvQuantity testQuantity1 = new DvQuantity(null, normalRangeHas, normalStatusN, ts, null, 0.0, false, "mg", 15, 2, ms); DvQuantity testQuantity2 = new DvQuantity(null, normalRangeHasNot, normalStatusOther, ts, null, 0.0, false, "mg", 15, 2, ms); try { DvQuantity testQuantity3 = new DvQuantity(null, normalRangeHas, normalStatusOther, ts, null, 0.0, false, "mg", 15, 2, ms); fail("exception should be thrown"); } catch (Exception ex) { assertTrue(ex instanceof IllegalStateException); } try { DvQuantity testQuantity4 = new DvQuantity(null, normalRangeHasNot, normalStatusN, ts, null, 0.0, false, "mg", 15, 2, ms); fail("exception should be thrown"); } catch (Exception ex) { assertTrue(ex instanceof IllegalStateException); } } Besides, I changed the method below in class TestTerminologyService: public CodeSetAccess codeSetForId(String id) { return new TestCodeSetAccess(); } Regards, Sergio Rong Chen escreveu: --- ## Post #3 by @system Hi Sergio, Thanks for the test case. It's very much appreciated! I am splitting it into several several finer tests and including them in DvOrderedTest. While I am testing the a new component that provides minimum openEHR terminology support, I found anomalies to do with code phrase validation in several places. I will commit the changes when they are fixed. Cheers, Rong --- **Canonical:** https://discourse.openehr.org/t/invariants-of-datatypes-quantity-dvordered/15999 **Original content:** https://discourse.openehr.org/t/invariants-of-datatypes-quantity-dvordered/15999