blob: 915bcafa73e93465acec6749e0908e1896a28922 [file] [log] [blame]
Simon Huntd2747a02015-04-30 22:41:16 -07001/*
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
18import com.fasterxml.jackson.databind.ObjectMapper;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.onlab.osgi.ServiceDirectory;
21
22import java.util.Collection;
23import java.util.Collections;
24import java.util.HashMap;
25import java.util.Map;
26import java.util.Set;
27
28import static com.google.common.base.Preconditions.checkArgument;
29import static com.google.common.base.Preconditions.checkNotNull;
30
31/**
32 * Abstraction of an entity capable of processing a JSON message from the user
33 * interface client.
34 * <p>
35 * The message is a JSON object with the following structure:
36 * </p>
37 * <pre>
38 * {
39 * "type": "<em>event-type</em>",
40 * "sid": "<em>sequence-number</em>",
41 * "payload": {
42 * <em>arbitrary JSON object structure</em>
43 * }
44 * }
45 * </pre>
46 */
47public abstract class UiMessageHandlerTwo {
48
49 private final Map<String, RequestHandler> handlerMap = new HashMap<>();
50
51 private UiConnection connection;
52 private ServiceDirectory directory;
53
54 /**
55 * Mapper for creating ObjectNodes and ArrayNodes etc.
56 */
57 protected final ObjectMapper mapper = new ObjectMapper();
58
59 /**
60 * Binds the handlers returned from {@link #getHandlers()} to this
61 * instance.
62 */
63 void bindHandlers() {
64 Collection<RequestHandler> handlers = getHandlers();
65 checkNotNull(handlers, "Handlers cannot be null");
66 checkArgument(!handlers.isEmpty(), "Handlers cannot be empty");
67
68 for (RequestHandler h : handlers) {
69 h.setParent(this);
70 handlerMap.put(h.eventType(), h);
71 }
72 }
73
74 /**
75 * Subclasses must return the collection of handlers for the
76 * message types they handle.
77 *
78 * @return the message handler instances
79 */
80 protected abstract Collection<RequestHandler> getHandlers();
81
82 /**
83 * Returns the set of message types which this handler is capable of
84 * processing.
85 *
86 * @return set of message types
87 */
88 public Set<String> messageTypes() {
89 return Collections.unmodifiableSet(handlerMap.keySet());
90 }
91
92 /**
93 * Processes a JSON message from the user interface client.
94 *
95 * @param message JSON message
96 */
97 public void process(ObjectNode message) {
98 String type = JsonUtils.eventType(message);
99 long sid = JsonUtils.sid(message);
100 ObjectNode payload = JsonUtils.payload(message);
101 exec(type, sid, payload);
102 }
103
104 /**
105 * Finds the appropriate handler and executes the process method.
106 *
107 * @param eventType event type
108 * @param sid sequence identifier
109 * @param payload message payload
110 */
111 void exec(String eventType, long sid, ObjectNode payload) {
112 RequestHandler handler = handlerMap.get(eventType);
113 if (handler != null) {
114 handler.process(sid, payload);
115 }
116 }
117
118 /**
119 * Initializes the handler with the user interface connection and
120 * service directory context.
121 *
122 * @param connection user interface connection
123 * @param directory service directory
124 */
125 public void init(UiConnection connection, ServiceDirectory directory) {
126 this.connection = connection;
127 this.directory = directory;
128 bindHandlers();
129 }
130
131 /**
132 * Destroys the message handler context.
133 */
134 public void destroy() {
135 this.connection = null;
136 this.directory = null;
137 }
138
139 /**
140 * Returns the user interface connection with which this handler was primed.
141 *
142 * @return user interface connection
143 */
144 public UiConnection connection() {
145 return connection;
146 }
147
148 /**
149 * Returns the user interface connection with which this handler was primed.
150 *
151 * @return user interface connection
152 */
153 public ServiceDirectory directory() {
154 return directory;
155 }
156
157 /**
158 * Returns implementation of the specified service class.
159 *
160 * @param serviceClass service class
161 * @param <T> type of service
162 * @return implementation class
163 * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
164 */
165 protected <T> T get(Class<T> serviceClass) {
166 return directory.get(serviceClass);
167 }
168
169}