blob: b20e28f629d4a8a41c1b3f2e8ccbf41f67cd0337 [file] [log] [blame]
Nils Diewaldc471b182014-11-19 22:51:15 +00001package de.ids_mannheim.korap.response;
2
3import de.ids_mannheim.korap.util.QueryException;
Akron74748c62016-06-29 00:22:43 +02004import static de.ids_mannheim.korap.util.KrillString.quote;
Nils Diewaldc471b182014-11-19 22:51:15 +00005import de.ids_mannheim.korap.response.Message;
6
Akron7d45e6b2015-06-26 17:23:42 +02007import com.fasterxml.jackson.annotation.JsonInclude.Include;
Nils Diewaldc471b182014-11-19 22:51:15 +00008import com.fasterxml.jackson.annotation.*;
9import com.fasterxml.jackson.databind.ObjectMapper;
10import com.fasterxml.jackson.databind.JsonNode;
11import com.fasterxml.jackson.databind.node.*;
12
Nils Diewald2f2b0672014-11-25 20:26:22 +000013import java.lang.*;
14import java.util.*;
Nils Diewaldc471b182014-11-19 22:51:15 +000015
16/**
Nils Diewald2f2b0672014-11-25 20:26:22 +000017 * A list of messages for Notifications.
Nils Diewaldbb33da22015-03-04 16:24:25 +000018 *
Nils Diewald2f2b0672014-11-25 20:26:22 +000019 * <p>
20 * <blockquote><pre>
Nils Diewaldbb33da22015-03-04 16:24:25 +000021 * Messages m = new Messages();
22 * m.add(614, "This is a new message");
Nils Diewald2f2b0672014-11-25 20:26:22 +000023 * </pre></blockquote>
Nils Diewaldbb33da22015-03-04 16:24:25 +000024 *
Nils Diewaldc99ed5b2015-01-21 22:08:53 +000025 * @author diewald
26 * @see Notifications
27 * @see Message
Nils Diewaldc471b182014-11-19 22:51:15 +000028 */
Akron7d45e6b2015-06-26 17:23:42 +020029@JsonInclude(Include.NON_NULL)
30@JsonIgnoreProperties(ignoreUnknown = true)
Nils Diewald2f2b0672014-11-25 20:26:22 +000031public class Messages implements Cloneable, Iterable<Message> {
Nils Diewaldc471b182014-11-19 22:51:15 +000032
Nils Diewald2f2b0672014-11-25 20:26:22 +000033 // Create object mapper for JSON generation
Nils Diewaldc471b182014-11-19 22:51:15 +000034 ObjectMapper mapper = new ObjectMapper();
Nils Diewald2f2b0672014-11-25 20:26:22 +000035
36 // List of messages
Nils Diewaldc471b182014-11-19 22:51:15 +000037 private ArrayList<Message> messages;
38
Nils Diewald2f2b0672014-11-25 20:26:22 +000039 // Private class for iterator implementation
40 private class MessageIterator implements Iterator<Message> {
Nils Diewald44d5fa12015-01-15 21:31:52 +000041 int index;
Nils Diewald2f2b0672014-11-25 20:26:22 +000042
Nils Diewaldbb33da22015-03-04 16:24:25 +000043
Nils Diewald44d5fa12015-01-15 21:31:52 +000044 // Constructor
Nils Diewald2f2b0672014-11-25 20:26:22 +000045 public MessageIterator () {
46 this.index = 0;
47 };
48
Nils Diewaldbb33da22015-03-04 16:24:25 +000049
Nils Diewald2f2b0672014-11-25 20:26:22 +000050 @Override
Nils Diewald44d5fa12015-01-15 21:31:52 +000051 public boolean hasNext () {
Nils Diewald2f2b0672014-11-25 20:26:22 +000052 return this.index < messages.size();
53 };
54
Nils Diewaldbb33da22015-03-04 16:24:25 +000055
Nils Diewald2f2b0672014-11-25 20:26:22 +000056 @Override
Nils Diewald44d5fa12015-01-15 21:31:52 +000057 public Message next () {
Nils Diewald2f2b0672014-11-25 20:26:22 +000058 return messages.get(this.index++);
59 };
60
Nils Diewaldbb33da22015-03-04 16:24:25 +000061
Nils Diewald2f2b0672014-11-25 20:26:22 +000062 @Override
63 public void remove () {
Nils Diewald44d5fa12015-01-15 21:31:52 +000064 messages.remove(this.index);
Nils Diewald2f2b0672014-11-25 20:26:22 +000065 };
66 };
67
Nils Diewald44d5fa12015-01-15 21:31:52 +000068
Nils Diewald2f2b0672014-11-25 20:26:22 +000069 /**
70 * Construct a new Messages object.
71 */
Nils Diewaldc471b182014-11-19 22:51:15 +000072 public Messages () {
Nils Diewald44d5fa12015-01-15 21:31:52 +000073 this.messages = new ArrayList<Message>(3);
Nils Diewaldc471b182014-11-19 22:51:15 +000074 };
75
Nils Diewald44d5fa12015-01-15 21:31:52 +000076
Nils Diewaldc471b182014-11-19 22:51:15 +000077 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +000078 * Get the iterator object.
Nils Diewaldbb33da22015-03-04 16:24:25 +000079 *
Nils Diewald2f2b0672014-11-25 20:26:22 +000080 * @return Iterator for Message object.
81 */
Nils Diewaldbb33da22015-03-04 16:24:25 +000082 public Iterator<Message> iterator () {
Nils Diewald2f2b0672014-11-25 20:26:22 +000083 return new MessageIterator();
84 };
85
Nils Diewald44d5fa12015-01-15 21:31:52 +000086
Nils Diewald2f2b0672014-11-25 20:26:22 +000087 /**
88 * Append a new message.
Nils Diewaldbb33da22015-03-04 16:24:25 +000089 *
90 * @param code
91 * Integer code representation of the warning
92 * @param msg
93 * String representation of the warning
94 * @param terms
95 * Optional strings of additional information
Nils Diewald2f2b0672014-11-25 20:26:22 +000096 * @return New Message object
Nils Diewaldc471b182014-11-19 22:51:15 +000097 */
Nils Diewaldbb33da22015-03-04 16:24:25 +000098 public Message add (int code, String message, String ... terms) {
Nils Diewald44d5fa12015-01-15 21:31:52 +000099 Message newMsg = new Message(code, message);
100 messages.add(newMsg);
101 if (terms != null)
102 for (String t : terms)
103 newMsg.addParameter(t);
104 return newMsg;
Nils Diewaldc471b182014-11-19 22:51:15 +0000105 };
106
Nils Diewald44d5fa12015-01-15 21:31:52 +0000107
Nils Diewaldc471b182014-11-19 22:51:15 +0000108 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000109 * Append an existing message.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000110 *
111 * @param msg
112 * Message object to be added. Message will be cloned.
Nils Diewald2f2b0672014-11-25 20:26:22 +0000113 * @return Cloned Message object
Nils Diewaldc471b182014-11-19 22:51:15 +0000114 */
115 public Message add (Message msg) {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000116 try {
117 Message msgClone = (Message) msg.clone();
118 messages.add(msgClone);
119 return msgClone;
120 }
Nils Diewaldbb33da22015-03-04 16:24:25 +0000121 catch (CloneNotSupportedException e) {};
Nils Diewald44d5fa12015-01-15 21:31:52 +0000122 return (Message) null;
Nils Diewaldc471b182014-11-19 22:51:15 +0000123 };
124
Nils Diewaldbb33da22015-03-04 16:24:25 +0000125
Nils Diewaldc471b182014-11-19 22:51:15 +0000126 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000127 * Append an existing message comming from a JsonNode.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000128 *
129 * @param node
130 * <code>JsonNode</code> representing a message
Nils Diewald2f2b0672014-11-25 20:26:22 +0000131 * @return New Message object
Nils Diewaldbb33da22015-03-04 16:24:25 +0000132 * @throws QueryException
133 * if notification is not well formed (Error 750)
Nils Diewaldc471b182014-11-19 22:51:15 +0000134 */
135 public Message add (JsonNode msg) throws QueryException {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000136 if (!msg.isArray() || !msg.has(0))
Nils Diewaldbb33da22015-03-04 16:24:25 +0000137 throw new QueryException(750,
138 "Passed notifications are not well formed");
Nils Diewaldc471b182014-11-19 22:51:15 +0000139
Nils Diewald44d5fa12015-01-15 21:31:52 +0000140 // Valid message
141 Message newMsg = new Message();
142 short i = 1;
143 if (msg.get(0).isNumber()) {
144 newMsg.setCode(msg.get(0).asInt());
145 if (!msg.has(1))
Nils Diewaldbb33da22015-03-04 16:24:25 +0000146 throw new QueryException(750,
147 "Passed notifications are not well formed");
Nils Diewald44d5fa12015-01-15 21:31:52 +0000148 newMsg.setMessage(msg.get(1).asText());
149 i++;
150 }
151 else {
152 newMsg.setMessage(msg.get(0).asText());
153 };
Nils Diewaldc471b182014-11-19 22:51:15 +0000154
Nils Diewald44d5fa12015-01-15 21:31:52 +0000155 // Add parameters
156 while (msg.has(i))
157 newMsg.addParameter(msg.get(i++).asText());
Nils Diewaldbb33da22015-03-04 16:24:25 +0000158
Nils Diewald44d5fa12015-01-15 21:31:52 +0000159 // Add messages to list
160 this.add(newMsg);
161 return newMsg;
Nils Diewaldc471b182014-11-19 22:51:15 +0000162 };
163
164
165 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000166 * Append existing messages.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000167 *
168 * @param msgs
169 * Messages object to be added. Messages will be
170 * cloned.
Nils Diewald2f2b0672014-11-25 20:26:22 +0000171 * @return Messages object for chaining.
Nils Diewaldc471b182014-11-19 22:51:15 +0000172 */
Nils Diewald2f2b0672014-11-25 20:26:22 +0000173 public Messages add (Messages msgs) {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000174 try {
175 for (Message msg : msgs.getMessages())
176 this.add((Message) msg.clone());
177 }
Nils Diewaldbb33da22015-03-04 16:24:25 +0000178 catch (CloneNotSupportedException e) {};
Nils Diewald44d5fa12015-01-15 21:31:52 +0000179 return this;
Nils Diewaldc471b182014-11-19 22:51:15 +0000180 };
181
Nils Diewald44d5fa12015-01-15 21:31:52 +0000182
Nils Diewaldc471b182014-11-19 22:51:15 +0000183 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000184 * Clear all messages.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000185 *
Nils Diewald2f2b0672014-11-25 20:26:22 +0000186 * @return Messages object for chaining
Nils Diewaldc471b182014-11-19 22:51:15 +0000187 */
Nils Diewald2f2b0672014-11-25 20:26:22 +0000188 public Messages clear () {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000189 this.messages.clear();
190 return this;
Nils Diewaldc471b182014-11-19 22:51:15 +0000191 };
192
Nils Diewald44d5fa12015-01-15 21:31:52 +0000193
Nils Diewald2f2b0672014-11-25 20:26:22 +0000194 /**
195 * Get the number of the messages.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000196 *
197 * @param Integer
198 * representing the number of messages in the list.
Nils Diewald2f2b0672014-11-25 20:26:22 +0000199 */
Nils Diewaldc471b182014-11-19 22:51:15 +0000200 public int size () {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000201 return this.messages.size();
Nils Diewaldc471b182014-11-19 22:51:15 +0000202 };
203
Nils Diewald2f2b0672014-11-25 20:26:22 +0000204
205 /**
206 * Return a specific message based on an index.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000207 *
208 * @param index
209 * The index of the message in the list of messages.
210 * @return The message in case it exists, otherwise
211 * <code>null</code>
Nils Diewald2f2b0672014-11-25 20:26:22 +0000212 */
Nils Diewaldc471b182014-11-19 22:51:15 +0000213 @JsonIgnore
214 public Message get (int index) {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000215 if (index >= this.size())
216 return (Message) null;
217 return this.messages.get(index);
Nils Diewaldc471b182014-11-19 22:51:15 +0000218 };
219
Nils Diewald44d5fa12015-01-15 21:31:52 +0000220
Nils Diewald2f2b0672014-11-25 20:26:22 +0000221 /**
222 * Return all messages.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000223 *
Nils Diewald2f2b0672014-11-25 20:26:22 +0000224 * @return List of all Message objects
225 */
Nils Diewaldc471b182014-11-19 22:51:15 +0000226 @JsonIgnore
227 public List<Message> getMessages () {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000228 return this.messages;
Nils Diewaldc471b182014-11-19 22:51:15 +0000229 };
230
Nils Diewald2f2b0672014-11-25 20:26:22 +0000231
232 /**
233 * Create a clone of the Messages.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000234 *
235 * @return The cloned messages object
236 * @throws CloneNotSupportedException
237 * if messages can't be cloned
Nils Diewald2f2b0672014-11-25 20:26:22 +0000238 */
239 public Object clone () throws CloneNotSupportedException {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000240 Messages clone = new Messages();
241 for (Message m : this.messages) {
242 clone.add((Message) m.clone());
243 };
Nils Diewaldc471b182014-11-19 22:51:15 +0000244
Nils Diewald44d5fa12015-01-15 21:31:52 +0000245 return clone;
Nils Diewaldc471b182014-11-19 22:51:15 +0000246 };
247
Nils Diewald44d5fa12015-01-15 21:31:52 +0000248
Nils Diewaldc471b182014-11-19 22:51:15 +0000249 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000250 * Serialize Messages as a JsonNode.
Nils Diewaldbb33da22015-03-04 16:24:25 +0000251 *
Nils Diewald2f2b0672014-11-25 20:26:22 +0000252 * @return JsonNode representation of all messages
Nils Diewaldc471b182014-11-19 22:51:15 +0000253 */
Nils Diewalde1ecd5e2014-11-27 02:17:24 +0000254 public JsonNode toJsonNode () {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000255 ArrayNode messageArray = mapper.createArrayNode();
Akron7d45e6b2015-06-26 17:23:42 +0200256
257 for (Message msg : this.messages) {
258
259 messageArray.add((JsonNode) msg.toJsonNode());
260 };
261
Nils Diewald44d5fa12015-01-15 21:31:52 +0000262 return (JsonNode) messageArray;
Nils Diewaldc471b182014-11-19 22:51:15 +0000263 };
264
Nils Diewald2f2b0672014-11-25 20:26:22 +0000265
Nils Diewaldc471b182014-11-19 22:51:15 +0000266 /**
Nils Diewald2f2b0672014-11-25 20:26:22 +0000267 * Serialize Messages as a JSON string.
268 * <p>
269 * <blockquote><pre>
270 * [
Nils Diewaldbb33da22015-03-04 16:24:25 +0000271 * [123, "You are not allowed to serialize these messages"],
272 * [124, "Your request was invalid"]
Nils Diewald2f2b0672014-11-25 20:26:22 +0000273 * ]
274 * </pre></blockquote>
Nils Diewaldbb33da22015-03-04 16:24:25 +0000275 *
Nils Diewald2f2b0672014-11-25 20:26:22 +0000276 * @return String representation of all messages
Nils Diewaldc471b182014-11-19 22:51:15 +0000277 */
Nils Diewalde1ecd5e2014-11-27 02:17:24 +0000278 public String toJsonString () {
Nils Diewald44d5fa12015-01-15 21:31:52 +0000279 String msg = "";
280 try {
281 return mapper.writeValueAsString(this.toJsonNode());
282 }
283 catch (Exception e) {
Akron74748c62016-06-29 00:22:43 +0200284 msg = ", " + quote(e.getLocalizedMessage());
Nils Diewald44d5fa12015-01-15 21:31:52 +0000285 };
Nils Diewaldc471b182014-11-19 22:51:15 +0000286
Nils Diewaldbb33da22015-03-04 16:24:25 +0000287 return "[620, " + "\"Unable to generate JSON\"" + msg + "]";
Nils Diewaldc471b182014-11-19 22:51:15 +0000288 };
289};