blob: d9c15102a9ca3443f239c074510991b6c99d38f7 [file] [log] [blame]
Thomas Vachuska3553b302015-03-07 14:49:43 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.ui;
17
Simon Hunt4c7edd32015-03-11 10:42:53 -070018import com.fasterxml.jackson.databind.ObjectMapper;
Thomas Vachuska3553b302015-03-07 14:49:43 -080019import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.onlab.osgi.ServiceDirectory;
21
22import java.util.Set;
23
24import static com.google.common.base.Preconditions.checkArgument;
25import static com.google.common.base.Preconditions.checkNotNull;
26
27/**
28 * Abstraction of an entity capable of processing a JSON message from the user
29 * interface client.
30 * <p>
31 * The message is a JSON object with the following structure:
Thomas Vachuskae586b792015-03-26 13:59:38 -070032 * </p>
Thomas Vachuska3553b302015-03-07 14:49:43 -080033 * <pre>
34 * {
35 * "type": "<em>event-type</em>",
36 * "sid": "<em>sequence-number</em>",
37 * "payload": {
38 * <em>arbitrary JSON object structure</em>
39 * }
40 * }
41 * </pre>
42 */
43public abstract class UiMessageHandler {
44
45 private final Set<String> messageTypes;
46 private UiConnection connection;
47 private ServiceDirectory directory;
48
Thomas Vachuskae586b792015-03-26 13:59:38 -070049 /**
50 * Mapper for creating ObjectNodes and ArrayNodes etc.
51 */
Simon Hunt4c7edd32015-03-11 10:42:53 -070052 protected final ObjectMapper mapper = new ObjectMapper();
53
Thomas Vachuska3553b302015-03-07 14:49:43 -080054 /**
55 * Creates a new message handler for the specified set of message types.
56 *
57 * @param messageTypes set of message types
58 */
59 protected UiMessageHandler(Set<String> messageTypes) {
60 this.messageTypes = checkNotNull(messageTypes, "Message types cannot be null");
61 checkArgument(!messageTypes.isEmpty(), "Message types cannot be empty");
62 }
63
64 /**
65 * Returns the set of message types which this handler is capable of
66 * processing.
67 *
68 * @return set of message types
69 */
70 public Set<String> messageTypes() {
71 return messageTypes;
72 }
73
74 /**
75 * Processes a JSON message from the user interface client.
76 *
77 * @param message JSON message
78 */
79 public abstract void process(ObjectNode message);
80
81 /**
82 * Initializes the handler with the user interface connection and
83 * service directory context.
84 *
85 * @param connection user interface connection
86 * @param directory service directory
87 */
88 public void init(UiConnection connection, ServiceDirectory directory) {
89 this.connection = connection;
90 this.directory = directory;
91 }
92
93 /**
94 * Destroys the message handler context.
95 */
96 public void destroy() {
97 this.connection = null;
98 this.directory = null;
99 }
100
101 /**
102 * Returns the user interface connection with which this handler was primed.
103 *
104 * @return user interface connection
105 */
106 public UiConnection connection() {
107 return connection;
108 }
109
110 /**
111 * Returns the user interface connection with which this handler was primed.
112 *
113 * @return user interface connection
114 */
115 public ServiceDirectory directory() {
116 return directory;
117 }
118
119 /**
120 * Returns implementation of the specified service class.
121 *
122 * @param serviceClass service class
123 * @param <T> type of service
124 * @return implementation class
125 * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
126 */
127 protected <T> T get(Class<T> serviceClass) {
128 return directory.get(serviceClass);
129 }
130
Simon Hunt4c7edd32015-03-11 10:42:53 -0700131 /**
132 * Wraps a message payload into an event structure for the given event
133 * type and sequence ID. Generally the
134 *
Thomas Vachuskae586b792015-03-26 13:59:38 -0700135 * @param type event type
136 * @param sid sequence ID
Simon Hunt4c7edd32015-03-11 10:42:53 -0700137 * @param payload event payload
138 * @return the object node representation
139 */
140 protected ObjectNode envelope(String type, long sid, ObjectNode payload) {
141 ObjectNode event = mapper.createObjectNode();
142 event.put("event", type);
143 if (sid > 0) {
144 event.put("sid", sid);
145 }
146 event.set("payload", payload);
147 return event;
148 }
149
Thomas Vachuskae586b792015-03-26 13:59:38 -0700150 /**
151 * Retrieves the payload from the specified event.
152 *
153 * @param event message event
154 * @return extracted payload object
155 */
156 protected ObjectNode payload(ObjectNode event) {
157 return (ObjectNode) event.path("payload");
158 }
159
160 /**
161 * Returns the specified node property as a number.
162 *
163 * @param node message event
164 * @param name property name
165 * @return property as number
166 */
167 protected long number(ObjectNode node, String name) {
168 return node.path(name).asLong();
169 }
170
171 /**
172 * Returns the specified node property as a string.
173 *
174 * @param node message event
175 * @param name property name
176 * @return property as a string
177 */
178 protected String string(ObjectNode node, String name) {
179 return node.path(name).asText();
180 }
181
182 /**
183 * Returns the specified node property as a string with a default fallback.
184 *
185 * @param node message event
186 * @param name property name
187 * @param defaultValue fallback value if property is absent
188 * @return property as a string
189 */
190 protected String string(ObjectNode node, String name, String defaultValue) {
191 return node.path(name).asText(defaultValue);
192 }
193
Thomas Vachuska3553b302015-03-07 14:49:43 -0800194}