blob: 17201cbf353fe40dbb2f313ca29fb646420e5cab [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/**
Simon Hunt8add9ee2016-09-20 17:05:07 -070030 * Immutable representation of a user interface extension.
31 * <p>
32 * Note that the {@link Builder} class is used to create a user
33 * interface extension instance, and that these instances are immutable.
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080034 */
Simon Hunte05cae42015-07-23 17:35:24 -070035public final class UiExtension {
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080036
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -070037 private final Logger log = LoggerFactory.getLogger(getClass());
38
Thomas Vachuska529db0a2015-02-23 16:42:14 -080039 private static final String VIEW_PREFIX = "app/view/";
Simon Hunte05cae42015-07-23 17:35:24 -070040 private static final String EMPTY = "";
41 private static final String SLASH = "/";
42 private static final String CSS_HTML = "css.html";
43 private static final String JS_HTML = "js.html";
Thomas Vachuska529db0a2015-02-23 16:42:14 -080044
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080045 private final ClassLoader classLoader;
Simon Hunte05cae42015-07-23 17:35:24 -070046 private final String resourcePath;
Simon Hunt8add9ee2016-09-20 17:05:07 -070047 private final List<UiView> viewList;
Thomas Vachuska3553b302015-03-07 14:49:43 -080048 private final UiMessageHandlerFactory messageHandlerFactory;
Simon Hunte05cae42015-07-23 17:35:24 -070049 private final UiTopoOverlayFactory topoOverlayFactory;
Steven Burrows3a9a6442016-05-05 15:31:16 +010050 private final UiTopoMapFactory topoMapFactory;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080051
Thomas Vachuskac4178cc2015-12-10 11:43:32 -080052 private boolean isValid = true;
Simon Hunte05cae42015-07-23 17:35:24 -070053
54 // private constructor - only the builder calls this
55 private UiExtension(ClassLoader cl, String path, List<UiView> views,
56 UiMessageHandlerFactory mhFactory,
Steven Burrows3a9a6442016-05-05 15:31:16 +010057 UiTopoOverlayFactory toFactory,
58 UiTopoMapFactory tmFactory) {
Simon Hunt8add9ee2016-09-20 17:05:07 -070059 classLoader = cl;
60 resourcePath = path;
61 viewList = views;
62 messageHandlerFactory = mhFactory;
63 topoOverlayFactory = toFactory;
64 topoMapFactory = tmFactory;
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080065 }
66
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080067
68 /**
69 * Returns input stream containing CSS inclusion statements.
70 *
71 * @return CSS inclusion statements
72 */
73 public InputStream css() {
Simon Hunte05cae42015-07-23 17:35:24 -070074 return getStream(resourcePath + CSS_HTML);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080075 }
76
77 /**
78 * Returns input stream containing JavaScript inclusion statements.
79 *
80 * @return JavaScript inclusion statements
81 */
82 public InputStream js() {
Thomas Vachuskad894b5d2015-07-30 11:59:07 -070083 return getStream(resourcePath + JS_HTML);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080084 }
85
86 /**
87 * Returns list of user interface views contributed by this extension.
88 *
89 * @return contributed view descriptors
90 */
91 public List<UiView> views() {
Simon Hunt8add9ee2016-09-20 17:05:07 -070092 return isValid ? viewList : ImmutableList.of();
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -080093 }
94
95 /**
96 * Returns input stream containing specified view-specific resource.
97 *
98 * @param viewId view identifier
99 * @param path resource path, relative to the view directory
100 * @return resource input stream
101 */
102 public InputStream resource(String viewId, String path) {
Simon Hunte05cae42015-07-23 17:35:24 -0700103 return getStream(VIEW_PREFIX + viewId + SLASH + path);
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -0800104 }
105
Thomas Vachuska3553b302015-03-07 14:49:43 -0800106 /**
Simon Hunte05cae42015-07-23 17:35:24 -0700107 * Returns message handler factory, if one was defined.
Thomas Vachuska3553b302015-03-07 14:49:43 -0800108 *
Simon Hunte05cae42015-07-23 17:35:24 -0700109 * @return message handler factory
Thomas Vachuska3553b302015-03-07 14:49:43 -0800110 */
111 public UiMessageHandlerFactory messageHandlerFactory() {
112 return messageHandlerFactory;
113 }
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700114
Simon Hunte05cae42015-07-23 17:35:24 -0700115 /**
116 * Returns the topology overlay factory, if one was defined.
117 *
118 * @return topology overlay factory
119 */
120 public UiTopoOverlayFactory topoOverlayFactory() {
121 return topoOverlayFactory;
122 }
123
Steven Burrows3a9a6442016-05-05 15:31:16 +0100124 /**
125 * Returns the topology map factory, if one was defined.
126 *
127 * @return topology map factory
128 */
129 public UiTopoMapFactory topoMapFactory() {
130 return topoMapFactory;
131 }
132
Simon Hunte05cae42015-07-23 17:35:24 -0700133
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700134 // Returns the resource input stream from the specified class-loader.
135 private InputStream getStream(String path) {
136 InputStream stream = classLoader.getResourceAsStream(path);
137 if (stream == null) {
Thomas Vachuskac4178cc2015-12-10 11:43:32 -0800138 isValid = false;
Thomas Vachuska3ccb9eb2015-04-29 23:33:56 -0700139 log.warn("Unable to find resource {}", path);
140 }
141 return stream;
142 }
143
144
Simon Hunte05cae42015-07-23 17:35:24 -0700145 /**
146 * UI Extension Builder.
147 */
148 public static class Builder {
149 private ClassLoader classLoader;
150
151 private String resourcePath = EMPTY;
Simon Hunt8add9ee2016-09-20 17:05:07 -0700152 private List<UiView> viewList = new ArrayList<>();
Simon Hunte05cae42015-07-23 17:35:24 -0700153 private UiMessageHandlerFactory messageHandlerFactory = null;
154 private UiTopoOverlayFactory topoOverlayFactory = null;
Steven Burrows3a9a6442016-05-05 15:31:16 +0100155 private UiTopoMapFactory topoMapFactory = null;
Simon Hunte05cae42015-07-23 17:35:24 -0700156
157 /**
158 * Create a builder with the given class loader.
159 * Resource path defaults to "".
160 * Views defaults to an empty list.
Simon Hunt8add9ee2016-09-20 17:05:07 -0700161 * MessageHandler, TopoOverlay, and TopoMap factories default to null.
Simon Hunte05cae42015-07-23 17:35:24 -0700162 *
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700163 * @param cl the class loader
164 * @param views list of views contributed by this extension
Simon Hunte05cae42015-07-23 17:35:24 -0700165 */
166 public Builder(ClassLoader cl, List<UiView> views) {
167 checkNotNull(cl, "Must provide a class loader");
Jon Hallcbd1b392017-01-18 20:15:44 -0800168 checkArgument(!views.isEmpty(), "Must provide at least one view");
Simon Hunt8add9ee2016-09-20 17:05:07 -0700169 classLoader = cl;
170 viewList = views;
Simon Hunte05cae42015-07-23 17:35:24 -0700171 }
172
173 /**
Simon Hunt8add9ee2016-09-20 17:05:07 -0700174 * Set the resource path. That is, the path to where the CSS and JS
175 * files are located.
Simon Hunte05cae42015-07-23 17:35:24 -0700176 *
177 * @param path resource path
178 * @return self, for chaining
179 */
180 public Builder resourcePath(String path) {
Simon Hunt8add9ee2016-09-20 17:05:07 -0700181 resourcePath = path == null ? EMPTY : path + SLASH;
Simon Hunte05cae42015-07-23 17:35:24 -0700182 return this;
183 }
184
185 /**
186 * Sets the message handler factory for this extension.
187 *
188 * @param mhFactory message handler factory
189 * @return self, for chaining
190 */
191 public Builder messageHandlerFactory(UiMessageHandlerFactory mhFactory) {
Simon Hunt8add9ee2016-09-20 17:05:07 -0700192 messageHandlerFactory = mhFactory;
Simon Hunte05cae42015-07-23 17:35:24 -0700193 return this;
194 }
195
196 /**
197 * Sets the topology overlay factory for this extension.
198 *
199 * @param toFactory topology overlay factory
200 * @return self, for chaining
201 */
202 public Builder topoOverlayFactory(UiTopoOverlayFactory toFactory) {
Simon Hunt8add9ee2016-09-20 17:05:07 -0700203 topoOverlayFactory = toFactory;
Simon Hunte05cae42015-07-23 17:35:24 -0700204 return this;
205 }
206
207 /**
Steven Burrows3a9a6442016-05-05 15:31:16 +0100208 * Sets the topology map factory for this extension.
209 *
210 * @param tmFactory topology map factory
211 * @return self, for chaining
212 */
213 public Builder topoMapFactory(UiTopoMapFactory tmFactory) {
Simon Hunt8add9ee2016-09-20 17:05:07 -0700214 topoMapFactory = tmFactory;
Steven Burrows3a9a6442016-05-05 15:31:16 +0100215 return this;
216 }
217
218 /**
Simon Hunt8add9ee2016-09-20 17:05:07 -0700219 * Builds the user interface extension.
Simon Hunte05cae42015-07-23 17:35:24 -0700220 *
221 * @return UI extension instance
222 */
223 public UiExtension build() {
Simon Hunt8add9ee2016-09-20 17:05:07 -0700224 return new UiExtension(classLoader, resourcePath, viewList,
Steven Burrows3a9a6442016-05-05 15:31:16 +0100225 messageHandlerFactory, topoOverlayFactory,
226 topoMapFactory);
Simon Hunte05cae42015-07-23 17:35:24 -0700227 }
Simon Hunte05cae42015-07-23 17:35:24 -0700228 }
Thomas Vachuskafe8c98a2015-02-04 01:24:32 -0800229}