blob: 1528db25d59e660426b978a7b88b4d924e977691 [file] [log] [blame]
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -08003 *
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
Thomas Vachuskac4178cc2015-12-10 11:43:32 -080018import com.google.common.collect.ImmutableList;
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -070019import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080021
22import java.io.InputStream;
Simon Hunte05cae42015-07-23 17:35:24 -070023import java.util.ArrayList;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080024import java.util.List;
25
Simon Hunte05cae42015-07-23 17:35:24 -070026import static com.google.common.base.Preconditions.checkArgument;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080027import static com.google.common.base.Preconditions.checkNotNull;
28
29/**
30 * User interface extension.
31 */
Simon Hunte05cae42015-07-23 17:35:24 -070032public final class UiExtension {
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080033
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -070034 private final Logger log = LoggerFactory.getLogger(getClass());
35
Thomas Vachuska529db0a2015-02-23 16:42:14 -080036 private static final String VIEW_PREFIX = "app/view/";
Simon Hunte05cae42015-07-23 17:35:24 -070037 private static final String EMPTY = "";
38 private static final String SLASH = "/";
39 private static final String CSS_HTML = "css.html";
40 private static final String JS_HTML = "js.html";
Thomas Vachuska529db0a2015-02-23 16:42:14 -080041
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080042 private final ClassLoader classLoader;
Simon Hunte05cae42015-07-23 17:35:24 -070043 private final String resourcePath;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080044 private final List<UiView> views;
Thomas Vachuska3553b302015-03-07 14:49:43 -080045 private final UiMessageHandlerFactory messageHandlerFactory;
Simon Hunte05cae42015-07-23 17:35:24 -070046 private final UiTopoOverlayFactory topoOverlayFactory;
Steven Burrows3a9a6442016-05-05 15:31:16 +010047 private final UiTopoMapFactory topoMapFactory;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080048
Thomas Vachuskac4178cc2015-12-10 11:43:32 -080049 private boolean isValid = true;
Simon Hunte05cae42015-07-23 17:35:24 -070050
51 // private constructor - only the builder calls this
52 private UiExtension(ClassLoader cl, String path, List<UiView> views,
53 UiMessageHandlerFactory mhFactory,
Steven Burrows3a9a6442016-05-05 15:31:16 +010054 UiTopoOverlayFactory toFactory,
55 UiTopoMapFactory tmFactory) {
Simon Hunte05cae42015-07-23 17:35:24 -070056 this.classLoader = cl;
57 this.resourcePath = path;
58 this.views = views;
59 this.messageHandlerFactory = mhFactory;
60 this.topoOverlayFactory = toFactory;
Steven Burrows3a9a6442016-05-05 15:31:16 +010061 this.topoMapFactory = tmFactory;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080062 }
63
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080064
65 /**
66 * Returns input stream containing CSS inclusion statements.
67 *
68 * @return CSS inclusion statements
69 */
70 public InputStream css() {
Simon Hunte05cae42015-07-23 17:35:24 -070071 return getStream(resourcePath + CSS_HTML);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080072 }
73
74 /**
75 * Returns input stream containing JavaScript inclusion statements.
76 *
77 * @return JavaScript inclusion statements
78 */
79 public InputStream js() {
Thomas Vachuskad894b5d2015-07-30 11:59:07 -070080 return getStream(resourcePath + JS_HTML);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080081 }
82
83 /**
84 * Returns list of user interface views contributed by this extension.
85 *
86 * @return contributed view descriptors
87 */
88 public List<UiView> views() {
Thomas Vachuskac4178cc2015-12-10 11:43:32 -080089 return isValid ? views : ImmutableList.of();
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080090 }
91
92 /**
93 * Returns input stream containing specified view-specific resource.
94 *
95 * @param viewId view identifier
96 * @param path resource path, relative to the view directory
97 * @return resource input stream
98 */
99 public InputStream resource(String viewId, String path) {
Simon Hunte05cae42015-07-23 17:35:24 -0700100 return getStream(VIEW_PREFIX + viewId + SLASH + path);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -0800101 }
102
Thomas Vachuska3553b302015-03-07 14:49:43 -0800103 /**
Simon Hunte05cae42015-07-23 17:35:24 -0700104 * Returns message handler factory, if one was defined.
Thomas Vachuska3553b302015-03-07 14:49:43 -0800105 *
Simon Hunte05cae42015-07-23 17:35:24 -0700106 * @return message handler factory
Thomas Vachuska3553b302015-03-07 14:49:43 -0800107 */
108 public UiMessageHandlerFactory messageHandlerFactory() {
109 return messageHandlerFactory;
110 }
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700111
Simon Hunte05cae42015-07-23 17:35:24 -0700112 /**
113 * Returns the topology overlay factory, if one was defined.
114 *
115 * @return topology overlay factory
116 */
117 public UiTopoOverlayFactory topoOverlayFactory() {
118 return topoOverlayFactory;
119 }
120
Steven Burrows3a9a6442016-05-05 15:31:16 +0100121 /**
122 * Returns the topology map factory, if one was defined.
123 *
124 * @return topology map factory
125 */
126 public UiTopoMapFactory topoMapFactory() {
127 return topoMapFactory;
128 }
129
Simon Hunte05cae42015-07-23 17:35:24 -0700130
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700131 // Returns the resource input stream from the specified class-loader.
132 private InputStream getStream(String path) {
133 InputStream stream = classLoader.getResourceAsStream(path);
134 if (stream == null) {
Thomas Vachuskac4178cc2015-12-10 11:43:32 -0800135 isValid = false;
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700136 log.warn("Unable to find resource {}", path);
137 }
138 return stream;
139 }
140
141
Simon Hunte05cae42015-07-23 17:35:24 -0700142 /**
143 * UI Extension Builder.
144 */
145 public static class Builder {
146 private ClassLoader classLoader;
147
148 private String resourcePath = EMPTY;
149 private List<UiView> views = new ArrayList<>();
150 private UiMessageHandlerFactory messageHandlerFactory = null;
151 private UiTopoOverlayFactory topoOverlayFactory = null;
Steven Burrows3a9a6442016-05-05 15:31:16 +0100152 private UiTopoMapFactory topoMapFactory = null;
Simon Hunte05cae42015-07-23 17:35:24 -0700153
154 /**
155 * Create a builder with the given class loader.
156 * Resource path defaults to "".
157 * Views defaults to an empty list.
158 * Both Message and TopoOverlay factories default to null.
159 *
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700160 * @param cl the class loader
161 * @param views list of views contributed by this extension
Simon Hunte05cae42015-07-23 17:35:24 -0700162 */
163 public Builder(ClassLoader cl, List<UiView> views) {
164 checkNotNull(cl, "Must provide a class loader");
165 checkArgument(views.size() > 0, "Must provide at least one view");
166 this.classLoader = cl;
167 this.views = views;
168 }
169
170 /**
171 * Set the resource path. That is, path to where the CSS and JS
172 * files are located. This value should
173 *
174 * @param path resource path
175 * @return self, for chaining
176 */
177 public Builder resourcePath(String path) {
178 this.resourcePath = path == null ? EMPTY : path + SLASH;
179 return this;
180 }
181
182 /**
183 * Sets the message handler factory for this extension.
184 *
185 * @param mhFactory message handler factory
186 * @return self, for chaining
187 */
188 public Builder messageHandlerFactory(UiMessageHandlerFactory mhFactory) {
189 this.messageHandlerFactory = mhFactory;
190 return this;
191 }
192
193 /**
194 * Sets the topology overlay factory for this extension.
195 *
196 * @param toFactory topology overlay factory
197 * @return self, for chaining
198 */
199 public Builder topoOverlayFactory(UiTopoOverlayFactory toFactory) {
200 this.topoOverlayFactory = toFactory;
201 return this;
202 }
203
204 /**
Steven Burrows3a9a6442016-05-05 15:31:16 +0100205 * Sets the topology map factory for this extension.
206 *
207 * @param tmFactory topology map factory
208 * @return self, for chaining
209 */
210 public Builder topoMapFactory(UiTopoMapFactory tmFactory) {
211 this.topoMapFactory = tmFactory;
212 return this;
213 }
214
215 /**
Simon Hunte05cae42015-07-23 17:35:24 -0700216 * Builds the UI extension.
217 *
218 * @return UI extension instance
219 */
220 public UiExtension build() {
221 return new UiExtension(classLoader, resourcePath, views,
Steven Burrows3a9a6442016-05-05 15:31:16 +0100222 messageHandlerFactory, topoOverlayFactory,
223 topoMapFactory);
Simon Hunte05cae42015-07-23 17:35:24 -0700224 }
225
226 }
227
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -0800228}