Next version of JABA
[jabaws.git] / datamodel / compbio / metadata / ValueConstrain.java
1 /* Copyright (c) 2009 Peter Troshin\r
2  *  \r
3  *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 1.0     \r
4  * \r
5  *  This library is free software; you can redistribute it and/or modify it under the terms of the\r
6  *  Apache License version 2 as published by the Apache Software Foundation\r
7  * \r
8  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r
9  *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache \r
10  *  License for more details.\r
11  * \r
12  *  A copy of the license is in apache_license.txt. It is also available here:\r
13  * @see: http://www.apache.org/licenses/LICENSE-2.0.txt\r
14  * \r
15  * Any republication or derived work distributed in source code form\r
16  * must include this copyright and license notice.\r
17  */\r
18 \r
19 package compbio.metadata;\r
20 \r
21 import javax.xml.bind.ValidationException;\r
22 import javax.xml.bind.annotation.XmlAccessType;\r
23 import javax.xml.bind.annotation.XmlAccessorType;\r
24 import javax.xml.bind.annotation.XmlElement;\r
25 \r
26 import compbio.util.Util;\r
27 \r
28 /**\r
29  * The type and the lower and upper boundaries for numerical value.\r
30  * \r
31  * @author pvtroshin\r
32  * \r
33  *         Date November 2009\r
34  */\r
35 @XmlAccessorType(XmlAccessType.FIELD)\r
36 public class ValueConstrain {\r
37 \r
38     public static enum Type {\r
39         Integer, Float\r
40     };\r
41 \r
42     @XmlElement(required = true)\r
43     Type type;\r
44     // These can contain different numeric types values, thus they are strings\r
45     String max;\r
46     String min;\r
47 \r
48     public Type getType() {\r
49         return type;\r
50     }\r
51 \r
52     public void setType(Type type) {\r
53         this.type = type;\r
54     }\r
55 \r
56     public Number getMax() {\r
57         if (Util.isEmpty(max)) {\r
58             return null;\r
59         }\r
60         switch (type) {\r
61         case Float:\r
62             return Double.parseDouble(max);\r
63         case Integer:\r
64             return Integer.parseInt(max);\r
65         }\r
66         // should not happened\r
67         throw new RuntimeException("Type is undefined! ");\r
68     }\r
69 \r
70     public void setMax(String max) {\r
71         this.max = max;\r
72     }\r
73 \r
74     public Number getMin() {\r
75         if (Util.isEmpty(min)) {\r
76             return null;\r
77         }\r
78         switch (type) {\r
79         case Float:\r
80             return Double.parseDouble(min);\r
81         case Integer:\r
82             return Integer.parseInt(min);\r
83         }\r
84         // should not happened\r
85         throw new RuntimeException("Type is undefined! ");\r
86     }\r
87 \r
88     public void setMin(String min) {\r
89         this.min = min;\r
90     }\r
91 \r
92     @Override\r
93     public boolean equals(Object obj) {\r
94         if (obj == null) {\r
95             return false;\r
96         }\r
97         ValueConstrain constr = null;\r
98         if (obj instanceof ValueConstrain) {\r
99             constr = (ValueConstrain) obj;\r
100         } else {\r
101             return false;\r
102         }\r
103         if (this.type != constr.type) {\r
104             return false;\r
105         }\r
106         if (this.max != null && constr.max != null) {\r
107             if (!this.max.equals(constr.max)) {\r
108                 return false;\r
109             }\r
110         } else {\r
111             return false;\r
112         }\r
113 \r
114         if (this.min != null && constr.min != null) {\r
115             if (!this.min.equals(constr.min)) {\r
116                 return false;\r
117             }\r
118         } else {\r
119             return false;\r
120         }\r
121 \r
122         return true;\r
123     }\r
124 \r
125     @Override\r
126     public String toString() {\r
127         String value = "Type: " + this.type + "\n";\r
128         if (this.min != null) {\r
129             value += "Min: " + this.min + "\n";\r
130         }\r
131         if (this.max != null) {\r
132             value += "Max: " + this.max + "\n";\r
133         }\r
134         return value;\r
135     }\r
136 \r
137     @Override\r
138     public int hashCode() {\r
139         int code = type.hashCode();\r
140         if (this.max != null) {\r
141             code *= this.max.hashCode();\r
142         }\r
143         if (this.min != null) {\r
144             code *= this.min.hashCode();\r
145         }\r
146         return code;\r
147     }\r
148 \r
149     boolean hasMinValue() {\r
150         return !Util.isEmpty(min);\r
151     }\r
152 \r
153     boolean hasMaxValue() {\r
154         return !Util.isEmpty(max);\r
155     }\r
156 \r
157     /**\r
158      * Validate that the value is within the constrain boundaries\r
159      * \r
160      * @param value\r
161      * @throws IndexOutOfBoundsException\r
162      *             when the value is outside the defined boundaries\r
163      */\r
164     void checkValue(String value) {\r
165         switch (type) {\r
166         case Float:\r
167             float val = Float.parseFloat(value);\r
168             if (getMin() != null\r
169                     && new Float(this.getMin().floatValue()).compareTo(val) == 1) {\r
170                 throw new IndexOutOfBoundsException("Value '" + value\r
171                         + "' is lower that minumim value '" + getMin() + "'");\r
172             }\r
173             if (getMax() != null\r
174                     && new Float(this.getMax().floatValue()).compareTo(val) == -1) {\r
175                 throw new IndexOutOfBoundsException("Value '" + value\r
176                         + "' is greater that maximum value '" + getMax() + "'");\r
177             }\r
178             break;\r
179         case Integer:\r
180             int ival = Integer.parseInt(value);\r
181             if (getMin() != null\r
182                     && new Integer(this.getMin().intValue()).compareTo(ival) == 1) {\r
183                 throw new IndexOutOfBoundsException("Value '" + value\r
184                         + "' is lower that minumim value '" + getMin() + "'");\r
185             }\r
186             if (getMax() != null\r
187                     && new Integer(this.getMax().intValue()).compareTo(ival) == -1) {\r
188                 throw new IndexOutOfBoundsException("Value '" + value\r
189                         + "' is greater that maximum value '" + getMax() + "'");\r
190             }\r
191             break;\r
192         }\r
193     }\r
194 \r
195     /**\r
196      * Validate the ValueConstrain object. For the ValueConstrain object the\r
197      * type and at least one boundary has to be defined\r
198      * \r
199      * @throws ValidationException\r
200      *             - if the type or no boundaries are defined\r
201      */\r
202     void validate() throws ValidationException {\r
203         if (this.type == null) {\r
204             throw new ValidationException(\r
205                     "Type is not defined for ValueConstrain: " + this);\r
206         }\r
207         if (Util.isEmpty(min) && Util.isEmpty(max)) {\r
208             throw new ValidationException(\r
209                     "Both boundaries (min and max) is undefined for ValueConstrain: "\r
210                             + this);\r
211         }\r
212     }\r
213 \r
214 }\r