source: TraumaOntologies/src/main/java/tudelft/healthpsychology/traumaontologies/answerstate/PropertiesAnswerState.java

Last change on this file was 5, checked in by Bart Vastenhouw, 5 years ago

Intermediate update

File size: 5.5 KB
Line 
1package tudelft.healthpsychology.traumaontologies.answerstate;
2
3import java.util.Collection;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.LinkedList;
8import java.util.List;
9import java.util.Map;
10import java.util.Set;
11
12import com.fasterxml.jackson.annotation.JsonCreator;
13import com.fasterxml.jackson.annotation.JsonProperty;
14import com.fasterxml.jackson.databind.ObjectMapper;
15import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
16import com.fasterxml.jackson.databind.annotation.JsonSerialize;
17import com.fasterxml.jackson.databind.util.StdConverter;
18
19import tudelft.healthpsychology.traumaontologies.questiontypes.TypedQuestion;
20import tudelft.utilities.tree.Tree;
21
22/**
23 * Handles the process in filling in the properties of an {@link OntologyNode}.
24 * The most accurate available {@link OntologyNode} was determined already. The
25 * process here is to get answers to all the questions relevant for such a node.
26 * Properties are picked up from the comment fields behind the given
27 * OntologyNode and its parents. <br>
28 * immutable.
29 *
30 */
31public class PropertiesAnswerState implements AnswerState {
32
33 private final String nodelabel;
34
35 @JsonSerialize(converter = PropMapSerializer.class)
36 private final Map<Property, String> answers;
37
38 /**
39 *
40 * @param object the ontologynode class for which all properties need to be
41 * collected and answered.
42 * @param answers the already collected answers to the properties
43 */
44 @JsonCreator
45 public PropertiesAnswerState(@JsonProperty("nodelabel") String objectlabel,
46 @JsonProperty("answers") @JsonDeserialize(converter = PropMapDeserializer.class) Map<Property, String> answers) {
47 this.nodelabel = objectlabel;
48 this.answers = answers;
49 }
50
51 /**
52 * Convenience constructor for initial state
53 *
54 * @param nodelabel the label of initial node
55 */
56 @SuppressWarnings("unchecked")
57 public PropertiesAnswerState(String nodelabel) {
58 this(nodelabel, Collections.EMPTY_MAP);
59 }
60
61 @Override
62 public PropertiesAnswerState with(String answer,
63 Tree<String, Collection<Property>, OntologyNode> tree) {
64 Property property = getProperty(tree);
65 if (property == null)
66 return this;
67 if (!property.getQuestionType().fits(answer)) {
68 throw new IllegalArgumentException("The answer string must fit an "
69 + property.getQuestionType());
70 }
71 Map<Property, String> newanswers = new HashMap<Property, String>(
72 answers);
73 newanswers.put(property, answer);
74 return new PropertiesAnswerState(nodelabel, newanswers);
75 }
76
77 /**
78 *
79 * @return the main node label for this object. Mainly for testing
80 */
81 public String getNode() {
82 return nodelabel;
83 }
84
85 @Override
86 public TypedQuestion getOptions(
87 Tree<String, Collection<Property>, OntologyNode> tree) {
88 Property prop = getProperty(tree);
89 if (prop == null)
90 return null;
91 return prop.getQuestionType();
92 }
93
94 /**
95 *
96 * @return the answers given so far.
97 */
98 public Map<Property, String> getAnswers() {
99 return answers;
100 }
101
102 /**
103 *
104 * @return the property to be answered, or null if no such property (all
105 * have been answered)
106 */
107 private Property getProperty(
108 Tree<String, Collection<Property>, OntologyNode> tree) {
109 Set<Property> remaining = new HashSet<>(
110 tree.get(nodelabel).getAttribute());
111 remaining.removeAll(answers.keySet());
112 if (remaining.isEmpty()) {
113 return null;
114 }
115 return remaining.iterator().next();
116 }
117
118 @Override
119 public int hashCode() {
120 final int prime = 31;
121 int result = 1;
122 result = prime * result + ((answers == null) ? 0 : answers.hashCode());
123 result = prime * result
124 + ((nodelabel == null) ? 0 : nodelabel.hashCode());
125 return result;
126 }
127
128 @Override
129 public boolean equals(Object obj) {
130 if (this == obj)
131 return true;
132 if (obj == null)
133 return false;
134 if (getClass() != obj.getClass())
135 return false;
136 PropertiesAnswerState other = (PropertiesAnswerState) obj;
137 if (answers == null) {
138 if (other.answers != null)
139 return false;
140 } else if (!answers.equals(other.answers))
141 return false;
142 if (nodelabel == null) {
143 if (other.nodelabel != null)
144 return false;
145 } else if (!nodelabel.equals(other.nodelabel))
146 return false;
147 return true;
148 }
149
150}
151
152/****** serialization of key-value pair of Map<Property,String> **********/
153
154class PropString {
155 @JsonProperty
156 private final Property prop;
157 @JsonProperty
158 private final String answer;
159
160 @JsonCreator
161 public PropString(@JsonProperty("prop") Property prop,
162 @JsonProperty("answer") String answer) {
163 this.prop = prop;
164 this.answer = answer;
165 }
166
167 public Property getProp() {
168 return prop;
169 }
170
171 public String getAnswer() {
172 return answer;
173 }
174}
175
176/**
177 * Custom serializer to map the Map into a List
178 *
179 */
180class PropMapSerializer
181 extends StdConverter<Map<Property, String>, List<PropString>> {
182 private final ObjectMapper mapper = new ObjectMapper();
183
184 @Override
185 public List<PropString> convert(Map<Property, String> propstringmap) {
186 List<PropString> list = new LinkedList<PropString>();
187 for (Map.Entry<Property, String> pair : propstringmap.entrySet()) {
188 list.add(new PropString(pair.getKey(), pair.getValue()));
189 }
190 return list;
191 }
192
193}
194
195/**
196 * Custom deserializer to map the List back to a Map
197 *
198 */
199class PropMapDeserializer
200 extends StdConverter<List<PropString>, Map<Property, String>> {
201 private final ObjectMapper mapper = new ObjectMapper();
202
203 @Override
204 public Map<Property, String> convert(List<PropString> valuelist) {
205 Map<Property, String> propsmap = new HashMap<>();
206 for (PropString prop : valuelist) {
207 propsmap.put(prop.getProp(), prop.getAnswer());
208 }
209 return propsmap;
210 }
211
212}
Note: See TracBrowser for help on using the repository browser.