Thomas Vachuska
Committed by Gerrit Code Review

Removing a very old CORD GUI demo app.

Change-Id: I1039d5acc145f51f930dee28c5895b9593070628
Showing 91 changed files with 0 additions and 6666 deletions
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!--
3 - ~ Copyright 2015-present Open Networking Laboratory
4 - ~
5 - ~ Licensed under the Apache License, Version 2.0 (the "License");
6 - ~ you may not use this file except in compliance with the License.
7 - ~ You may obtain a copy of the License at
8 - ~
9 - ~ http://www.apache.org/licenses/LICENSE-2.0
10 - ~
11 - ~ Unless required by applicable law or agreed to in writing, software
12 - ~ distributed under the License is distributed on an "AS IS" BASIS,
13 - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 - ~ See the License for the specific language governing permissions and
15 - ~ limitations under the License.
16 - -->
17 -<project xmlns="http://maven.apache.org/POM/4.0.0"
18 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20 - <modelVersion>4.0.0</modelVersion>
21 -
22 - <parent>
23 - <groupId>org.onosproject</groupId>
24 - <artifactId>onos-base</artifactId>
25 - <version>1</version>
26 - <relativePath>../../../tools/build/pom.xml</relativePath>
27 - </parent>
28 -
29 - <artifactId>cord-gui</artifactId>
30 - <version>1.8.0-SNAPSHOT</version>
31 - <packaging>war</packaging>
32 -
33 - <description>Demo CORD Subscriber Web GUI</description>
34 -
35 - <properties>
36 - <web.context>/cord</web.context>
37 - </properties>
38 -
39 - <dependencies>
40 - <dependency>
41 - <groupId>javax.servlet</groupId>
42 - <artifactId>servlet-api</artifactId>
43 - <version>2.5</version>
44 - </dependency>
45 -
46 - <dependency>
47 - <groupId>org.glassfish.jersey.containers</groupId>
48 - <artifactId>jersey-container-servlet</artifactId>
49 - <version>2.22.2</version>
50 - </dependency>
51 - <dependency>
52 - <groupId>org.glassfish.jersey.core</groupId>
53 - <artifactId>jersey-client</artifactId>
54 - <version>2.22.2</version>
55 - </dependency>
56 -
57 - <dependency>
58 - <groupId>org.slf4j</groupId>
59 - <artifactId>slf4j-api</artifactId>
60 - <version>1.7.21</version>
61 - </dependency>
62 -
63 - <dependency>
64 - <groupId>org.slf4j</groupId>
65 - <artifactId>slf4j-jdk14</artifactId>
66 - <version>1.7.21</version>
67 - </dependency>
68 -
69 - <dependency>
70 - <groupId>commons-io</groupId>
71 - <artifactId>commons-io</artifactId>
72 - <version>2.4</version>
73 - </dependency>
74 - <dependency>
75 - <groupId>com.fasterxml.jackson.core</groupId>
76 - <artifactId>jackson-core</artifactId>
77 - <version>2.7.3</version>
78 - </dependency>
79 - <dependency>
80 - <groupId>com.fasterxml.jackson.core</groupId>
81 - <artifactId>jackson-databind</artifactId>
82 - <version>2.7.3</version>
83 - </dependency>
84 - <dependency>
85 - <groupId>com.google.guava</groupId>
86 - <artifactId>guava</artifactId>
87 - <version>19.0</version>
88 - </dependency>
89 - </dependencies>
90 -
91 - <build>
92 - <pluginManagement>
93 - <plugins>
94 - <plugin>
95 - <groupId>org.apache.maven.plugins</groupId>
96 - <artifactId>maven-compiler-plugin</artifactId>
97 - <!-- TODO: update once following issue is fixed. -->
98 - <!-- https://jira.codehaus.org/browse/MCOMPILER-205 -->
99 - <version>2.5.1</version>
100 - <configuration>
101 - <source>1.7</source>
102 - <target>1.7</target>
103 - </configuration>
104 - </plugin>
105 - </plugins>
106 - </pluginManagement>
107 - </build>
108 -
109 -</project>
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui;
19 -
20 -import com.fasterxml.jackson.databind.JsonNode;
21 -import com.fasterxml.jackson.databind.node.ArrayNode;
22 -import com.fasterxml.jackson.databind.node.ObjectNode;
23 -import com.google.common.collect.ImmutableList;
24 -import org.onosproject.cord.gui.model.Bundle;
25 -import org.onosproject.cord.gui.model.BundleDescriptor;
26 -import org.onosproject.cord.gui.model.BundleFactory;
27 -import org.onosproject.cord.gui.model.JsonFactory;
28 -import org.onosproject.cord.gui.model.SubscriberUser;
29 -import org.onosproject.cord.gui.model.UserFactory;
30 -import org.onosproject.cord.gui.model.XosFunction;
31 -import org.onosproject.cord.gui.model.XosFunctionDescriptor;
32 -import org.slf4j.Logger;
33 -import org.slf4j.LoggerFactory;
34 -
35 -import java.util.HashMap;
36 -import java.util.Iterator;
37 -import java.util.List;
38 -import java.util.Map;
39 -import java.util.TreeMap;
40 -
41 -import static com.google.common.base.Preconditions.checkNotNull;
42 -import static org.onosproject.cord.gui.model.XosFunctionDescriptor.URL_FILTER;
43 -
44 -/**
45 - * In memory cache of the model of the subscriber's account.
46 - */
47 -public class CordModelCache extends JsonFactory {
48 -
49 - private static final String KEY_SSID_MAP = "ssidmap";
50 - private static final String KEY_SSID = "service_specific_id";
51 - private static final String KEY_SUB_ID = "subscriber_id";
52 -
53 - private static final int DEMO_SSID = 1234;
54 -
55 - private static final String EMAIL_0 = "john@smith.org";
56 - private static final String EMAIL_1 = "john@doe.org";
57 -
58 - private static final String EMAIL = "email";
59 - private static final String SSID = "ssid";
60 - private static final String SUB_ID = "subId";
61 -
62 - private static final String BUNDLE = "bundle";
63 - private static final String USERS = "users";
64 - private static final String LEVEL = "level";
65 - private static final String LOGOUT = "logout";
66 -
67 - private static final String BUNDLE_NAME = BUNDLE + "_name";
68 - private static final String BUNDLE_DESC = BUNDLE + "_desc";
69 -
70 - private static final Map<Integer, Integer> LOOKUP = new HashMap<>();
71 -
72 - private String email = null;
73 - private int subscriberId;
74 - private int ssid;
75 - private Bundle currentBundle;
76 -
77 - private final Logger log = LoggerFactory.getLogger(getClass());
78 -
79 - // NOTE: use a tree map to maintain sorted order by user ID
80 - private final Map<Integer, SubscriberUser> userMap =
81 - new TreeMap<Integer, SubscriberUser>();
82 -
83 - /**
84 - * Constructs a model cache, retrieving a mapping of SSID to XOS Subscriber
85 - * IDs from the XOS server.
86 - */
87 - CordModelCache() {
88 - log.info("Initialize model cache");
89 - ObjectNode map = XosManager.INSTANCE.initXosSubscriberLookups();
90 - initLookupMap(map);
91 - log.info("{} entries in SSID->SubID lookup map", LOOKUP.size());
92 - }
93 -
94 - private void initLookupMap(ObjectNode map) {
95 - ArrayNode array = (ArrayNode) map.get(KEY_SSID_MAP);
96 - Iterator<JsonNode> iter = array.elements();
97 - StringBuilder msg = new StringBuilder();
98 - while (iter.hasNext()) {
99 - ObjectNode node = (ObjectNode) iter.next();
100 - String ssidStr = node.get(KEY_SSID).asText();
101 - int ssid = Integer.valueOf(ssidStr);
102 - int subId = node.get(KEY_SUB_ID).asInt();
103 - LOOKUP.put(ssid, subId);
104 - msg.append(String.format("\n..binding SSID %s to sub-id %s", ssid, subId));
105 - }
106 - log.info(msg.toString());
107 - }
108 -
109 - private int lookupSubId(int ssid) {
110 - Integer subId = LOOKUP.get(ssid);
111 - if (subId == null) {
112 - log.error("Unmapped SSID: {}", ssid);
113 - return 0;
114 - }
115 - return subId;
116 - }
117 -
118 - /**
119 - * Initializes the model for the subscriber account associated with
120 - * the given email address.
121 - *
122 - * @param email the email address
123 - */
124 - void init(String email) {
125 - // defaults to the demo account
126 - int ssid = DEMO_SSID;
127 -
128 - this.email = email;
129 -
130 - // obviously not scalable, but good enough for demo code...
131 - if (EMAIL_0.equals(email)) {
132 - ssid = 0;
133 - } else if (EMAIL_1.equals(email)) {
134 - ssid = 1;
135 - }
136 -
137 - this.ssid = ssid;
138 - subscriberId = lookupSubId(ssid);
139 - XosManager.INSTANCE.setXosUtilsForSubscriber(subscriberId);
140 -
141 - // call the initdemo API to ensure users are populated in XOS
142 - XosManager.INSTANCE.initDemoSubscriber();
143 -
144 - // NOTE: I think the following should work for non-DEMO account...
145 - currentBundle = new Bundle(BundleFactory.BASIC_BUNDLE);
146 - initUsers();
147 - }
148 -
149 - private void initUsers() {
150 - // start with a clean slate
151 - userMap.clear();
152 -
153 - ArrayNode users = XosManager.INSTANCE.getUserList();
154 - if (users == null) {
155 - log.warn("no user list for SSID {} (subid {})", ssid, subscriberId);
156 - return;
157 - }
158 -
159 - StringBuilder sb = new StringBuilder();
160 - for (JsonNode u: users) {
161 - ObjectNode user = (ObjectNode) u;
162 -
163 - int id = user.get("id").asInt();
164 - String name = user.get("name").asText();
165 - String mac = user.get("mac").asText();
166 - String level = user.get("level").asText();
167 -
168 - // NOTE: We are just storing the current "url-filter" level.
169 - // Since we are starting with the BASIC bundle, (that does
170 - // not include URL_FILTER), we don't yet have the URL_FILTER
171 - // memento in which to store the level.
172 - SubscriberUser su = createUser(id, name, mac, level);
173 - userMap.put(id, su);
174 - sb.append(String.format("\n..cache user %s [%d], %s, %s",
175 - name, id, mac, level));
176 - }
177 - log.info(sb.toString());
178 - }
179 -
180 - private SubscriberUser createUser(int uid, String name, String mac,
181 - String level) {
182 - SubscriberUser user = new SubscriberUser(uid, name, mac, level);
183 - for (XosFunction f: currentBundle.functions()) {
184 - user.setMemento(f.descriptor(), f.createMemento());
185 - }
186 - return user;
187 - }
188 -
189 - /**
190 - * Returns the currently selected bundle.
191 - *
192 - * @return current bundle
193 - */
194 - public Bundle getCurrentBundle() {
195 - return currentBundle;
196 - }
197 -
198 - /**
199 - * Sets a new bundle.
200 - *
201 - * @param bundleId bundle identifier
202 - * @throws IllegalArgumentException if bundle ID is unknown
203 - */
204 - public void setCurrentBundle(String bundleId) {
205 - log.info("set new bundle : {}", bundleId);
206 - BundleDescriptor bd = BundleFactory.bundleFromId(bundleId);
207 - currentBundle = new Bundle(bd);
208 - // update the user mementos
209 - for (SubscriberUser user: userMap.values()) {
210 - user.clearMementos();
211 - for (XosFunction f: currentBundle.functions()) {
212 - user.setMemento(f.descriptor(), f.createMemento());
213 - if (f.descriptor().equals(URL_FILTER)) {
214 - applyUrlFilterLevel(user, user.urlFilterLevel());
215 - }
216 - }
217 - }
218 -
219 - XosManager.INSTANCE.setNewBundle(currentBundle);
220 - }
221 -
222 -
223 - /**
224 - * Returns the list of current users for this subscriber account.
225 - *
226 - * @return the list of users
227 - */
228 - public List<SubscriberUser> getUsers() {
229 - return ImmutableList.copyOf(userMap.values());
230 - }
231 -
232 - /**
233 - * Applies a function parameter change for a user, pushing that
234 - * change through to XOS.
235 - *
236 - * @param userId user identifier
237 - * @param funcId function identifier
238 - * @param param function parameter to change
239 - * @param value new value for function parameter
240 - */
241 - public void applyPerUserParam(String userId, String funcId,
242 - String param, String value) {
243 -
244 - int uid = Integer.parseInt(userId);
245 - SubscriberUser user = userMap.get(uid);
246 - checkNotNull(user, "unknown user id: " + uid);
247 -
248 - XosFunctionDescriptor xfd =
249 - XosFunctionDescriptor.valueOf(funcId.toUpperCase());
250 -
251 - XosFunction func = currentBundle.findFunction(xfd);
252 - checkNotNull(func, "function not part of bundle: " + funcId);
253 - applyParam(func, user, param, value, true);
254 - }
255 -
256 - // =============
257 -
258 - private void applyUrlFilterLevel(SubscriberUser user, String level) {
259 - XosFunction urlFilter = currentBundle.findFunction(URL_FILTER);
260 - if (urlFilter != null) {
261 - applyParam(urlFilter, user, LEVEL, level, false);
262 - }
263 - }
264 -
265 - private void applyParam(XosFunction func, SubscriberUser user,
266 - String param, String value, boolean punchThrough) {
267 - func.applyParam(user, param, value);
268 - if (punchThrough) {
269 - XosManager.INSTANCE.apply(func, user);
270 - }
271 - }
272 -
273 - private ArrayNode userJsonArray() {
274 - ArrayNode userList = arrayNode();
275 - for (SubscriberUser user: userMap.values()) {
276 - userList.add(UserFactory.toObjectNode(user));
277 - }
278 - return userList;
279 - }
280 -
281 - // ============= generate JSON for GUI rest calls..
282 -
283 - private void addSubId(ObjectNode root) {
284 - root.put(SUB_ID, subscriberId);
285 - root.put(SSID, ssid);
286 - root.put(EMAIL, email);
287 - }
288 -
289 -
290 - /**
291 - * Returns response JSON for login request.
292 - * <p>
293 - * Depending on which email is used, will bind the GUI to the
294 - * appropriate XOS Subscriber ID.
295 - *
296 - * @param email the supplied email
297 - * @return JSON acknowledgement
298 - */
299 - public synchronized String jsonLogin(String email) {
300 - log.info("jsonLogin(\"{}\")", email);
301 - init(email);
302 - ObjectNode root = objectNode();
303 - addSubId(root);
304 - return root.toString();
305 - }
306 -
307 - /**
308 - * Returns the dashboard page data as JSON.
309 - *
310 - * @return dashboard page JSON data
311 - */
312 - public synchronized String jsonDashboard() {
313 - log.info("jsonDashboard()");
314 -
315 - if (email == null) {
316 - return jsonLogout();
317 - }
318 -
319 - BundleDescriptor bundleDescriptor = currentBundle.descriptor();
320 - ObjectNode root = objectNode();
321 - root.put(BUNDLE_NAME, bundleDescriptor.displayName());
322 - root.put(BUNDLE_DESC, bundleDescriptor.description());
323 - root.set(USERS, userJsonArray());
324 - addSubId(root);
325 - return root.toString();
326 - }
327 -
328 - /**
329 - * Returns the bundle page data as JSON.
330 - *
331 - * @return bundle page JSON data
332 - */
333 - public synchronized String jsonBundle() {
334 - log.info("jsonBundle()");
335 -
336 - if (email == null) {
337 - return jsonLogout();
338 - }
339 -
340 - ObjectNode root = BundleFactory.toObjectNode(currentBundle);
341 - addSubId(root);
342 - return root.toString();
343 - }
344 -
345 - /**
346 - * Returns the users page data as JSON.
347 - *
348 - * @return users page JSON data
349 - */
350 - public synchronized String jsonUsers() {
351 - log.info("jsonUsers()");
352 -
353 - if (email == null) {
354 - return jsonLogout();
355 - }
356 -
357 - ObjectNode root = objectNode();
358 - root.set(USERS, userJsonArray());
359 - addSubId(root);
360 - return root.toString();
361 - }
362 -
363 - /**
364 - * Returns logout acknowledgement as JSON.
365 - *
366 - * @return logout acknowledgement
367 - */
368 - public synchronized String jsonLogout() {
369 - log.info("jsonLogout()");
370 - ObjectNode root = objectNode().put(LOGOUT, true);
371 - addSubId(root);
372 -
373 - email = null; // signifies no one logged in
374 -
375 - return root.toString();
376 - }
377 -
378 - /**
379 - * Singleton instance.
380 - */
381 - public static final CordModelCache INSTANCE = new CordModelCache();
382 -}
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -package org.onosproject.cord.gui;
18 -
19 -import javax.ws.rs.GET;
20 -import javax.ws.rs.Path;
21 -import javax.ws.rs.PathParam;
22 -import javax.ws.rs.Produces;
23 -import javax.ws.rs.core.MediaType;
24 -import javax.ws.rs.core.Response;
25 -
26 -/**
27 - * Web resource to use as the GUI back-end and as a proxy to XOS REST API.
28 - */
29 -@Path("")
30 -public class CordWebResource {
31 -
32 - @GET
33 - @Produces(MediaType.APPLICATION_JSON)
34 - @Path("login/{email}")
35 - public Response login(@PathParam("email") String email) {
36 - return Response.ok(CordModelCache.INSTANCE.jsonLogin(email)).build();
37 - }
38 -
39 - @GET
40 - @Produces(MediaType.APPLICATION_JSON)
41 - @Path("dashboard")
42 - public Response dashboard() {
43 - return Response.ok(CordModelCache.INSTANCE.jsonDashboard()).build();
44 - }
45 -
46 - @GET
47 - @Produces(MediaType.APPLICATION_JSON)
48 - @Path("bundle")
49 - public Response bundle() {
50 - return Response.ok(CordModelCache.INSTANCE.jsonBundle()).build();
51 - }
52 -
53 - @GET
54 - @Produces(MediaType.APPLICATION_JSON)
55 - @Path("users")
56 - public Response users() {
57 - return Response.ok(CordModelCache.INSTANCE.jsonUsers()).build();
58 - }
59 -
60 - @GET
61 - @Produces(MediaType.APPLICATION_JSON)
62 - @Path("logout")
63 - public Response logout() {
64 - return Response.ok(CordModelCache.INSTANCE.jsonLogout()).build();
65 - }
66 -
67 - // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
68 -
69 - @GET
70 - @Produces(MediaType.APPLICATION_JSON)
71 - @Path("bundle/{id}")
72 - public Response bundle(@PathParam("id") String bundleId) {
73 - CordModelCache.INSTANCE.setCurrentBundle(bundleId);
74 - return bundle();
75 - }
76 -
77 - @GET
78 - @Produces(MediaType.APPLICATION_JSON)
79 - @Path("users/{id}/apply/{func}/{param}/{value}")
80 - public Response bundle(@PathParam("id") String userId,
81 - @PathParam("func") String funcId,
82 - @PathParam("param") String param,
83 - @PathParam("value") String value) {
84 - CordModelCache.INSTANCE.applyPerUserParam(userId, funcId, param, value);
85 - return users();
86 - }
87 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui;
19 -
20 -import org.apache.commons.io.IOUtils;
21 -
22 -import java.io.IOException;
23 -import java.io.InputStream;
24 -
25 -/**
26 - * Provides support for fake data.
27 - */
28 -public class FakeUtils {
29 - private static final ClassLoader CL = FakeUtils.class.getClassLoader();
30 - private static final String ROOT_PATH = "/org/onosproject/cord/gui/";
31 - private static final String UTF_8 = "UTF-8";
32 -
33 - /**
34 - * Returns the contents of a local file as a string.
35 - *
36 - * @param path file path name
37 - * @return contents of file as a string
38 - */
39 - public static String slurp(String path) {
40 - String result = null;
41 - InputStream is = CL.getResourceAsStream(ROOT_PATH + path);
42 - if (is != null) {
43 - try {
44 - result = IOUtils.toString(is, UTF_8);
45 - } catch (IOException e) {
46 - e.printStackTrace();
47 - }
48 - }
49 - return result;
50 - }
51 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui;
19 -
20 -import com.fasterxml.jackson.databind.JsonNode;
21 -import com.fasterxml.jackson.databind.ObjectMapper;
22 -import com.fasterxml.jackson.databind.node.ArrayNode;
23 -import com.fasterxml.jackson.databind.node.ObjectNode;
24 -import org.onosproject.cord.gui.model.Bundle;
25 -import org.onosproject.cord.gui.model.SubscriberUser;
26 -import org.onosproject.cord.gui.model.XosFunction;
27 -import org.onosproject.cord.gui.model.XosFunctionDescriptor;
28 -import org.slf4j.Logger;
29 -import org.slf4j.LoggerFactory;
30 -
31 -import java.io.IOException;
32 -import java.util.Set;
33 -
34 -/**
35 - * Encapsulation of interactions with XOS.
36 - */
37 -public class XosManager {
38 -
39 - private static final ObjectMapper MAPPER = new ObjectMapper();
40 -
41 - private static final String HEAD_NODE_IP = "headnodeip";
42 - private static final String HEAD_NODE_PORT = "headnodeport";
43 - private static final int PORT_MIN = 1025;
44 - private static final int PORT_MAX = 65535;
45 -
46 - private static final String TEST_XOS_SERVER_IP = "10.254.1.22";
47 - private static final String TEST_XOS_SERVER_PORT_STR = "8000";
48 - private static final int TEST_XOS_SERVER_PORT = 8000;
49 - private static final String URI_RS = "/rs/";
50 - private static final String URI_SUBSCRIBER = "/rs/subscriber/%d/";
51 - private static final String BUNDLE_URI_FORMAT = "services/%s/%s/";
52 -
53 -
54 - private String xosServerIp;
55 - private int xosServerPort;
56 - private XosManagerRestUtils xosUtilsRs;
57 - private XosManagerRestUtils xosUtils;
58 -
59 -
60 - private final Logger log = LoggerFactory.getLogger(getClass());
61 -
62 - /**
63 - * No instantiation (except via unit test).
64 - */
65 - XosManager() {}
66 -
67 - private String getXosServerIp() {
68 - return System.getProperty(HEAD_NODE_IP, TEST_XOS_SERVER_IP);
69 - }
70 -
71 - private int getXosServerPort() {
72 - String p = System.getProperty(HEAD_NODE_PORT, TEST_XOS_SERVER_PORT_STR);
73 - int port;
74 - try {
75 - port = Integer.valueOf(p);
76 - } catch (NumberFormatException e) {
77 - port = TEST_XOS_SERVER_PORT;
78 - log.warn("Could not parse port number [{}], using {}", p, port);
79 - }
80 - if (port < PORT_MIN || port > PORT_MAX) {
81 - log.warn("Bad port number [{}], using {}", port, TEST_XOS_SERVER_PORT);
82 - port = TEST_XOS_SERVER_PORT;
83 - }
84 - return port;
85 - }
86 -
87 - /**
88 - * Queries XOS for the Subscriber ID lookup data, and returns it.
89 - */
90 - public ObjectNode initXosSubscriberLookups() {
91 - log.info("intDemoSubscriberLookups() called");
92 - xosServerIp = getXosServerIp();
93 - xosServerPort = getXosServerPort();
94 - log.info("Using XOS server at {}:{}", xosServerIp, xosServerPort);
95 -
96 - xosUtilsRs = new XosManagerRestUtils(xosServerIp, xosServerPort, URI_RS);
97 -
98 - // ask XOS for the subscriber ID lookup info
99 - String result = xosUtilsRs.getRest("subidlookup/");
100 - log.info("lookup data from XOS: {}", result);
101 -
102 - JsonNode node;
103 - try {
104 - node = MAPPER.readTree(result);
105 - } catch (IOException e) {
106 - log.error("failed to read subscriber lookup JSON data", e);
107 - return null;
108 - }
109 - return (ObjectNode) node;
110 - }
111 -
112 - /**
113 - * Sets a new XOS utils object to bind URL patterns for the
114 - * given XOS subscriber ID.
115 - *
116 - * @param xosSubId XOS subscriber ID
117 - */
118 - public void setXosUtilsForSubscriber(int xosSubId) {
119 - String uri = String.format(URI_SUBSCRIBER, xosSubId);
120 - xosUtils = new XosManagerRestUtils(xosServerIp, xosServerPort, uri);
121 - }
122 -
123 -
124 - public void initDemoSubscriber() {
125 - log.info("initDemoSubscriber() called");
126 - String result = xosUtilsRs.getRest("initdemo/");
127 - log.info("initdemo data from XOS: {}", result);
128 - }
129 -
130 - /**
131 - * Returns the array of users for the subscriber.
132 - *
133 - * @return list of users
134 - */
135 - public ArrayNode getUserList() {
136 - log.info("getUserList() called");
137 - String result = xosUtils.getRest("users/");
138 -
139 - JsonNode node;
140 - try {
141 - node = MAPPER.readTree(result);
142 - } catch (IOException e) {
143 - log.error("failed to read user list JSON", e);
144 - return null;
145 - }
146 -
147 - ObjectNode obj = (ObjectNode) node;
148 - return (ArrayNode) obj.get("users");
149 - }
150 -
151 -
152 - /**
153 - * Configure XOS to enable the functions that compose the given bundle,
154 - * and disable all the others, for the given subscriber.
155 - *
156 - * @param bundle new bundle to set
157 - */
158 - public void setNewBundle(Bundle bundle) {
159 - log.info(">> Set New Bundle : {}", bundle.descriptor().id());
160 -
161 - Set<XosFunctionDescriptor> inBundle = bundle.descriptor().functions();
162 - for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) {
163 - // only process the functions that have a real back-end on XOS
164 - if (xfd.backend()) {
165 - String uri = String.format(BUNDLE_URI_FORMAT, xfd.id(),
166 - inBundle.contains(xfd));
167 - log.info("XOS-URI: {}", uri);
168 - String result = xosUtils.putRest(uri);
169 - // TODO: convert JSON result to object and check (if we care)
170 - }
171 - }
172 - }
173 -
174 - /**
175 - * Configure XOS with new setting for given user and function, for the
176 - * given subscriber account.
177 - *
178 - * @param func specific XOS function
179 - * @param user user (containing function state)
180 - */
181 - public void apply(XosFunction func, SubscriberUser user) {
182 - log.info(">> Apply : {} for {}", func, user);
183 -
184 - String uriPrefix = "users/" + user.id() + "/";
185 - String uri = uriPrefix + func.xosUrlApply(user);
186 - log.info("XOS-URI: {}", uri);
187 - String result = xosUtils.putRest(uri);
188 - // TODO: convert JSON result to object and check (if we care)
189 - }
190 -
191 -
192 - // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
193 -
194 - /**
195 - * Singleton instance.
196 - */
197 - public static final XosManager INSTANCE = new XosManager();
198 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui;
19 -
20 -import com.sun.jersey.api.client.Client;
21 -import com.sun.jersey.api.client.ClientHandlerException;
22 -import com.sun.jersey.api.client.ClientResponse;
23 -import com.sun.jersey.api.client.WebResource;
24 -import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
25 -import org.slf4j.Logger;
26 -
27 -import static com.google.common.net.MediaType.JSON_UTF_8;
28 -import static java.net.HttpURLConnection.*;
29 -import static org.slf4j.LoggerFactory.getLogger;
30 -
31 -/**
32 - * Utility RESTful methods for dealing with the XOS server.
33 - */
34 -public class XosManagerRestUtils {
35 - private static final String XOSLIB = "/xoslib";
36 - private static final String AUTH_USER = "padmin@vicci.org";
37 - private static final String AUTH_PASS = "letmein";
38 -
39 - private static final String UTF_8 = JSON_UTF_8.toString();
40 -
41 - private final Logger log = getLogger(getClass());
42 -
43 - private final String xosServerAddress;
44 - private final int xosServerPort;
45 - private final String baseUri;
46 -
47 -
48 - /**
49 - * Constructs a utility class, using the supplied server address and port,
50 - * using the given base URI.
51 - * <p>
52 - * Note that the uri should start and end with a slash; for example:
53 - * {@code "/volttenant/"}. This example would result in URIs of the form:
54 - * <pre>
55 - * "http://[server]:[port]/xoslib/volttenant/"
56 - * </pre>
57 - *
58 - * @param xosServerAddress server IP address
59 - * @param xosServerPort server port
60 - * @param baseUri base URI
61 - */
62 - public XosManagerRestUtils(String xosServerAddress, int xosServerPort,
63 - String baseUri) {
64 - this.xosServerAddress = xosServerAddress;
65 - this.xosServerPort = xosServerPort;
66 - this.baseUri = baseUri;
67 - log.info("XMRU:: {}:{}{}", xosServerAddress, xosServerPort, baseUri);
68 - }
69 -
70 - // build the base URL from the pieces we know...
71 - private String baseUrl() {
72 - return "http://" + xosServerAddress + ":" +
73 - Integer.toString(xosServerPort) + XOSLIB + baseUri;
74 - }
75 -
76 - /**
77 - * Gets a client web resource builder for the base XOS REST API
78 - * with no additional URI.
79 - *
80 - * @return web resource builder
81 - */
82 - public WebResource.Builder getClientBuilder() {
83 - return getClientBuilder("");
84 - }
85 -
86 - /**
87 - * Gets a client web resource builder for the base XOS REST API
88 - * with an optional additional URI.
89 - *
90 - * @param uri URI suffix to append to base URI
91 - * @return web resource builder
92 - */
93 - public WebResource.Builder getClientBuilder(String uri) {
94 - Client client = Client.create();
95 - client.addFilter(new HTTPBasicAuthFilter(AUTH_USER, AUTH_PASS));
96 - WebResource resource = client.resource(baseUrl() + uri);
97 - log.info("XOS REST CALL>> {}", resource);
98 - return resource.accept(UTF_8).type(UTF_8);
99 - }
100 -
101 - /**
102 - * Performs a REST GET operation on the base XOS REST URI.
103 - *
104 - * @return JSON string fetched by the GET operation
105 - */
106 - public String getRest() {
107 - return getRest("");
108 - }
109 -
110 - /**
111 - * Performs a REST GET operation on the base XOS REST URI with
112 - * an optional additional URI.
113 - *
114 - * @param uri URI suffix to append to base URI
115 - * @return JSON string fetched by the GET operation
116 - */
117 - public String getRest(String uri) {
118 - WebResource.Builder builder = getClientBuilder(uri);
119 - ClientResponse response = builder.get(ClientResponse.class);
120 -
121 - if (response.getStatus() != HTTP_OK) {
122 - log.info("REST GET request returned error code {}",
123 - response.getStatus());
124 - }
125 - return response.getEntity(String.class);
126 - }
127 -
128 - /**
129 - * Performs a REST PUT operation on the base XOS REST URI.
130 - *
131 - * @return JSON string returned by the PUT operation
132 - */
133 - public String putRest() {
134 - return putRest("");
135 - }
136 -
137 - /**
138 - * Performs a REST PUT operation on the base XOS REST URI with
139 - * an optional additional URI.
140 - *
141 - * @param uri URI suffix to append to base URI
142 - * @return JSON string returned by the PUT operation
143 - */
144 - public String putRest(String uri) {
145 - WebResource.Builder builder = getClientBuilder(uri);
146 - ClientResponse response;
147 -
148 - try {
149 - response = builder.put(ClientResponse.class);
150 - } catch (ClientHandlerException e) {
151 - log.warn("Unable to contact REST server: {}", e.getMessage());
152 - return "";
153 - }
154 -
155 - if (response.getStatus() != HTTP_OK) {
156 - log.info("REST PUT request returned error code {}",
157 - response.getStatus());
158 - }
159 - return response.getEntity(String.class);
160 - }
161 -
162 - /**
163 - * Performs a REST POST operation of a json string on the base
164 - * XOS REST URI with an optional additional URI.
165 - *
166 - * @param json JSON string to post
167 - */
168 - public void postRest(String json) {
169 - postRest("", json);
170 - }
171 -
172 - /**
173 - * Performs a REST POST operation of a json string on the base
174 - * XOS REST URI with an optional additional URI suffix.
175 - *
176 - * @param uri URI suffix to append to base URI
177 - * @param json JSON string to post
178 - */
179 - public void postRest(String uri, String json) {
180 - WebResource.Builder builder = getClientBuilder(uri);
181 - ClientResponse response;
182 -
183 - try {
184 - response = builder.post(ClientResponse.class, json);
185 - } catch (ClientHandlerException e) {
186 - log.warn("Unable to contact REST server: {}", e.getMessage());
187 - return;
188 - }
189 -
190 - if (response.getStatus() != HTTP_CREATED) {
191 - log.info("REST POST request returned error code {}",
192 - response.getStatus());
193 - }
194 - }
195 -
196 - /**
197 - * Performs a REST DELETE operation on the base
198 - * XOS REST URI with an optional additional URI.
199 - *
200 - * @param uri URI suffix to append to base URI
201 - */
202 - public void deleteRest(String uri) {
203 - WebResource.Builder builder = getClientBuilder(uri);
204 - ClientResponse response = builder.delete(ClientResponse.class);
205 -
206 - if (response.getStatus() != HTTP_NO_CONTENT) {
207 - log.info("REST DELETE request returned error code {}",
208 - response.getStatus());
209 - }
210 - }
211 -
212 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.google.common.collect.ImmutableSet;
21 -
22 -import java.util.HashMap;
23 -import java.util.Map;
24 -import java.util.Set;
25 -
26 -/**
27 - * Encapsulates a bundle, including current state.
28 - */
29 -public class Bundle {
30 - private final BundleDescriptor bundleDescriptor;
31 - private final Map<XosFunctionDescriptor, XosFunction> functionMap =
32 - new HashMap<XosFunctionDescriptor, XosFunction>();
33 -
34 - /**
35 - * Constructs a new bundle instance.
36 - *
37 - * @param bundleDescriptor the descriptor
38 - */
39 - public Bundle(BundleDescriptor bundleDescriptor) {
40 - this.bundleDescriptor = bundleDescriptor;
41 - initFunctions();
42 - }
43 -
44 - /**
45 - * Returns the bundle descriptor.
46 - *
47 - * @return the descriptor
48 - */
49 - public BundleDescriptor descriptor() {
50 - return bundleDescriptor;
51 - }
52 -
53 - /**
54 - * Returns the set of function instances for this bundle.
55 - *
56 - * @return the functions
57 - */
58 - public Set<XosFunction> functions() {
59 - return ImmutableSet.copyOf(functionMap.values());
60 - }
61 -
62 - /**
63 - * Creates an initial set of function instances.
64 - */
65 - private void initFunctions() {
66 - for (XosFunctionDescriptor xfd: bundleDescriptor.functions()) {
67 - functionMap.put(xfd, createFunction(xfd));
68 - }
69 - }
70 -
71 - private XosFunction createFunction(XosFunctionDescriptor xfd) {
72 - XosFunction func;
73 - switch (xfd) {
74 - case URL_FILTER:
75 - func = new UrlFilterFunction();
76 - break;
77 -
78 - default:
79 - func = new DefaultXosFunction(xfd);
80 - break;
81 - }
82 - return func;
83 - }
84 -
85 - /**
86 - * Returns the function instance for the specified descriptor, or returns
87 - * null if function is not part of this bundle.
88 - *
89 - * @param xfd function descrriptor
90 - * @return function instance
91 - */
92 - public XosFunction findFunction(XosFunctionDescriptor xfd) {
93 - return functionMap.get(xfd);
94 - }
95 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import java.util.Set;
21 -
22 -/**
23 - * Defines a bundle of {@link XosFunctionDescriptor XOS functions}.
24 - */
25 -public interface BundleDescriptor {
26 -
27 - /**
28 - * Bundle internal identifier.
29 - *
30 - * @return bundle identifier
31 - */
32 - String id();
33 -
34 - /**
35 - * Bundle display name.
36 - *
37 - * @return display name
38 - */
39 - String displayName();
40 -
41 - /**
42 - * Textual description of this bundle.
43 - *
44 - * @return description
45 - */
46 - String description();
47 -
48 - /**
49 - * The set of functions in this bundle instance.
50 - *
51 - * @return the functions
52 - */
53 - Set<XosFunctionDescriptor> functions();
54 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.fasterxml.jackson.databind.node.ArrayNode;
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 -import com.google.common.collect.ImmutableList;
23 -
24 -import java.util.List;
25 -
26 -/**
27 - * Utility factory for creating and/or operating on bundles.
28 - */
29 -public class BundleFactory extends JsonFactory {
30 -
31 - private static final String BUNDLE = "bundle";
32 - private static final String BUNDLES = "bundles";
33 - private static final String FUNCTIONS = "functions";
34 -
35 - private static final String BASIC_ID = "basic";
36 - private static final String BASIC_DISPLAY_NAME = "Basic Bundle";
37 - private static final String BASIC_DESCRIPTION =
38 - "If the thing that matters most to you is high speed Internet" +
39 - " connectivity delivered at a great price, then the basic" +
40 - " bundle is right for you.\n" +
41 - "Starting at $30 a month for 12 months.";
42 -
43 - private static final String FAMILY_ID = "family";
44 - private static final String FAMILY_DISPLAY_NAME = "Family Bundle";
45 - private static final String FAMILY_DESCRIPTION =
46 - "Enjoy great entertainment, peace of mind and big savings when " +
47 - "you bundle high speed Internet and Firewall with" +
48 - " Parental Control.\n" +
49 - "Starting at $40 a month for 12 months.";
50 -
51 -
52 - // no instantiation
53 - private BundleFactory() {}
54 -
55 - /**
56 - * Designates the BASIC bundle.
57 - */
58 - public static final BundleDescriptor BASIC_BUNDLE =
59 - new DefaultBundleDescriptor(BASIC_ID, BASIC_DISPLAY_NAME,
60 - BASIC_DESCRIPTION,
61 - XosFunctionDescriptor.INTERNET,
62 - XosFunctionDescriptor.FIREWALL,
63 - XosFunctionDescriptor.CDN);
64 -
65 - /**
66 - * Designates the FAMILY bundle.
67 - */
68 - public static final BundleDescriptor FAMILY_BUNDLE =
69 - new DefaultBundleDescriptor(FAMILY_ID, FAMILY_DISPLAY_NAME,
70 - FAMILY_DESCRIPTION,
71 - XosFunctionDescriptor.INTERNET,
72 - XosFunctionDescriptor.FIREWALL,
73 - XosFunctionDescriptor.CDN,
74 - XosFunctionDescriptor.URL_FILTER);
75 -
76 - // all bundles, in the order they should be listed in the GUI
77 - private static final List<BundleDescriptor> ALL_BUNDLES = ImmutableList.of(
78 - BASIC_BUNDLE,
79 - FAMILY_BUNDLE
80 - );
81 -
82 - /**
83 - * Returns the list of available bundles.
84 - *
85 - * @return available bundles
86 - */
87 - public static List<BundleDescriptor> availableBundles() {
88 - return ALL_BUNDLES;
89 - }
90 -
91 - /**
92 - * Returns the bundle descriptor for the given identifier.
93 - *
94 - * @param bundleId bundle identifier
95 - * @return bundle descriptor
96 - * @throws IllegalArgumentException if bundle ID is unknown
97 - */
98 - public static BundleDescriptor bundleFromId(String bundleId) {
99 - for (BundleDescriptor bd : ALL_BUNDLES) {
100 - if (bd.id().equals(bundleId)) {
101 - return bd;
102 - }
103 - }
104 - throw new IllegalArgumentException("unknown bundle: " + bundleId);
105 - }
106 -
107 - /**
108 - * Returns an object node representation of the given bundle.
109 - * Note that some functions (such as CDN) are not added to the output
110 - * as we don't want them to appear in the GUI.
111 - *
112 - * @param bundle the bundle
113 - * @return object node
114 - */
115 - public static ObjectNode toObjectNode(Bundle bundle) {
116 - ObjectNode root = objectNode();
117 - BundleDescriptor descriptor = bundle.descriptor();
118 -
119 - ObjectNode bnode = objectNode()
120 - .put(ID, descriptor.id())
121 - .put(NAME, descriptor.displayName())
122 - .put(DESC, descriptor.description());
123 -
124 - ArrayNode funcs = arrayNode();
125 - for (XosFunctionDescriptor xfd: bundle.descriptor().functions()) {
126 - if (xfd.visible()) {
127 - funcs.add(XosFunctionFactory.toObjectNode(xfd));
128 - }
129 - }
130 - bnode.set(FUNCTIONS, funcs);
131 - root.set(BUNDLE, bnode);
132 -
133 - ArrayNode bundles = arrayNode();
134 - for (BundleDescriptor bd: BundleFactory.availableBundles()) {
135 - ObjectNode bdnode = objectNode()
136 - .put(ID, bd.id())
137 - .put(NAME, bd.displayName())
138 - .put(DESC, bd.description());
139 - bundles.add(bdnode);
140 - }
141 - root.set(BUNDLES, bundles);
142 - return root;
143 - }
144 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.google.common.collect.ImmutableSet;
21 -
22 -import java.util.Set;
23 -
24 -
25 -/**
26 - * Base implementation of BundleDescriptor.
27 - */
28 -public class DefaultBundleDescriptor implements BundleDescriptor {
29 -
30 - private final String id;
31 - private final String displayName;
32 - private final String description;
33 - private final Set<XosFunctionDescriptor> functions;
34 -
35 - /**
36 - * Constructs a bundle descriptor.
37 - *
38 - * @param id bundle identifier
39 - * @param displayName bundle display name
40 - * @param functions functions that make up this bundle
41 - */
42 - DefaultBundleDescriptor(String id, String displayName, String description,
43 - XosFunctionDescriptor... functions) {
44 - this.id = id;
45 - this.displayName = displayName;
46 - this.description = description;
47 - this.functions = ImmutableSet.copyOf(functions);
48 - }
49 -
50 -
51 - public String id() {
52 - return id;
53 - }
54 -
55 - public String displayName() {
56 - return displayName;
57 - }
58 -
59 - public String description() {
60 - return description;
61 - }
62 -
63 - public Set<XosFunctionDescriptor> functions() {
64 - return functions;
65 - }
66 -
67 - @Override
68 - public String toString() {
69 - return "{BundleDescriptor: " + displayName + "}";
70 - }
71 -
72 - @Override
73 - public boolean equals(Object o) {
74 - if (this == o) {
75 - return true;
76 - }
77 - if (o == null || getClass() != o.getClass()) {
78 - return false;
79 - }
80 -
81 - DefaultBundleDescriptor that = (DefaultBundleDescriptor) o;
82 - return id.equals(that.id);
83 - }
84 -
85 - @Override
86 - public int hashCode() {
87 - return id.hashCode();
88 - }
89 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.fasterxml.jackson.databind.ObjectMapper;
21 -
22 -/**
23 - * Default XOS function implementation, that does not have any parameters
24 - * to tweak.
25 - */
26 -public class DefaultXosFunction implements XosFunction {
27 -
28 - protected static final ObjectMapper MAPPER = new ObjectMapper();
29 -
30 - private final XosFunctionDescriptor xfd;
31 -
32 - public DefaultXosFunction(XosFunctionDescriptor xfd) {
33 - this.xfd = xfd;
34 - }
35 -
36 - public XosFunctionDescriptor descriptor() {
37 - return xfd;
38 - }
39 -
40 - /**
41 - * {@inheritDoc}
42 - * <p>
43 - * This default implementation throws an exception.
44 - *
45 - * @param user user to apply the change to
46 - * @param param parameter name
47 - * @param value new parameter value
48 - * @throws UnsupportedOperationException if invoked
49 - */
50 - public void applyParam(SubscriberUser user, String param, String value) {
51 - throw new UnsupportedOperationException();
52 - }
53 -
54 - public Memento createMemento() {
55 - return null;
56 - }
57 -
58 - public String xosUrlApply(SubscriberUser user) {
59 - return null;
60 - }
61 -
62 - @Override
63 - public String toString() {
64 - return "{XosFunction: " + xfd + "}";
65 - }
66 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.fasterxml.jackson.databind.ObjectMapper;
21 -import com.fasterxml.jackson.databind.node.ArrayNode;
22 -import com.fasterxml.jackson.databind.node.ObjectNode;
23 -
24 -/**
25 - * Base class for factories that convert objects to JSON.
26 - */
27 -public abstract class JsonFactory {
28 -
29 - private static final ObjectMapper MAPPER = new ObjectMapper();
30 -
31 - protected static final String ID = "id";
32 - protected static final String NAME = "name";
33 - protected static final String DESC = "desc";
34 - protected static final String ICON_ID = "icon_id";
35 -
36 - /**
37 - * Returns a freshly minted object node.
38 - *
39 - * @return empty object node
40 - */
41 - protected static ObjectNode objectNode() {
42 - return MAPPER.createObjectNode();
43 - }
44 -
45 - /**
46 - * Returns a freshly minted array node.
47 - *
48 - * @return empty array node
49 - */
50 - protected static ArrayNode arrayNode() {
51 - return MAPPER.createArrayNode();
52 - }
53 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import java.util.HashMap;
21 -import java.util.Map;
22 -
23 -/**
24 - * Designates a user of a subscriber's account.
25 - */
26 -public class SubscriberUser {
27 - private final int id;
28 - private final String name;
29 - private final String mac;
30 -
31 - // this is "duplicated" in the URL_FILTER memento, but, oh well...
32 - // -- the level, as returned from XOS, when we create this user object.
33 - private String level;
34 -
35 - private final Map<XosFunctionDescriptor, XosFunction.Memento> mementos =
36 - new HashMap<XosFunctionDescriptor, XosFunction.Memento>();
37 -
38 - /**
39 - * Constructs a subscriber user from the given parameters.
40 - *
41 - * @param id internal identifier
42 - * @param name display name
43 - * @param mac MAC address of the associated device
44 - * @param level URL filter level
45 - */
46 - public SubscriberUser(int id, String name, String mac, String level) {
47 - this.id = id;
48 - this.name = name;
49 - this.mac = mac;
50 - this.level = level;
51 - }
52 -
53 - /**
54 - * Returns the internal identifier.
55 - *
56 - * @return the identifier
57 - */
58 - public int id() {
59 - return id;
60 - }
61 -
62 - /**
63 - * Returns the display name.
64 - *
65 - * @return display name
66 - */
67 - public String name() {
68 - return name;
69 - }
70 -
71 - /**
72 - * Returns the MAC address of the associated device.
73 - *
74 - * @return MAC address
75 - */
76 - public String mac() {
77 - return mac;
78 - }
79 -
80 - /**
81 - * Returns the URL filter level.
82 - *
83 - * @return URL filter level
84 - */
85 - public String urlFilterLevel() {
86 - return level;
87 - }
88 -
89 - /**
90 - * Sets the URL filter level.
91 - *
92 - * @param level URL filter level
93 - */
94 - public void setUrlFilterLevel(String level) {
95 - this.level = level;
96 - }
97 -
98 - /**
99 - * Stores a memento for the given XOS function.
100 - *
101 - * @param f XOS function
102 - * @param m memento
103 - */
104 - public void setMemento(XosFunctionDescriptor f, XosFunction.Memento m) {
105 - if (m != null) {
106 - mementos.put(f, m);
107 - }
108 - }
109 -
110 - /**
111 - * Returns the memento stored on this user, for the given XOS function.
112 - *
113 - * @param f XOS function
114 - * @return memento
115 - */
116 - public XosFunction.Memento getMemento(XosFunctionDescriptor f) {
117 - return mementos.get(f);
118 - }
119 -
120 - /**
121 - * Clears the memento map.
122 - */
123 - public void clearMementos() {
124 - mementos.clear();
125 - }
126 -
127 - @Override
128 - public String toString() {
129 - return "{User: " + name + "}";
130 - }
131 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.fasterxml.jackson.databind.node.ObjectNode;
21 -
22 -import static com.google.common.base.Preconditions.checkNotNull;
23 -
24 -/**
25 - * Specialization of XosFunction for URL filtering.
26 - */
27 -public class UrlFilterFunction extends DefaultXosFunction {
28 -
29 - private static final String LEVEL = "level";
30 - private static final String URI_PATTERN = "%s/%s/";
31 -
32 - /**
33 - * Denotes the URL filtering levels available. From most restrictive
34 - * to least restrictive. Note: <em>NONE</em> allows nothing;
35 - * <em>ALL</em> allows everything.
36 - */
37 - public enum Level { NONE, G, PG, PG_13, R, ALL }
38 -
39 - /**
40 - * The default URL filtering level
41 - */
42 - public static final Level DEFAULT_LEVEL = Level.G;
43 -
44 - public UrlFilterFunction() {
45 - super(XosFunctionDescriptor.URL_FILTER);
46 - }
47 -
48 - @Override
49 - public void applyParam(SubscriberUser user, String param, String value) {
50 - Memento memo = user.getMemento(descriptor());
51 - checkNotNull(memo, "missing memento for " + descriptor());
52 - UrlFilterMemento ufMemo = (UrlFilterMemento) memo;
53 -
54 - if (LEVEL.equals(param)) {
55 - Level newLevel = Level.valueOf(value.toUpperCase());
56 - ufMemo.setLevel(newLevel);
57 -
58 - // Also store the (string version) of the level
59 - // (not in the memento). Hackish, but that's how it is for now.
60 - user.setUrlFilterLevel(value);
61 - }
62 - }
63 -
64 - @Override
65 - public Memento createMemento() {
66 - return new UrlFilterMemento();
67 - }
68 -
69 - class UrlFilterMemento implements Memento {
70 - private Level level = DEFAULT_LEVEL;
71 -
72 - public ObjectNode toObjectNode() {
73 - ObjectNode node = MAPPER.createObjectNode();
74 - node.put(LEVEL, level.name());
75 - return node;
76 - }
77 -
78 - public void setLevel(Level level) {
79 - this.level = level;
80 - }
81 -
82 - public String level() {
83 - return level.toString();
84 - }
85 - }
86 -
87 - @Override
88 - public String xosUrlApply(SubscriberUser user) {
89 - XosFunctionDescriptor xfd = XosFunctionDescriptor.URL_FILTER;
90 - UrlFilterMemento memo = (UrlFilterMemento) user.getMemento(xfd);
91 - return String.format(URI_PATTERN, xfd.id(), memo.level());
92 - }
93 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import com.fasterxml.jackson.databind.node.ObjectNode;
21 -
22 -import java.util.HashMap;
23 -import java.util.Map;
24 -
25 -/**
26 - * Utility functions on users.
27 - */
28 -public class UserFactory extends JsonFactory {
29 -
30 - private static final String MAC = "mac";
31 - private static final String PROFILE = "profile";
32 -
33 -
34 - // hard-coded icons for the demo
35 - private static final Map<String, String> ICON_LOOKUP =
36 - new HashMap<String, String>();
37 - static {
38 - ICON_LOOKUP.put("Mom's PC", "mom");
39 - ICON_LOOKUP.put("Dad's PC", "dad");
40 - ICON_LOOKUP.put("Jack's Laptop", "boy2");
41 - ICON_LOOKUP.put("Jill's Laptop", "girl1");
42 - }
43 -
44 - private static final String DEFAULT_ICON_ID = "boy1";
45 -
46 - // no instantiation
47 - private UserFactory() {}
48 -
49 - /**
50 - * Returns an object node representation of the given user.
51 - *
52 - * @param user the user
53 - * @return object node
54 - */
55 - public static ObjectNode toObjectNode(SubscriberUser user) {
56 - String icon = ICON_LOOKUP.get(user.name());
57 - icon = icon == null ? DEFAULT_ICON_ID : icon;
58 -
59 - ObjectNode root = objectNode()
60 - .put(ID, user.id())
61 - .put(ICON_ID, icon)
62 - .put(NAME, user.name())
63 - .put(MAC, user.mac());
64 - root.set(PROFILE, XosFunctionFactory.profileForUser(user));
65 - return root;
66 - }
67 -
68 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 -
23 -/**
24 - * Designates a specific instance of an XOS function.
25 - */
26 -public interface XosFunction {
27 -
28 - /**
29 - * Returns the descriptor for this function.
30 - *
31 - * @return function descriptor
32 - */
33 - XosFunctionDescriptor descriptor();
34 -
35 - /**
36 - * Applies a parameter change for the given user.
37 - *
38 - * @param user user to apply change to
39 - * @param param parameter name
40 - * @param value new parameter value
41 - */
42 - void applyParam(SubscriberUser user, String param, String value);
43 -
44 - /**
45 - * Create an initialized memento.
46 - * If the function maintains no state per user, return null.
47 - *
48 - * @return a new memento
49 - */
50 - Memento createMemento();
51 -
52 - /**
53 - * Create the XOS specific URL suffix for applying state change for
54 - * the given user.
55 - *
56 - * @param user the user
57 - * @return URL suffix
58 - */
59 - String xosUrlApply(SubscriberUser user);
60 -
61 - /**
62 - * Internal state memento.
63 - */
64 - interface Memento {
65 - /**
66 - * Returns a JSON representation of this memento.
67 - *
68 - * @return memento state as object node
69 - */
70 - ObjectNode toObjectNode();
71 - }
72 -}
73 -
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -/**
21 - * Designates XOS Functions.
22 - */
23 -public enum XosFunctionDescriptor {
24 - /**
25 - * Internet function.
26 - */
27 - INTERNET("internet",
28 - "Internet",
29 - "Discover the joys of high-speed, reliable Internet" +
30 - " connectivity delivered seamlessly to your home.",
31 - false,
32 - true),
33 -
34 - /**
35 - * Firewall function.
36 - */
37 - FIREWALL("firewall",
38 - "Firewall",
39 - "Simple access control and filtering with minimal set-up.",
40 - true,
41 - true),
42 -
43 - /**
44 - * URL Filtering function (parental controls).
45 - */
46 - URL_FILTER("url_filter",
47 - "Parental Control",
48 - "Parental Control is peace of mind that your kids are safe" +
49 - " - whether you are around or away. Indicate with a " +
50 - "few clicks what online content is appropriate for " +
51 - "your children, and voila - you have control over" +
52 - " what your kids can and cannot view.",
53 - true,
54 - true),
55 -
56 - /**
57 - * Content Distribution function.
58 - */
59 - CDN("cdn",
60 - "CDN",
61 - "Content Distribution Network service.",
62 - true,
63 - false);
64 -
65 -
66 - private final String id;
67 - private final String displayName;
68 - private final String description;
69 - private final boolean backend;
70 - private final boolean visible;
71 -
72 - XosFunctionDescriptor(String id, String displayName, String description,
73 - boolean backend, boolean visible) {
74 - this.id = id;
75 - this.displayName = displayName;
76 - this.description = description;
77 - this.backend = backend;
78 - this.visible = visible;
79 - }
80 -
81 - /**
82 - * Returns this function's internal identifier.
83 - *
84 - * @return the identifier
85 - */
86 - public String id() {
87 - return id;
88 - }
89 -
90 - /**
91 - * Returns this function's display name.
92 - *
93 - * @return display name
94 - */
95 - public String displayName() {
96 - return displayName;
97 - }
98 -
99 - /**
100 - * Returns a short, textual description of the function.
101 - *
102 - * @return textual description
103 - */
104 - public String description() {
105 - return description;
106 - }
107 -
108 - /**
109 - * Returns true if this function is supported by the XOS backend.
110 - *
111 - * @return true if backend function exists
112 - */
113 - public boolean backend() {
114 - return backend;
115 - }
116 -
117 - /**
118 - * Returns true if this function should be shown in the GUI, in the
119 - * bundle listing.
120 - *
121 - * @return true if to be displayed
122 - */
123 - public boolean visible() {
124 - return visible;
125 - }
126 -}
1 -/*
2 - * Copyright 2015-present 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 - */
16 -package org.onosproject.cord.gui.model;
17 -
18 -import com.fasterxml.jackson.databind.node.ArrayNode;
19 -import com.fasterxml.jackson.databind.node.ObjectNode;
20 -
21 -import java.util.HashMap;
22 -import java.util.Map;
23 -
24 -import static org.onosproject.cord.gui.model.XosFunctionDescriptor.URL_FILTER;
25 -
26 -/**
27 - * Utility factory for operating on XOS functions.
28 - */
29 -public class XosFunctionFactory extends JsonFactory {
30 -
31 - private static final String PARAMS = "params";
32 - private static final String LEVEL = "level";
33 - private static final String LEVELS = "levels";
34 -
35 -
36 - // no instantiation
37 - private XosFunctionFactory() {}
38 -
39 - /**
40 - * Produces the JSON representation of the given XOS function descriptor.
41 - *
42 - * @param xfd function descriptor
43 - * @return JSON encoding
44 - */
45 - public static ObjectNode toObjectNode(XosFunctionDescriptor xfd) {
46 - ObjectNode root = objectNode()
47 - .put(ID, xfd.id())
48 - .put(NAME, xfd.displayName())
49 - .put(DESC, xfd.description());
50 - root.set(PARAMS, paramsForXfd(xfd));
51 - return root;
52 - }
53 -
54 - private static ObjectNode paramsForXfd(XosFunctionDescriptor xfd) {
55 - ParamsFactory psf = PARAM_MAP.get(xfd);
56 - if (psf == null) {
57 - psf = DEF_PARAMS_FACTORY;
58 - }
59 - return psf.params();
60 - }
61 -
62 -
63 - // ==== handling different parameter structures...
64 - private static final Map<XosFunctionDescriptor, ParamsFactory>
65 - PARAM_MAP = new HashMap<XosFunctionDescriptor, ParamsFactory>();
66 -
67 - private static final ParamsFactory DEF_PARAMS_FACTORY = new ParamsFactory();
68 - static {
69 - PARAM_MAP.put(URL_FILTER, new UrlFilterParamsFactory());
70 - }
71 -
72 - /**
73 - * Creates an object node representation of the profile for the
74 - * specified user.
75 - *
76 - * @param user the user
77 - * @return object node profile
78 - */
79 - public static ObjectNode profileForUser(SubscriberUser user) {
80 - ObjectNode root = objectNode();
81 - for (XosFunctionDescriptor xfd: XosFunctionDescriptor.values()) {
82 - XosFunction.Memento mem = user.getMemento(xfd);
83 - if (mem != null) {
84 - root.set(xfd.id(), mem.toObjectNode());
85 - }
86 - }
87 - return root;
88 - }
89 -
90 -
91 - // ===================================================================
92 - // === factories for creating parameter structures, both default
93 - // and from a memento...
94 -
95 - // private parameter structure creator
96 - static class ParamsFactory {
97 - ObjectNode params() {
98 - return objectNode();
99 - }
100 - }
101 -
102 - static class UrlFilterParamsFactory extends ParamsFactory {
103 - @Override
104 - ObjectNode params() {
105 - ObjectNode result = objectNode();
106 - result.put(LEVEL, UrlFilterFunction.DEFAULT_LEVEL.name());
107 - ArrayNode levels = arrayNode();
108 - for (UrlFilterFunction.Level lvl: UrlFilterFunction.Level.values()) {
109 - levels.add(lvl.name());
110 - }
111 - result.set(LEVELS, levels);
112 - return result;
113 - }
114 - }
115 -}
1 -{
2 - "bundle": {
3 - "id": "basic",
4 - "name": "Basic Bundle",
5 - "functions": [
6 - {
7 - "id": "internet",
8 - "name": "Internet",
9 - "desc": "Basic internet connectivity.",
10 - "params": {}
11 - },
12 - {
13 - "id": "firewall",
14 - "name": "Firewall",
15 - "desc": "Normal firewall protection.",
16 - "params": {}
17 - }
18 - ]
19 - },
20 - "bundles": [
21 - { "id": "basic", "name": "Basic Bundle" },
22 - { "id": "family", "name": "Family Bundle" }
23 - ]
24 -}
1 -{
2 - "bundle": {
3 - "id": "family",
4 - "name": "Family Bundle",
5 - "functions": [
6 - {
7 - "id": "internet",
8 - "name": "Internet",
9 - "desc": "Basic internet connectivity.",
10 - "params": {}
11 - },
12 - {
13 - "id": "firewall",
14 - "name": "Firewall",
15 - "desc": "Normal firewall protection.",
16 - "params": {}
17 - },
18 - {
19 - "id": "url_filter",
20 - "name": "Parental Control",
21 - "desc": "Variable levels of URL filtering.",
22 - "params": {
23 - "level": "PG",
24 - "levels": [ "PG", "PG-13", "R" ]
25 - }
26 - }
27 - ]
28 - },
29 - "bundles": [
30 - { "id": "basic", "name": "Basic Bundle" },
31 - { "id": "family", "name": "Family Bundle" }
32 - ]
33 -}
1 -{
2 - "bundle": "Basic Bundle",
3 - "users": [
4 - { "id": 1, "name": "Mom's MacBook", "mac": "00:11:22:33:44:55" },
5 - { "id": 1, "name": "Dad's iPad", "mac": "00:11:22:33:44:66" },
6 - { "id": 1, "name": "Dick's laptop", "mac": "00:11:22:33:44:77" },
7 - { "id": 1, "name": "Jane's laptop", "mac": "00:11:22:33:44:88" }
8 - ]
9 -}
1 -{
2 - "bundle": "Family Bundle",
3 - "users": [
4 - { "id": 1, "name": "Mom's MacBook", "mac": "00:11:22:33:44:55" },
5 - { "id": 1, "name": "Dad's iPad", "mac": "00:11:22:33:44:66" },
6 - { "id": 1, "name": "Dick's laptop", "mac": "00:11:22:33:44:77" },
7 - { "id": 1, "name": "Jane's laptop", "mac": "00:11:22:33:44:88" }
8 - ]
9 -}
1 -{
2 - "users": [
3 - {
4 - "id": 1,
5 - "name": "Mom's MacBook",
6 - "mac": "01:02:03:04:05:06",
7 - "profile": { }
8 - },
9 - {
10 - "id": 2,
11 - "name": "Dad's iPad",
12 - "mac": "01:02:03:04:05:77",
13 - "profile": { }
14 - },
15 - {
16 - "id": 3,
17 - "name": "Dick's laptop",
18 - "mac": "01:02:03:04:05:88",
19 - "profile": { }
20 - },
21 - {
22 - "id": 4,
23 - "name": "Jane's laptop",
24 - "mac": "01:02:03:04:05:99",
25 - "profile": { }
26 - }
27 - ]
28 -}
1 -{
2 - "users": [
3 - {
4 - "id": 1,
5 - "name": "Mom's MacBook",
6 - "mac": "010203040506",
7 - "profile": {
8 - "url_filter": {
9 - "level": "R"
10 - }
11 - }
12 - },
13 - {
14 - "id": 2,
15 - "name": "Dad's iPad",
16 - "mac": "010203040507",
17 - "profile": {
18 - "url_filter": {
19 - "level": "R"
20 - }
21 - }
22 - },
23 - {
24 - "id": 3,
25 - "name": "Dick's laptop",
26 - "mac": "010203040508",
27 - "profile": {
28 - "url_filter": {
29 - "level": "PG_13"
30 - }
31 - }
32 - },
33 - {
34 - "id": 4,
35 - "name": "Jane's laptop",
36 - "mac": "010203040509",
37 - "profile": {
38 - "url_filter": {
39 - "level": "PG"
40 - }
41 - }
42 - }
43 - ]
44 -}
1 -{
2 - "comment": [
3 - "This is a sample JSON File",
4 - "Which can contain fake data."
5 - ],
6 - "fake": true,
7 - "numbers": [ 1, 2, 3 ],
8 - "map": {
9 - "x": 100,
10 - "y": 200,
11 - "z": 32
12 - }
13 -}
1 -{
2 - "users": [
3 - {
4 - "id": 1,
5 - "name": "Mom's MacBook",
6 - "mac": "01:02:03:04:05:06"
7 - },
8 - {
9 - "id": 2,
10 - "name": "Dad's iPad",
11 - "mac": "01:02:03:04:05:77"
12 - },
13 - {
14 - "id": 3,
15 - "name": "Dick's laptop",
16 - "mac": "01:02:03:04:05:88"
17 - },
18 - {
19 - "id": 4,
20 - "name": "Jane's laptop",
21 - "mac": "01:02:03:04:05:99"
22 - }
23 - ]
24 -}
1 -{
2 - "humanReadableName": "vOLT on service 16",
3 - "id": 1,
4 - "service_specific_id": "",
5 - "vlan_id": null,
6 - "vcpe_id": 2,
7 - "sliver": 384,
8 - "sliver_name": "onlab_vcpe",
9 - "image": 29,
10 - "image_name": "Ubuntu 14.04 LTS",
11 - "firewall_enable": true,
12 - "firewall_rules": "accept all anywhere anywhere",
13 - "url_filter_enable": true,
14 - "url_filter_rules": "allow all",
15 - "url_filter_level": "PG",
16 - "cdn_enable": true,
17 - "vbng_id": 4,
18 - "routeable_subnet": "1.1.1.1/4"
19 -}
1 -{
2 - "users": [
3 - {
4 - "mac": "010203040506",
5 - "name": "Moms laptop",
6 - "id": 0
7 - },
8 - {
9 - "mac": "010203040507",
10 - "name": "Dads desktop",
11 - "id": 1
12 - },
13 - {
14 - "id": 2,
15 - "mac": "010203040507",
16 - "name": "Jacks iPad",
17 - "level": "PG"
18 - },
19 - {
20 - "mac": "010203040508",
21 - "name": "Jills iPad",
22 - "id": 3
23 - }
24 - ]
25 -}
1 -{
2 - "users": [
3 - {
4 - "mac": "010203040506",
5 - "name": "Moms laptop",
6 - "id": 0
7 - },
8 - {
9 - "mac": "010203040507",
10 - "name": "Dads desktop",
11 - "id": 1
12 - },
13 - {
14 - "mac": "010203040507",
15 - "name": "Jacks iPad",
16 - "id": 2
17 - },
18 - {
19 - "mac": "010203040508",
20 - "name": "Jills iPad",
21 - "id": 3
22 - }
23 - ]
24 -}
1 -{
2 - "humanReadableName": "vOLT on service 1",
3 - "id": 92,
4 - "service_specific_id": "33445573",
5 - "vlan_id": "77889908",
6 - "vcpe_id": 93,
7 - "sliver": 108,
8 - "sliver_name": "mysite_vcpe",
9 - "image": 1,
10 - "image_name": "Ubuntu-14.04-LTS",
11 - "firewall_enable": false,
12 - "firewall_rules": "accept all anywhere anywhere",
13 - "url_filter_enable": false,
14 - "url_filter_rules": "allow all",
15 - "url_filter_level": "R",
16 - "cdn_enable": false,
17 - "vbng_id": 94,
18 - "routeable_subnet": "",
19 - "nat_ip": "172.16.0.106",
20 - "lan_ip": "12.0.0.16",
21 - "wan_ip": "11.0.0.16",
22 - "private_ip": "10.0.6.43"
23 -}
1 -{
2 - "subscribers": [
3 - {
4 - "humanReadableName": "vOLT on service 1",
5 - "id": 92,
6 - "service_specific_id": "33445573",
7 - "vlan_id": "77889908",
8 - "vcpe_id": 93,
9 - "sliver": 108,
10 - "sliver_name": "mysite_vcpe",
11 - "image": 1,
12 - "image_name": "Ubuntu-14.04-LTS",
13 - "firewall_enable": false,
14 - "firewall_rules": "accept all anywhere anywhere",
15 - "url_filter_enable": false,
16 - "url_filter_rules": "allow all",
17 - "url_filter_level": "R",
18 - "cdn_enable": false,
19 - "vbng_id": 94,
20 - "routeable_subnet": "",
21 - "nat_ip": "172.16.0.106",
22 - "lan_ip": "12.0.0.16",
23 - "wan_ip": "11.0.0.16",
24 - "private_ip": "10.0.6.43"
25 - },
26 - {
27 - "humanReadableName": "vOLT on service 1",
28 - "id": 138,
29 - "service_specific_id": "",
30 - "vlan_id": "100",
31 - "vcpe_id": 139,
32 - "sliver": 106,
33 - "sliver_name": "mysite_vcpe",
34 - "image": 1,
35 - "image_name": "Ubuntu-14.04-LTS",
36 - "firewall_enable": false,
37 - "firewall_rules": "accept all anywhere anywhere",
38 - "url_filter_enable": false,
39 - "url_filter_rules": "allow all",
40 - "url_filter_level": "PG",
41 - "cdn_enable": false,
42 - "vbng_id": 140,
43 - "routeable_subnet": "",
44 - "nat_ip": "172.16.0.104",
45 - "lan_ip": "12.0.0.14",
46 - "wan_ip": "11.0.0.14",
47 - "private_ip": "10.0.6.41"
48 - },
49 - {
50 - "humanReadableName": "vOLT on service 1",
51 - "id": 154,
52 - "service_specific_id": "98765",
53 - "vlan_id": "99",
54 - "vcpe_id": 155,
55 - "sliver": 117,
56 - "sliver_name": "mysite_vcpe",
57 - "image": 1,
58 - "image_name": "Ubuntu-14.04-LTS",
59 - "firewall_enable": false,
60 - "firewall_rules": "accept all anywhere anywhere",
61 - "url_filter_enable": false,
62 - "url_filter_rules": "allow all",
63 - "url_filter_level": "PG",
64 - "cdn_enable": false,
65 - "vbng_id": 156,
66 - "routeable_subnet": "",
67 - "nat_ip": "172.16.0.114",
68 - "lan_ip": "12.0.0.24",
69 - "wan_ip": "11.0.0.24",
70 - "private_ip": "10.0.6.48"
71 - },
72 - {
73 - "humanReadableName": "vOLT on service 1",
74 - "id": 157,
75 - "service_specific_id": "5678",
76 - "vlan_id": "999",
77 - "vcpe_id": 158,
78 - "sliver": 118,
79 - "sliver_name": "mysite_vcpe",
80 - "image": 1,
81 - "image_name": "Ubuntu-14.04-LTS",
82 - "firewall_enable": false,
83 - "firewall_rules": "accept all anywhere anywhere",
84 - "url_filter_enable": false,
85 - "url_filter_rules": "allow all",
86 - "url_filter_level": "PG",
87 - "cdn_enable": false,
88 - "vbng_id": 159,
89 - "routeable_subnet": "",
90 - "nat_ip": "172.16.0.119",
91 - "lan_ip": "12.0.0.29",
92 - "wan_ip": "11.0.0.29",
93 - "private_ip": "10.0.6.53"
94 - },
95 - {
96 - "humanReadableName": "vOLT on service 1",
97 - "id": 160,
98 - "service_specific_id": "1",
99 - "vlan_id": "100",
100 - "vcpe_id": 161,
101 - "sliver": 119,
102 - "sliver_name": "mysite_vcpe",
103 - "image": 1,
104 - "image_name": "Ubuntu-14.04-LTS",
105 - "firewall_enable": false,
106 - "firewall_rules": "accept all anywhere anywhere",
107 - "url_filter_enable": false,
108 - "url_filter_rules": "allow all",
109 - "url_filter_level": "PG",
110 - "cdn_enable": false,
111 - "vbng_id": 162,
112 - "routeable_subnet": "",
113 - "nat_ip": "172.16.0.120",
114 - "lan_ip": "12.0.0.30",
115 - "wan_ip": "11.0.0.30",
116 - "private_ip": "10.0.6.54"
117 - },
118 - {
119 - "humanReadableName": "vOLT on service 1",
120 - "id": 163,
121 - "service_specific_id": "101",
122 - "vlan_id": "101",
123 - "vcpe_id": 164,
124 - "sliver": 120,
125 - "sliver_name": "mysite_vcpe",
126 - "image": 1,
127 - "image_name": "Ubuntu-14.04-LTS",
128 - "firewall_enable": false,
129 - "firewall_rules": "accept all anywhere anywhere",
130 - "url_filter_enable": false,
131 - "url_filter_rules": "allow all",
132 - "url_filter_level": "PG",
133 - "cdn_enable": false,
134 - "vbng_id": 165,
135 - "routeable_subnet": "",
136 - "nat_ip": "172.16.0.121",
137 - "lan_ip": "12.0.0.31",
138 - "wan_ip": "11.0.0.31",
139 - "private_ip": "10.0.6.55"
140 - }
141 - ]
142 -}
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!--
3 - ~ Copyright 2015-present Open Networking Laboratory
4 - ~
5 - ~ Licensed under the Apache License, Version 2.0 (the "License");
6 - ~ you may not use this file except in compliance with the License.
7 - ~ You may obtain a copy of the License at
8 - ~
9 - ~ http://www.apache.org/licenses/LICENSE-2.0
10 - ~
11 - ~ Unless required by applicable law or agreed to in writing, software
12 - ~ distributed under the License is distributed on an "AS IS" BASIS,
13 - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 - ~ See the License for the specific language governing permissions and
15 - ~ limitations under the License.
16 - -->
17 -<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
18 - xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 - id="ONOS" version="2.5">
21 - <display-name>CORD Subscriber Web GUI</display-name>
22 -
23 - <servlet>
24 - <servlet-name>JAX-RS Service</servlet-name>
25 - <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
26 - <init-param>
27 - <param-name>jersey.config.server.provider.classnames</param-name>
28 - <param-value>
29 - org.onosproject.cord.gui.CordWebResource
30 - </param-value>
31 - </init-param>
32 - <load-on-startup>1</load-on-startup>
33 - </servlet>
34 -
35 - <servlet-mapping>
36 - <servlet-name>JAX-RS Service</servlet-name>
37 - <url-pattern>/rs/*</url-pattern>
38 - </servlet-mapping>
39 -
40 -</web-app>
1 -{
2 - "_comment_": "Parental Control Categories - data file",
3 -
4 - "level_order": [
5 - "NONE", "G", "PG", "PG_13", "R", "ALL"
6 - ],
7 -
8 - "category_order": [
9 - "Safe", "Search", "Shopping", "Sports", "Privacy", "Dating", "Games",
10 - "Social", "Illegal", "Weapons", "Drugs", "Gambling", "Cyberbully",
11 - "Pornography", "Adult", "Anonymizers", "Suicide", "Malware"
12 - ],
13 -
14 - "descriptions": {
15 - "Safe": [
16 - "."
17 - ],
18 - "Search": [
19 - "Sites which provide the ability to perform searches for specific ",
20 - "topics or websites across the entire Internet, and which display ",
21 - "results in a multi-page format that allows material to be sorted ",
22 - "based on content, topic, or file type."
23 - ],
24 - "Shopping": [
25 - "."
26 - ],
27 - "Sports": [
28 - "Sites which analyze, promote, or providing information about ",
29 - "competitive sports and its fans whether official or unofficial."
30 - ],
31 - "Privacy": [
32 - "Sites which provide hosted online advertising intended to attract ",
33 - "web traffic, deliver marketing messages or capture email addresses."
34 - ],
35 - "Dating": [
36 - "Sites which promote or provide the opportunity for establishing ",
37 - "romantic relationship."
38 - ],
39 - "Games": [
40 - "Sites which related to the development, promotion, review, and ",
41 - "enjoyment of online, PC, and console videogaming."
42 - ],
43 - "Social": [
44 - "Sites which facilitate online socializing and the development or ",
45 - "maintenance of personal and professional relationships across ",
46 - "geographical and organizational boundaries."
47 - ],
48 - "Illegal": [
49 - "Sites which promote or provide the means to practice illegal or ",
50 - "unauthorized acts using computer-programming skills. And sites ",
51 - "which offer custom academic writing services for free or for ",
52 - "purchase. These sites are geared toward students who do not want ",
53 - "to write their own papers, but will download or buy previously ",
54 - "written or custom written papers."
55 - ],
56 - "Weapons": [
57 - "Sites which sell, manufacture, or describe the manufacture of weapons."
58 - ],
59 - "Drugs": [
60 - "Sites which promote, offer, sell, supply, encourage or otherwise ",
61 - "advocate the recreational or illegal use, cultivation, manufacture, ",
62 - "or distribution of drugs, pharmaceuticals, intoxicating plants or ",
63 - "chemicals and their related paraphernalia. And sites which glamorize, ",
64 - "glorify, tout or otherwise encourage the consumption of alcohol. And ",
65 - "sites which sell, glamorize, enable or encourage the use of tobacco ",
66 - "and tobacco-related products."
67 - ],
68 - "Gambling": [
69 - "."
70 - ],
71 - "Cyberbully": [
72 - "Sites or pages where people post targeted, deliberate and slanderous ",
73 - "or offensive content about other people with the INTENT to torment, ",
74 - "threaten, humiliate or defame them. Content is often sexual, ",
75 - "malicious or hostile in nature and is submitted via interactive ",
76 - "digital technology. And sites which advocate hostility, aggression ",
77 - "and the denigration of an individual or group on the basis of race, ",
78 - "religion, gender, nationality, ethnic origin, or other involuntary ",
79 - "characteristics. Sites that use purported scientific or commonly ",
80 - "accredited methods to justify inequality, aggression, and hostility."
81 - ],
82 - "Pornography": [
83 - "Sites which contain explicit material for the purpose of causing ",
84 - "sexual excitement or arousing lascivious interest."
85 - ],
86 - "Adult": [
87 - "Sites which contain sexually explicit information that is not ",
88 - "medical or scientific nature and yet are also not pornographic. ",
89 - "And sites which feature social or family nudism/naturism, nudist ",
90 - "camps/resorts, or „nudist-only‟ travel."
91 - ],
92 - "Anonymizers": [
93 - "Sites which provide anonymous access to websites through a PHP or ",
94 - "CGI proxy, allowing users to gain access to websites blocked by ",
95 - "corporate and school proxies as well as parental control filtering ",
96 - "solutions."
97 - ],
98 - "Suicide": [
99 - "Sites which advocate, normalize, or glamourize repetitive and ",
100 - "deliberate ways to inflict non-fatal harm to oneself. And sites ",
101 - "advocating or glorifying suicide as well as educating people on how ",
102 - "to commit suicide."
103 - ],
104 - "Malware": [
105 - "Sites where the domain was found to either contain malware or take ",
106 - "advantage of other exploits to deliver adware, spyware or malware. ",
107 - "And Sites that contain direct links to malware file downloads: ",
108 - ".exe, .dll, .ocx, and others. These URLs are generally highly malicious."
109 - ]
110 - },
111 -
112 - "_prohibited_comment_": [
113 - "Note: Level NONE allows nothing (prohibits everything)",
114 - " level ALL allows everything (prohibits nothing)",
115 - " Levels G, PG, PG_13, R prohibitions listed below:"
116 - ],
117 -
118 - "prohibited": {
119 - "G": [
120 - "Games", "Social", "Illegal", "Weapons", "Drugs", "Gambling",
121 - "Cyberbully", "Pornography", "Adult", "Anonymizers", "Suicide", "Malware"
122 - ],
123 - "PG": [
124 - "Social", "Illegal", "Weapons", "Drugs", "Gambling",
125 - "Cyberbully", "Pornography", "Adult", "Anonymizers", "Suicide", "Malware"
126 - ],
127 - "PG_13": [
128 - "Illegal", "Weapons", "Drugs", "Gambling",
129 - "Cyberbully", "Pornography", "Adult", "Anonymizers", "Suicide", "Malware"
130 - ],
131 - "R": [
132 - "Pornography", "Adult", "Anonymizers", "Suicide", "Malware"
133 - ]
134 - }
135 -}
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -div.foot {
18 - width: 100%;
19 - height: 30px;
20 - background-color: white;
21 - position: absolute;
22 - left: 0;
23 - right: 0;
24 - bottom: 0;
25 - margin-left: auto;
26 - margin-right: auto;
27 - z-index: 100;
28 - box-shadow: 0 10px 5px 10px gray;
29 -}
30 -
31 -.foot div {
32 - position: absolute;
33 - top: 50%;
34 - transform: translate(0, -50%);
35 - font-style: italic;
36 - font-size: 12px;
37 - color: #3C3C3C;
38 -}
39 -
40 -.foot div.left {
41 - left: 25px;
42 -}
43 -
44 -.foot div.right {
45 - right: 25px;
46 -}
1 -<!--Foot partial html-->
2 -<div class="foot">
3 - <div class="left">
4 -
5 - </div>
6 -
7 - <div class="right">
8 - © ONOS Project. All rights reserved.
9 - </div>
10 -</div>
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -angular.module('cordFoot', [])
18 - .directive('foot', function () {
19 - return {
20 - restrict: 'E',
21 - templateUrl: 'app/fw/foot/foot.html'
22 - };
23 - });
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - angular.module('cordGui')
21 -
22 - .directive('icon', [function () {
23 - return {
24 - restrict: 'E',
25 - compile: function (element, attrs) {
26 - var html =
27 - '<svg class="embedded-icon" width="' + attrs.size + '" ' +
28 - 'height="' + attrs.size + '" viewBox="0 0 50 50">' +
29 - '<g class="icon">' +
30 - '<circle cx="25" cy="25" r="25"></circle>' +
31 - '<use width="50" height="50" class="glyph '
32 - + attrs.id + '" xlink:href="#' + attrs.id +
33 - '"></use>' +
34 - '</g>' +
35 - '</svg>';
36 - element.replaceWith(html);
37 - }
38 - };
39 - }]);
40 -}());
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -div.mast {
18 - width: 100%;
19 - height: 85px;
20 - background-color: white;
21 - position: relative;
22 - box-shadow: 0 10px 5px -7px gray;
23 - z-index: 100;
24 -}
25 -
26 -.mast div {
27 - position: absolute;
28 - top: 50%;
29 - transform: translate(0, -50%);
30 -}
31 -
32 -.mast div.left {
33 - left: 25px;
34 -}
35 -
36 -.mast div.right {
37 - right: 7%;
38 - width: 37%;
39 -}
40 -
41 -.mast img {
42 - width: 220px;
43 -}
44 -
45 -.mast a,
46 -.mast a:visited {
47 - text-decoration: none;
48 - color: #3C3C3C;
49 -}
50 -
51 -.mast li.logout {
52 - list-style-type: none;
53 - position: absolute;
54 - right: 0;
55 - top: 50%;
56 - transform: translate(0, -50%);
57 - font-size: 90%;
58 -}
59 -.mast li.logout:hover {
60 - font-weight: bold;
61 - list-style-type: none;
62 - cursor: pointer;
63 -}
1 -<!--Mast HTML-->
2 -
3 -<div class="mast" ng-controller="CordMastCtrl">
4 - <div class="left">
5 - <img src="/imgs/logo.png">
6 - </div>
7 -
8 - <div class="right">
9 - <nav ng-show="page.curr !== 'login'"></nav>
10 - <li class="logout"
11 - ng-show="page.curr !== 'login'"
12 - ng-click="logout()">LOGOUT</li>
13 - </div>
14 -</div>
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - var urlSuffix = '/rs/logout';
21 -
22 - angular.module('cordMast', [])
23 - .controller('CordMastCtrl',
24 - ['$log','$scope', '$resource', '$location', '$window',
25 - function ($log, $scope, $resource, $location, $window) {
26 - var LogoutData, resource;
27 -
28 - $scope.logout = function () {
29 - $log.debug('Logging out...');
30 - LogoutData = $resource($scope.shared.url + urlSuffix);
31 - resource = LogoutData.get({},
32 - function () {
33 - $location.path('/login');
34 - $window.location.href = $location.absUrl();
35 - $log.debug('Resource received:', resource);
36 - });
37 - };
38 - }])
39 -
40 - .directive('mast', function () {
41 - return {
42 - restrict: 'E',
43 - templateUrl: 'app/fw/mast/mast.html'
44 - };
45 - });
46 -}());
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -.nav ul {
18 - display: table;
19 - table-layout: fixed;
20 - list-style-type: none;
21 - width: 80%;
22 -}
23 -
24 -.nav li {
25 - padding: 2.5% 0;
26 - color: #3C3C3C;
27 -}
28 -.nav li:hover {
29 - border-bottom: 2px solid #CE5650;
30 - color: black;
31 -}
32 -.nav li.selected {
33 - font-weight: bolder;
34 - color: #3C3C3C;
35 - letter-spacing: 0.03em;
36 - border-bottom: 2px solid #CE5650;
37 -}
38 -
39 -.nav a,
40 -.nav a:visited {
41 - display: table-cell;
42 - text-align: center;
43 - text-decoration: none;
44 - color: black;
45 -}
1 -<!--Nav HTML-->
2 -<div class="nav">
3 - <ul>
4 - <a href="#/home">
5 - <li ng-class="{selected: page.curr === 'dashboard'}"
6 - ng-click="$route.reload()">Home</li>
7 - </a>
8 - <a href="#/user">
9 - <li ng-class="{selected: page.curr === 'user'}"
10 - ng-click="$route.reload()">Users</li>
11 - </a>
12 - <a href="#/bundle">
13 - <li ng-class="{selected: page.curr === 'bundle'}"
14 - ng-click="$route.reload()">Bundles</li>
15 - </a>
16 - </ul>
17 -</div>
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -angular.module('cordNav', [])
18 - .directive('nav', function () {
19 - return {
20 - restrict: 'E',
21 - templateUrl: 'app/fw/nav/nav.html'
22 - };
23 - });
1 -<div ng-cloak class="ng-hide ng-cloak" ng-show="show" id="available">
2 - <h3>{{available.name}}</h3>
3 - <p>{{available.desc}}</p>
4 - <button ng-click="changeBundle(available.id)">Apply</button>
5 -</div>
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -div#bundle div.main-left {
18 - width: 61%;
19 - padding: 4% 0 0 1%;
20 -}
21 -div#bundle div.main-right {
22 - width: 37%;
23 - padding-top: 4%;
24 -}
25 -
26 -#bundle table {
27 - width: 95%;
28 - margin-top: 5%;
29 - margin-left: 2%;
30 - border-radius: 3px;
31 -}
32 -
33 -#bundle td {
34 - font-size: 90%;
35 -}
36 -#bundle td.icon {
37 - text-align: center;
38 - width: 50px;
39 - height: 50px;
40 - padding: 4%;
41 -}
42 -#bundle td.name {
43 - border-left: solid 1px rgba(136, 0, 0, 0.25);
44 - padding-left: 3%;
45 -}
46 -#bundle td.desc {
47 - width: 60%;
48 - text-align: left;
49 - font-style: italic;
50 -}
51 -/* animation specific */
52 -#bundle tr.fadein.ng-leave td.name,
53 -#bundle tr.fadein.ng-leave-active td.name {
54 - opacity: 0;
55 - border: none;
56 -}
57 -
58 -#bundle img {
59 - width: 100%;
60 -}
61 -
62 -#bundle h2 {
63 - text-align: center;
64 - padding: 3%;
65 - font-weight: lighter;
66 - border: 1px solid #3C3C3C;
67 - cursor: pointer;
68 -}
69 -#bundle h2:hover {
70 - color: #CE5650;
71 - border-color: #CE5650;
72 -}
73 -
74 -div#bundles {
75 - position: relative;
76 -}
77 -
78 -div#available.ng-hide-add.ng-hide-add-active,
79 -div#available.ng-hide-remove.ng-hide-remove-active {
80 - -webkit-transition: all linear 0.5s;
81 - transition: all linear 0.5s;
82 -}
83 -div#available.ng-hide {
84 - opacity: 0;
85 - top: -80px;
86 -}
87 -
88 -div#available {
89 - position: absolute;
90 - padding: 5%;
91 - opacity: 1;
92 - top: -10px;
93 - width: 100%;
94 -}
95 -
96 -#available p {
97 - text-indent: initial;
98 - text-align: initial;
99 -}
100 -
101 -#available button {
102 - float: right;
103 - width: 33%;
104 - margin-top: 5%;
105 -}
1 -<!-- Bundle page partial html -->
2 -<div id="bundle" class="container">
3 - <div class="main-left">
4 - <h4>You are subscribed to the</h4>
5 - <h3>{{name}}</h3>
6 - <p>{{desc}}</p>
7 - <table>
8 - <tr ng-repeat="func in funcs" class="fadein">
9 - <td class="icon">
10 - <img ng-src="{{'/imgs/' + func.id + '.png'}}">
11 - </td>
12 - <td class="name">{{func.name}}</td>
13 - <td class="desc">{{func.desc}}</td>
14 - </tr>
15 - </table>
16 - </div>
17 - <div class="main-right">
18 - <img src="imgs/bundle.jpg">
19 - <div ng-click="showBundles()">
20 - <h2>Available Bundles</h2>
21 - </div>
22 - <div id="bundles" bundle-available></div>
23 - </div>
24 -</div>
...\ No newline at end of file ...\ No newline at end of file
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - var urlSuffix = '/rs/bundle';
21 -
22 - var basic = 'basic',
23 - family = 'family';
24 -
25 - angular.module('cordBundle', [])
26 - .controller('CordBundleCtrl', ['$log', '$scope', '$resource',
27 - function ($log, $scope, $resource) {
28 - var BundleData, resource,
29 - getData;
30 - $scope.page.curr = 'bundle';
31 - $scope.show = false;
32 -
33 - getData = function (id) {
34 - if (!id) { id = ''; }
35 -
36 - BundleData = $resource($scope.shared.url + urlSuffix + '/' + id);
37 - resource = BundleData.get({},
38 - // success
39 - function () {
40 - var current, availId;
41 - current = resource.bundle.id;
42 - $scope.name = resource.bundle.name;
43 - $scope.desc = resource.bundle.desc;
44 - $scope.funcs = resource.bundle.functions;
45 -
46 - availId = (current === basic) ? family : basic;
47 - resource.bundles.forEach(function (bundle) {
48 - if (bundle.id === availId) {
49 - $scope.available = bundle;
50 - }
51 - });
52 - },
53 - // error
54 - function () {
55 - $log.error('Problem with resource', resource);
56 - });
57 - };
58 -
59 - getData();
60 -
61 - $scope.changeBundle = function (id) {
62 - getData(id);
63 - };
64 -
65 - $scope.showBundles = function () {
66 - $scope.show = !$scope.show;
67 - };
68 -
69 - $log.debug('Cord Bundle Ctrl has been created.');
70 - }])
71 -
72 - .directive('bundleAvailable', [function () {
73 - return {
74 - templateUrl: 'app/view/bundle/available.html'
75 - };
76 - }]);
77 -}());
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -[ng\:cloak], [ng-cloak], .ng-cloak {
18 - display: none !important;
19 -}
20 -
21 -html, body, div#frame, div#view {
22 - height: 100%;
23 -}
24 -
25 -head, body, footer,
26 -h1, h2, h3, h4, h5, h6, p,
27 -a, ul, li, div,
28 -table, tr, td, th, thead, tbody,
29 -form, select, input, option, label {
30 - padding: 0;
31 - margin: 0;
32 -}
33 -
34 -h1, h2, h3, h4, h5, h6,
35 -p, a, li, th, td,
36 -select, input, option, label {
37 - font-family: sans-serif, "Droid Sans", "Lucida Grande", Arial, Helvetica;
38 - color: #3C3C3C;
39 -}
40 -
41 -body {
42 - background-color: white;
43 - overflow: hidden;
44 -}
45 -table {
46 - border-spacing: 0;
47 - border-collapse: collapse;
48 -}
49 -th, td {
50 - color: rgba(0, 0, 0, 0.8);
51 -}
52 -h3 {
53 - margin-bottom: 4%;
54 - font-size: xx-large;
55 - font-weight: lighter;
56 -}
57 -h4 {
58 - font-size: large;
59 - font-weight: lighter;
60 -}
61 -h5 {
62 - color: rgb(107, 107, 107);
63 - font-style: italic;
64 - font-weight: normal;
65 - font-size: 90%;
66 - margin-bottom: 1%;
67 -}
68 -p {
69 - font-size: 100%;
70 - color: rgba(0,0,0, 0.8);
71 - text-indent: 20px;
72 - text-align: justify;
73 - padding-right: 5%;
74 -}
75 -th {
76 - background-color: #7AB6EA;
77 - color: white;
78 - letter-spacing: 0.05em;
79 - font-weight: lighter;
80 -}
81 -
82 -button,
83 -input[type="button"],
84 -input[type="reset"] {
85 - height: 30px;
86 - box-shadow: none;
87 - border: none;
88 - outline: none;
89 - cursor: pointer;
90 - letter-spacing: 0.02em;
91 - font-size: 14px;
92 - background-color: lightgray;
93 - transition: background-color 0.4s;
94 -}
95 -button:hover,
96 -input[type="button"]:hover,
97 -input[type="reset"]:hover {
98 - color: white;
99 - background-color: rgb(122, 188, 229);
100 -}
101 -
102 -button[disabled],
103 -input[type="button"][disabled],
104 -input[type="reset"][disabled] {
105 - background-color: lightgray;
106 - color: graytext;
107 -}
108 -
109 -
110 -button[disabled]:hover,
111 -input[type="button"][disabled]:hover,
112 -input[type="reset"][disabled]:hover {
113 - cursor: default;
114 -}
115 -
116 -div.container {
117 - width: 85%;
118 - margin: 0 auto;
119 - min-height: 100%;
120 -}
121 -div.main-left, div.main-right {
122 - float: left;
123 -}
124 -div.main-left {
125 - width: 37%;
126 - padding-left: 1%;
127 -}
128 -div.main-right {
129 - width: 61%;
130 -}
131 -
132 -svg#icon-defs {
133 - display: none;
134 -}
135 -
136 -g.icon circle {
137 - fill: none;
138 -}
139 -g.icon use.glyph.checkMark {
140 - fill: rgb(68, 189, 83)
141 -}
142 -g.icon use.glyph.xMark {
143 - fill: #CE5650;
144 -}
145 -
146 -th.user-pic {
147 - background-color: white;
148 -}
149 -th.user-pic,
150 -td.user-pic {
151 - width: 30px;
152 - padding-left: 4%;
153 -}
154 -td.user-pic img {
155 - width: 25px;
156 -}
157 -
158 -/* animation */
159 -.fadein {
160 - transition: all linear 0.5s;
161 -}
162 -.fadein.ng-enter-stagger,
163 -.fadein.ng-leave-stagger {
164 - transition-delay: 0.2s;
165 - animation-delay: 0.2s;
166 -}
167 -.fadein.ng-enter {
168 - opacity: 0;
169 -}
170 -.fadein.ng-enter.ng-enter-active {
171 - opacity: 1;
172 -}
173 -.fadein.ng-leave,
174 -.fadein.ng-leave-active {
175 - opacity: 0;
176 -}
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -#home div.main-left {
18 - width: 55%;
19 - padding: 0;
20 -}
21 -#home div.main-right {
22 - padding: 1% 0 0 3%;
23 - width: 42%;
24 -}
25 -#home div.move-down {
26 - margin-top: 5%;
27 -}
28 -
29 -#home div.image-holder {
30 - width: 100%;
31 - position: relative;
32 -}
33 -
34 -#home div.main-left img {
35 - width: 100%;
36 -}
37 -
38 -#home div.main-right div.bundle-title {
39 - padding: 2% 0;
40 -}
41 -
42 -#home h4 {
43 - padding-bottom: 2%;
44 -}
45 -
46 -#home p {
47 - margin-bottom: 3%;
48 -}
49 -
50 -#home table {
51 - width: 94%;
52 - table-layout: fixed;
53 - margin-left: 6%;
54 - border-left: 1px solid #CE5650;
55 -}
56 -
57 -#home table.users th,
58 -#home table.users td {
59 - font-size: 90%;
60 -}
61 -
62 -#home td, #home th {
63 - text-align: left;
64 - padding: 2%;
65 -}
1 -<!-- Home page partial html -->
2 -<div id="home" class="container">
3 - <div class="main-left">
4 - <img src="/imgs/home.jpg">
5 - </div>
6 -
7 - <div class="main-right">
8 - <div class="move-down">
9 - <div class="bundle-title">
10 - <h4>Welcome Dad!</h4>
11 - <h5>You are subscribed to the</h5>
12 - <h3>{{bundle_name}}</h3>
13 - </div>
14 -
15 - <p>{{bundle_desc}}</p>
16 -
17 -
18 - <h4>Users</h4>
19 - <table class="users">
20 - <thead>
21 - <tr>
22 - <th class="user-pic"></th>
23 - <th>Name</th>
24 - <th>Last Login</th>
25 - </tr>
26 - </thead>
27 - <tbody>
28 -
29 - <tr ng-repeat="user in users" class="fadein">
30 - <td class="user-pic">
31 - <img ng-src="{{'/imgs/' + user.icon_id + '.jpg'}}">
32 - </td>
33 - <td>{{user.name}}</td>
34 - <td>{{shared.userActivity[user.id]}}</td>
35 - </tr>
36 - </tbody>
37 - </table>
38 - </div>
39 - </div>
40 -</div>
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - var urlSuffix = '/rs/dashboard';
21 -
22 - function randomDate(start, end) {
23 - return new Date(
24 - start.getTime() + Math.random() * (end.getTime() - start.getTime())
25 - );
26 - }
27 -
28 - angular.module('cordHome', [])
29 - .controller('CordHomeCtrl', ['$log', '$scope', '$resource', '$filter',
30 - function ($log, $scope, $resource, $filter) {
31 - var DashboardData, resource;
32 - $scope.page.curr = 'dashboard';
33 -
34 - DashboardData = $resource($scope.shared.url + urlSuffix);
35 - resource = DashboardData.get({},
36 - // success
37 - function () {
38 - $scope.bundle_name = resource.bundle_name;
39 - $scope.bundle_desc = resource.bundle_desc;
40 - $scope.users = resource.users;
41 -
42 - if ($.isEmptyObject($scope.shared.userActivity)) {
43 - $scope.users.forEach(function (user) {
44 - var date = randomDate(new Date(2015, 0, 1),
45 - new Date());
46 -
47 - $scope.shared.userActivity[user.id] =
48 - $filter('date')(date, 'mediumTime');
49 - });
50 - }
51 - },
52 - // error
53 - function () {
54 - $log.error('Problem with resource', resource);
55 - });
56 - $log.debug('Resource received:', resource);
57 -
58 - $log.debug('Cord Home Ctrl has been created.');
59 - }]);
60 -}());
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -div#login {
18 - background: url("/imgs/login.jpg") no-repeat center;
19 - background-size: contain;
20 - position: absolute;
21 - top: 3%;
22 - left: 5%;
23 -}
24 -
25 -div#login-wrapper {
26 - text-align: center;
27 -}
28 -
29 -#login h2 {
30 - margin: 1%;
31 - color: rgb(115, 115, 115);
32 - font-size: xx-large;
33 - font-weight: lighter;
34 - text-align: left;
35 - position: absolute;
36 - top: -140px;
37 -}
38 -
39 -div#login-form {
40 - display: inline-block;
41 -}
42 -
43 -#login div.outline {
44 - position: absolute;
45 - border: 1px solid rgba(115, 115, 115, 0.7);
46 - background-color: white;
47 - opacity: .6;
48 - top: -160px;
49 - left: -25px;
50 - width: 300px;
51 - height: 245px;
52 - border-radius: 1px;
53 -}
54 -
55 -div#login-form {
56 - margin-left: 2.5%;
57 - position: relative;
58 - width: 255px;
59 - margin-top: 33.5%;
60 -}
61 -
62 -#login-form form {
63 - line-height: 250%;
64 -}
65 -
66 -#login-form input {
67 - display: block;
68 - height: 40px;
69 - width: 230px;
70 - font-size: 19px;
71 - padding: 0 5px;
72 - margin-bottom: 3.5%;
73 - border-radius: 1px;
74 - position: absolute;
75 -}
76 -#login-form input[type="text"] {
77 - top: -90px;
78 -}
79 -#login-form input[type="password"] {
80 - top: -35px;
81 -}
82 -
83 -#login-form input[type="text"],
84 -#login-form input[type="password"] {
85 - border: 2px solid rgba(115, 115, 115, 0.7);
86 - transition: border 0.1s;
87 -}
88 -#login-form input[type="text"]:focus,
89 -#login-form input[type="password"]:focus,
90 -#login-form input[type="button"]:focus {
91 - outline: none;
92 - border: solid 2px rgba(122, 188, 229, 0.5);
93 -}
94 -
95 -#login-form a {
96 - text-decoration: none;
97 -}
98 -
99 -#login-form input[type="button"] {
100 - top: 25px;
101 - width: 245px;
102 - height: 30px;
103 - cursor: pointer;
104 - letter-spacing: 0.02em;
105 - font-size: 100%;
106 - color: #3C3C3C;
107 - background-color: lightgray;
108 - transition: background-color 0.4s;
109 -}
110 -
111 -#login-form input[type="button"]:hover {
112 - color: white;
113 - background-color: rgb(122, 188, 229);
114 -}
115 -
116 -#login-form input.ng-invalid.ng-touched {
117 - background-color: #CE5650;
118 - color: white;
119 -}
1 -<!-- Login page partial html -->
2 -<div id="login" class="container">
3 - <div id="login-wrapper">
4 - <div id="login-form">
5 - <div class="outline"></div>
6 - <h2>Subscriber Portal</h2>
7 - <form>
8 - <input ng-model="email" type="text" placeholder="email" required>
9 - <input ng-model="password" type="password" placeholder="password" required>
10 - <input ng-click="login()" type="button" value="Log In">
11 - </form>
12 - </div>
13 - </div>
14 -</div>
...\ No newline at end of file ...\ No newline at end of file
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 - var urlSuffix = '/rs/login';
20 -
21 - angular.module('cordLogin', [])
22 - .controller('CordLoginCtrl',
23 - ['$log', '$scope', '$resource', '$location', '$window',
24 - function ($log, $scope, $resource, $location, $window) {
25 - var LoginData, resource;
26 - $scope.page.curr = 'login';
27 -
28 - function getResource(email) {
29 - LoginData = $resource($scope.shared.url + urlSuffix + '/' + email);
30 - resource = LoginData.get({},
31 - function () {
32 - $location.url('/home');
33 - $window.location.href = $location.absUrl();
34 - });
35 - }
36 -
37 - $scope.login = function () {
38 - if ($scope.email && $scope.password) {
39 - getResource($scope.email);
40 - $scope.shared.login = $scope.email;
41 - }
42 - };
43 -
44 - $log.debug('Cord Login Ctrl has been created.');
45 - }]);
46 -}());
1 -<!--Partial HTML for rating panel directive-->
2 -<div id="rating-panel">
3 - <div ng-cloak class="ng-hide ng-cloak panel" ng-show="ratingsShown">
4 - <table>
5 - <tr>
6 - <th class="title">Category</th>
7 - <th ng-repeat="rating in level_order">{{rating}}</th>
8 - </tr>
9 - <tr ng-repeat="cat in category_order">
10 - <td class="title">{{cat}}</td>
11 - <td ng-repeat="r in level_order">
12 - <div ng-if="prohibitedSites[r][cat]">
13 - <icon size="15" id="xMark"></icon>
14 - </div>
15 - <div ng-if="!prohibitedSites[r][cat]">
16 - <icon size="15" id="checkMark"></icon>
17 - </div>
18 - </td>
19 - </tr>
20 - </table>
21 - </div>
22 -</div>
...\ No newline at end of file ...\ No newline at end of file
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -#user div {
18 - padding-top: 2%;
19 -}
20 -
21 -#user div.main-left {
22 - width: 98%;
23 - padding-left: 1%;
24 -}
25 -#user div.main-left.family {
26 - width: 62%;
27 - padding-left: 1%;
28 -}
29 -
30 -#user div.main-right {
31 - width: 0;
32 -}
33 -#user div.main-right.family {
34 - width: 37%;
35 -}
36 -
37 -#user table.user-info,
38 -#user table.user-form {
39 - float: left;
40 - width: 100%;
41 -}
42 -
43 -#user table.user-info th,
44 -#user table.user-form th {
45 - text-align: left;
46 - padding: 2% 1%;
47 -}
48 -
49 -#user span.help:hover {
50 - cursor: pointer;
51 - color: #CE5650;
52 -}
53 -
54 -#user div.main-left.family table.user-info th,
55 -#user div.main-right.family table.user-form th {
56 - padding: 17px;
57 -}
58 -
59 -#user div.main-left.family table.user-info td,
60 -#user div.main-right.family table.user-form td {
61 - padding: 10px;
62 - height: 23px;
63 -}
64 -#user table.user-info td {
65 - padding: 1%;
66 -}
67 -
68 -#user table.user-form td {
69 - border-left: 1px solid #CE5650;
70 -}
71 -
72 -#user table.user-form td.buttons {
73 - text-align: right;
74 - border: none;
75 -}
76 -
77 -#user table.user-form tr.options td {
78 - padding-left: 5%;
79 -}
80 -
81 -#user select,
82 -#user select:focus {
83 - border: none;
84 -}
85 -
86 -#user select {
87 - font-size: 95%;
88 -}
89 -
90 -#user option,
91 -#user option:focus {
92 - border: none;
93 -}
94 -
95 -#user option[selected] {
96 - background-color: rgb(122, 188, 229);
97 -}
98 -
99 -#user label {
100 - font-weight: bold;
101 - display: block;
102 - text-align: center;
103 - padding: 5%;
104 -}
105 -
106 -#user input[type="button"],
107 -#user input[type="reset"] {
108 - width: 30%;
109 -}
110 -
111 -#user td.buttons div {
112 - display: inline;
113 -}
114 -#user td.buttons svg {
115 - vertical-align: middle;
116 -}
117 -
118 -#rating-panel th,
119 -#rating-panel td {
120 - text-align: center;
121 - padding: 1%;
122 - font-weight: lighter;
123 -}
124 -
125 -#rating-panel th.title,
126 -#rating-panel td.title {
127 - width: 125px;
128 - text-align: left;
129 -}
130 -
131 -#rating-panel th {
132 - background-color: white;
133 - padding-top: 3%;
134 - border-bottom: 1px solid #CE5650;
135 - color: #3C3C3C;
136 - font-weight: normal;
137 -}
138 -
139 -#rating-panel tr th:first-child,
140 -#rating-panel tr td:first-child {
141 - padding-left: 5%;
142 -}
143 -#rating-panel tr th:last-child,
144 -#rating-panel tr td:last-child {
145 - padding-right: 5%;
146 -}
147 -
148 -div#rating-panel {
149 - position: relative;
150 - pointer-events: none;
151 -}
152 -
153 -#rating-panel div.ng-hide-add.ng-hide-add-active,
154 -#rating-panel div.ng-hide-remove.ng-hide-remove-active {
155 - -webkit-transition: all linear 0.75s;
156 - transition: all linear 0.75s;
157 -}
158 -
159 -#rating-panel div.panel {
160 - position: absolute;
161 - top: 0;
162 - left: -6%;
163 - height: 545px;
164 - overflow: auto;
165 - padding: 0;
166 - pointer-events: auto;
167 - box-shadow: 0 3px 23px 7px rgb(118, 118, 118);
168 - border-radius: 3px;
169 -}
170 -#rating-panel table {
171 - table-layout: fixed;
172 - width: 500px;
173 - background-color: white;
174 - opacity: 1;
175 -}
176 -
177 -#rating-panel div.ng-hide {
178 - opacity: 0;
179 - left: -55%;
180 -}
1 -<!-- Users page partial html -->
2 -<div class="container">
3 - <div id="user">
4 - <div class="main-left" ng-class="{family: isFamily}">
5 - <table class="user-info">
6 - <tr>
7 - <th class="user-pic"></th>
8 - <th>Name</th>
9 - <th>Last Login</th>
10 - </tr>
11 - <tr ng-repeat="user in users" class="fadein">
12 - <td class="user-pic">
13 - <img ng-src="{{'/imgs/' + user.icon_id + '.jpg'}}">
14 - </td>
15 - <td>{{user.name}}</td>
16 - <td>{{shared.userActivity[user.id]}}</td>
17 - </tr>
18 - </table>
19 - </div>
20 -
21 - <div class="main-right" ng-class="{family: isFamily}">
22 - <form ng-if="isFamily"
23 - name="changeLevels">
24 - <table class="user-form">
25 - <tr>
26 - <th>
27 - Select Site Rating
28 - <span class="help"
29 - ng-click="showRatings()"> (?)</span>
30 - </th>
31 - </tr>
32 - <tr ng-repeat="user in users" class="options">
33 - <td>
34 - <select ng-init="newLevels[user.id]=user.profile.url_filter.level"
35 - ng-model="newLevels[user.id]"
36 - ng-options="l for l in levels">
37 - </select>
38 - </td>
39 - </tr>
40 - <tr>
41 - <td class="buttons">
42 - <div ng-show="showCheck">
43 - <icon size="20px" id="checkMark"></icon>
44 - </div>
45 - <input type="reset" value="Cancel"
46 - ng-click="cancelChanges(changeLevels)"
47 - ng-disabled="changeLevels.$pristine">
48 - <input type="button" value="Apply"
49 - ng-click="applyChanges(changeLevels)"
50 - ng-disabled="changeLevels.$pristine">
51 - </td>
52 - </tr>
53 - </table>
54 - </form>
55 - </div>
56 - <div ng-if="isFamily">
57 - <ratings-panel></ratings-panel>
58 - </div>
59 - </div>
60 -</div>
...\ No newline at end of file ...\ No newline at end of file
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - var bundleUrlSuffix = '/rs/bundle',
21 - userUrlSuffix = '/rs/users',
22 - family = 'family',
23 - url_filter = 'url_filter';
24 -
25 - angular.module('cordUser', [])
26 - .controller('CordUserCtrl', ['$log', '$scope', '$resource', '$timeout',
27 - function ($log, $scope, $resource, $timeout) {
28 - var BundleData, bundleResource;
29 - $scope.page.curr = 'user';
30 - $scope.isFamily = false;
31 - $scope.newLevels = {};
32 - $scope.showCheck = false;
33 - $scope.ratingsShown = false;
34 -
35 - // === Get data functions ---
36 -
37 - BundleData = $resource($scope.shared.url + bundleUrlSuffix);
38 - bundleResource = BundleData.get({},
39 - // success
40 - function () {
41 - var result;
42 - $scope.isFamily = (bundleResource.bundle.id === family);
43 - if ($scope.isFamily) {
44 - result = $.grep(
45 - bundleResource.bundle.functions,
46 - function (elem) {
47 - if (elem.id === url_filter) { return true; }
48 - }
49 - );
50 - $scope.levels = result[0].params.levels;
51 - }
52 - },
53 - // error
54 - function () {
55 - $log.error('Problem with resource', bundleResource);
56 - }
57 - );
58 -
59 - function getUsers(url) {
60 - var UserData, userResource;
61 - UserData = $resource(url);
62 - userResource = UserData.get({},
63 - // success
64 - function () {
65 - $scope.users = userResource.users;
66 - },
67 - // error
68 - function () {
69 - $log.error('Problem with resource', userResource);
70 - }
71 - );
72 - }
73 -
74 - getUsers($scope.shared.url + userUrlSuffix);
75 -
76 - // === Form functions ---
77 -
78 - function levelUrl(id, level) {
79 - return $scope.shared.url +
80 - userUrlSuffix + '/' + id + '/apply/url_filter/level/' + level;
81 - }
82 -
83 - $scope.applyChanges = function (changeLevels) {
84 - var requests = [];
85 -
86 - if ($scope.users) {
87 - $.each($scope.users, function (index, user) {
88 - var id = user.id,
89 - level = user.profile.url_filter.level;
90 - if ($scope.newLevels[id] !== level) {
91 - requests.push(levelUrl(id, $scope.newLevels[id]));
92 - }
93 - });
94 -
95 - $.each(requests, function (index, req) {
96 - getUsers(req);
97 - });
98 - }
99 - changeLevels.$setPristine();
100 - $scope.showCheck = true;
101 - $timeout(function () {
102 - $scope.showCheck = false;
103 - }, 3000);
104 - };
105 -
106 - $scope.cancelChanges = function (changeLevels) {
107 - if ($scope.users) {
108 - $.each($scope.users, function (index, user) {
109 - $scope.newLevels[user.id] = user.profile.url_filter.level;
110 - });
111 - }
112 - changeLevels.$setPristine();
113 - $scope.showCheck = false;
114 - };
115 -
116 - $scope.showRatings = function () {
117 - $scope.ratingsShown = !$scope.ratingsShown;
118 - };
119 -
120 - $log.debug('Cord User Ctrl has been created.');
121 - }])
122 -
123 - .directive('ratingsPanel', ['$log', function ($log) {
124 - return {
125 - templateUrl: 'app/view/user/ratingPanel.html',
126 - link: function (scope, elem, attrs) {
127 - function fillSubMap(order, bool) {
128 - var result = {};
129 - $.each(order, function (index, cat) {
130 - result[cat] = bool;
131 - });
132 - return result;
133 - }
134 - function processSubMap(prhbSites) {
135 - var result = {};
136 - $.each(prhbSites, function (index, cat) {
137 - result[cat] = true;
138 - });
139 - return result;
140 - }
141 -
142 - function preprocess(data, order) {
143 - return {
144 - ALL: fillSubMap(order, false),
145 - G: processSubMap(data.G),
146 - PG: processSubMap(data.PG),
147 - PG_13: processSubMap(data.PG_13),
148 - R: processSubMap(data.R),
149 - NONE: fillSubMap(order, true)
150 - };
151 - }
152 -
153 - $.getJSON('/app/data/pc_cats.json', function (data) {
154 - scope.level_order = data.level_order;
155 - scope.category_order = data.category_order;
156 - scope.prohibitedSites = preprocess(
157 - data.prohibited, data.category_order
158 - );
159 - scope.$apply();
160 - });
161 - }
162 - };
163 - }]);
164 -
165 -}());
1 -/*
2 - * Copyright 2015-present 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 - */
16 -
17 -(function () {
18 - 'use strict';
19 -
20 - var modules = [
21 - 'ngRoute',
22 - 'ngResource',
23 - 'ngAnimate',
24 - 'cordMast',
25 - 'cordFoot',
26 - 'cordNav'
27 - ],
28 - viewIds = [
29 - 'login',
30 - 'home',
31 - 'user',
32 - 'bundle'
33 - ],
34 - viewDependencies = [],
35 - dependencies;
36 -
37 - function capitalize(word) {
38 - return word ? word[0].toUpperCase() + word.slice(1) : word;
39 - }
40 -
41 - viewIds.forEach(function (id) {
42 - if (id) {
43 - viewDependencies.push('cord' + capitalize(id));
44 - }
45 - });
46 -
47 - dependencies = modules.concat(viewDependencies);
48 -
49 - angular.module('cordGui', dependencies)
50 - .config(['$routeProvider', function ($routeProvider) {
51 - $routeProvider
52 - .otherwise({
53 - redirectTo: '/login'
54 - });
55 -
56 - function viewCtrlName(vid) {
57 - return 'Cord' + capitalize(vid) + 'Ctrl';
58 - }
59 -
60 - function viewTemplateUrl(vid) {
61 - return 'app/view/' + vid + '/' + vid + '.html';
62 - }
63 -
64 - viewIds.forEach(function (vid) {
65 - if (vid) {
66 - $routeProvider.when('/' + vid, {
67 - controller: viewCtrlName(vid),
68 - controllerAs: 'ctrl',
69 - templateUrl: viewTemplateUrl(vid)
70 - });
71 - }
72 - });
73 - }])
74 - .controller('CordCtrl', ['$scope', '$location',
75 - function ($scope, $location) {
76 - $scope.shared = {
77 - url: 'http://' + $location.host() + ':' + $location.port(),
78 - userActivity: {}
79 - };
80 - $scope.page = {};
81 - }]);
82 -}());
1 -<!DOCTYPE html>
2 -<!--
3 -~ Copyright 2015-present Open Networking Laboratory
4 -~
5 -~ Licensed under the Apache License, Version 2.0 (the "License");
6 -~ you may not use this file except in compliance with the License.
7 -~ You may obtain a copy of the License at
8 -~
9 -~ http://www.apache.org/licenses/LICENSE-2.0
10 -~
11 -~ Unless required by applicable law or agreed to in writing, software
12 -~ distributed under the License is distributed on an "AS IS" BASIS,
13 -~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 -~ See the License for the specific language governing permissions and
15 -~ limitations under the License.
16 -~
17 --->
18 -<html>
19 -<head>
20 - <meta charset="utf-8">
21 - <link rel="shortcut icon" href="imgs/bird.png">
22 -
23 - <title>CORD Subscriber Portal</title>
24 -
25 - <script src="tp/angular.js"></script>
26 - <script src="tp/angular-route.js"></script>
27 - <script src="tp/angular-animate.js"></script>
28 - <script src="tp/angular-resource.js"></script>
29 - <script src="tp/jquery-2.1.4.js"></script>
30 -
31 - <script src="cord.js"></script>
32 - <link rel="stylesheet" href="app/view/common/common.css">
33 -
34 - <script src="app/fw/mast/mast.js"></script>
35 - <link rel="stylesheet" href="app/fw/mast/mast.css">
36 - <script src="app/fw/foot/foot.js"></script>
37 - <link rel="stylesheet" href="app/fw/foot/foot.css">
38 -
39 - <script src="app/fw/nav/nav.js"></script>
40 - <link rel="stylesheet" href="app/fw/nav/nav.css">
41 -
42 - <script src="app/fw/icon/icon.js"></script>
43 -
44 - <script src="app/view/login/login.js"></script>
45 - <link rel="stylesheet" href="app/view/login/login.css">
46 -
47 - <script src="app/view/home/home.js"></script>
48 - <link rel="stylesheet" href="app/view/home/home.css">
49 -
50 - <script src="app/view/user/user.js"></script>
51 - <link rel="stylesheet" href="app/view/user/user.css">
52 -
53 - <script src="app/view/bundle/bundle.js"></script>
54 - <link rel="stylesheet" href="app/view/bundle/bundle.css">
55 -
56 -</head>
57 -<body ng-app="cordGui">
58 -<div id="frame" ng-controller="CordCtrl as cordCtrl">
59 -
60 -<mast></mast>
61 -<foot></foot>
62 -<div id="view" ng-view></div>
63 -
64 -<svg id="icon-defs">
65 - <defs>
66 - <symbol id="bird" viewBox="352 224 113 112">
67 - <path d="M427.7,300.4 c-6.9,0.6-13.1,5-19.2,7.1c-18.1,6.2-33.9,
68 - 9.1-56.5,4.7c24.6,17.2,36.6,13,63.7,0.1c-0.5,0.6-0.7,1.3-1.3,
69 - 1.9c1.4-0.4,2.4-1.7,3.4-2.2c-0.4,0.7-0.9,1.5-1.4,1.9c2.2-0.6,
70 - 3.7-2.3,5.9-3.9c-2.4,2.1-4.2,5-6,8c-1.5,2.5-3.1,4.8-5.1,6.9c-1,
71 - 1-1.9,1.9-2.9,2.9c-1.4,1.3-2.9,2.5-5.1,2.9c1.7,0.1,3.6-0.3,6.5
72 - -1.9c-1.6,2.4-7.1,6.2-9.9,7.2c10.5-2.6,19.2-15.9,25.7-18c18.3
73 - -5.9,13.8-3.4,27-14.2c1.6-1.3,3-1,5.1-0.8c1.1,0.1,2.1,0.3,3.2,
74 - 0.5c0.8,0.2,1.4,0.4,2.2,0.8l1.8,0.9c-1.9-4.5-2.3-4.1-5.9-6c-2.3
75 - -1.3-3.3-3.8-6.2-4.9c-7.1-2.6-11.9,11.7-11.7-5c0.1-8,4.2-14.4,
76 - 6.4-22c1.1-3.8,2.3-7.6,2.4-11.5c0.1-2.3,0-4.7-0.4-7c-2-11.2-8.4
77 - -21.5-19.7-24.8c-1-0.3-1.1-0.3-0.9,0c9.6,17.1,7.2,38.3,3.1,54.2
78 - C429.9,285.5,426.7,293.2,427.7,300.4z"></path>
79 - </symbol>
80 - <symbol id="checkMark" viewBox="0 0 10 10">
81 - <path d="M2.6,4.5c0,0,0.7-0.4,1.2,0.3l1.0,1.8c0,0,2.7-5.4,2.8-5.7c
82 - 0,0,0.5-0.9,1.4-0.1c0,0,0.5,0.5,0,1.3S6.8,7.3,5.6,9.2c0,0-0.4,0.5
83 - -1.2,0.1S2.2,5.4,2.2,5.4S2.2,4.7,2.6,4.5z"></path>
84 - </symbol>
85 - <symbol id="xMark" viewBox="0 0 10 10">
86 - <path d="M9.0,7.2C8.2,6.9,7.4,6.1,6.7,5.2c0.4-0.5,0.7-0.8,0.8-1.0C
87 - 7.8,3.5,9.4,1.6,8.1,1.1C6.8,0.6,6.6,1.7,6.6,1.7C6.4,2.1,6.0,2.7,
88 - 5.4,3.4C4.9,2.5,4.5,1.9,4.5,1.9S3.8,0.2,2.9,0.7C1.9,1.1,2.3,2.3,
89 - 2.3,2.3c0.3,1.1,0.8,2.1,1.4,2.9C2.5,6.4,1.3,7.4,1.3,7.4S0.8,7.8,
90 - 0.8,8.1C0.9,8.3,0.9,9.6,2.4,9.1C3.1,8.8,4.1,7.9,5.1,7.0c1.3,1.3,
91 - 2.5,1.9,2.5,1.9s0.5,0.5,1.4-0.2C9.8,7.9,9.0,7.2,9.0,7.2z"></path>
92 - </symbol>
93 - </defs>
94 -</svg>
95 -</div>
96 -
97 -</body>
98 -</html>
This diff could not be displayed because it is too large.
1 -/**
2 - * @license AngularJS v1.3.5
3 - * (c) 2010-2014 Google, Inc. http://angularjs.org
4 - * License: MIT
5 - */
6 -(function(window, angular, undefined) {'use strict';
7 -
8 -var $resourceMinErr = angular.$$minErr('$resource');
9 -
10 -// Helper functions and regex to lookup a dotted path on an object
11 -// stopping at undefined/null. The path must be composed of ASCII
12 -// identifiers (just like $parse)
13 -var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
14 -
15 -function isValidDottedPath(path) {
16 - return (path != null && path !== '' && path !== 'hasOwnProperty' &&
17 - MEMBER_NAME_REGEX.test('.' + path));
18 -}
19 -
20 -function lookupDottedPath(obj, path) {
21 - if (!isValidDottedPath(path)) {
22 - throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
23 - }
24 - var keys = path.split('.');
25 - for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) {
26 - var key = keys[i];
27 - obj = (obj !== null) ? obj[key] : undefined;
28 - }
29 - return obj;
30 -}
31 -
32 -/**
33 - * Create a shallow copy of an object and clear other fields from the destination
34 - */
35 -function shallowClearAndCopy(src, dst) {
36 - dst = dst || {};
37 -
38 - angular.forEach(dst, function(value, key) {
39 - delete dst[key];
40 - });
41 -
42 - for (var key in src) {
43 - if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
44 - dst[key] = src[key];
45 - }
46 - }
47 -
48 - return dst;
49 -}
50 -
51 -/**
52 - * @ngdoc module
53 - * @name ngResource
54 - * @description
55 - *
56 - * # ngResource
57 - *
58 - * The `ngResource` module provides interaction support with RESTful services
59 - * via the $resource service.
60 - *
61 - *
62 - * <div doc-module-components="ngResource"></div>
63 - *
64 - * See {@link ngResource.$resource `$resource`} for usage.
65 - */
66 -
67 -/**
68 - * @ngdoc service
69 - * @name $resource
70 - * @requires $http
71 - *
72 - * @description
73 - * A factory which creates a resource object that lets you interact with
74 - * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
75 - *
76 - * The returned resource object has action methods which provide high-level behaviors without
77 - * the need to interact with the low level {@link ng.$http $http} service.
78 - *
79 - * Requires the {@link ngResource `ngResource`} module to be installed.
80 - *
81 - * By default, trailing slashes will be stripped from the calculated URLs,
82 - * which can pose problems with server backends that do not expect that
83 - * behavior. This can be disabled by configuring the `$resourceProvider` like
84 - * this:
85 - *
86 - * ```js
87 - app.config(['$resourceProvider', function($resourceProvider) {
88 - // Don't strip trailing slashes from calculated URLs
89 - $resourceProvider.defaults.stripTrailingSlashes = false;
90 - }]);
91 - * ```
92 - *
93 - * @param {string} url A parametrized URL template with parameters prefixed by `:` as in
94 - * `/user/:username`. If you are using a URL with a port number (e.g.
95 - * `http://example.com:8080/api`), it will be respected.
96 - *
97 - * If you are using a url with a suffix, just add the suffix, like this:
98 - * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
99 - * or even `$resource('http://example.com/resource/:resource_id.:format')`
100 - * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
101 - * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
102 - * can escape it with `/\.`.
103 - *
104 - * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
105 - * `actions` methods. If any of the parameter value is a function, it will be executed every time
106 - * when a param value needs to be obtained for a request (unless the param was overridden).
107 - *
108 - * Each key value in the parameter object is first bound to url template if present and then any
109 - * excess keys are appended to the url search query after the `?`.
110 - *
111 - * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
112 - * URL `/path/greet?salutation=Hello`.
113 - *
114 - * If the parameter value is prefixed with `@` then the value for that parameter will be extracted
115 - * from the corresponding property on the `data` object (provided when calling an action method). For
116 - * example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of `someParam`
117 - * will be `data.someProp`.
118 - *
119 - * @param {Object.<Object>=} actions Hash with declaration of custom action that should extend
120 - * the default set of resource actions. The declaration should be created in the format of {@link
121 - * ng.$http#usage $http.config}:
122 - *
123 - * {action1: {method:?, params:?, isArray:?, headers:?, ...},
124 - * action2: {method:?, params:?, isArray:?, headers:?, ...},
125 - * ...}
126 - *
127 - * Where:
128 - *
129 - * - **`action`** – {string} – The name of action. This name becomes the name of the method on
130 - * your resource object.
131 - * - **`method`** – {string} – Case insensitive HTTP method (e.g. `GET`, `POST`, `PUT`,
132 - * `DELETE`, `JSONP`, etc).
133 - * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of
134 - * the parameter value is a function, it will be executed every time when a param value needs to
135 - * be obtained for a request (unless the param was overridden).
136 - * - **`url`** – {string} – action specific `url` override. The url templating is supported just
137 - * like for the resource-level urls.
138 - * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
139 - * see `returns` section.
140 - * - **`transformRequest`** –
141 - * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
142 - * transform function or an array of such functions. The transform function takes the http
143 - * request body and headers and returns its transformed (typically serialized) version.
144 - * By default, transformRequest will contain one function that checks if the request data is
145 - * an object and serializes to using `angular.toJson`. To prevent this behavior, set
146 - * `transformRequest` to an empty array: `transformRequest: []`
147 - * - **`transformResponse`** –
148 - * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
149 - * transform function or an array of such functions. The transform function takes the http
150 - * response body and headers and returns its transformed (typically deserialized) version.
151 - * By default, transformResponse will contain one function that checks if the response looks like
152 - * a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior, set
153 - * `transformResponse` to an empty array: `transformResponse: []`
154 - * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
155 - * GET request, otherwise if a cache instance built with
156 - * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
157 - * caching.
158 - * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
159 - * should abort the request when resolved.
160 - * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the
161 - * XHR object. See
162 - * [requests with credentials](https://developer.mozilla.org/en/http_access_control#section_5)
163 - * for more information.
164 - * - **`responseType`** - `{string}` - see
165 - * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
166 - * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
167 - * `response` and `responseError`. Both `response` and `responseError` interceptors get called
168 - * with `http response` object. See {@link ng.$http $http interceptors}.
169 - *
170 - * @param {Object} options Hash with custom settings that should extend the
171 - * default `$resourceProvider` behavior. The only supported option is
172 - *
173 - * Where:
174 - *
175 - * - **`stripTrailingSlashes`** – {boolean} – If true then the trailing
176 - * slashes from any calculated URL will be stripped. (Defaults to true.)
177 - *
178 - * @returns {Object} A resource "class" object with methods for the default set of resource actions
179 - * optionally extended with custom `actions`. The default set contains these actions:
180 - * ```js
181 - * { 'get': {method:'GET'},
182 - * 'save': {method:'POST'},
183 - * 'query': {method:'GET', isArray:true},
184 - * 'remove': {method:'DELETE'},
185 - * 'delete': {method:'DELETE'} };
186 - * ```
187 - *
188 - * Calling these methods invoke an {@link ng.$http} with the specified http method,
189 - * destination and parameters. When the data is returned from the server then the object is an
190 - * instance of the resource class. The actions `save`, `remove` and `delete` are available on it
191 - * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create,
192 - * read, update, delete) on server-side data like this:
193 - * ```js
194 - * var User = $resource('/user/:userId', {userId:'@id'});
195 - * var user = User.get({userId:123}, function() {
196 - * user.abc = true;
197 - * user.$save();
198 - * });
199 - * ```
200 - *
201 - * It is important to realize that invoking a $resource object method immediately returns an
202 - * empty reference (object or array depending on `isArray`). Once the data is returned from the
203 - * server the existing reference is populated with the actual data. This is a useful trick since
204 - * usually the resource is assigned to a model which is then rendered by the view. Having an empty
205 - * object results in no rendering, once the data arrives from the server then the object is
206 - * populated with the data and the view automatically re-renders itself showing the new data. This
207 - * means that in most cases one never has to write a callback function for the action methods.
208 - *
209 - * The action methods on the class object or instance object can be invoked with the following
210 - * parameters:
211 - *
212 - * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])`
213 - * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
214 - * - non-GET instance actions: `instance.$action([parameters], [success], [error])`
215 - *
216 - * Success callback is called with (value, responseHeaders) arguments. Error callback is called
217 - * with (httpResponse) argument.
218 - *
219 - * Class actions return empty instance (with additional properties below).
220 - * Instance actions return promise of the action.
221 - *
222 - * The Resource instances and collection have these additional properties:
223 - *
224 - * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
225 - * instance or collection.
226 - *
227 - * On success, the promise is resolved with the same resource instance or collection object,
228 - * updated with data from server. This makes it easy to use in
229 - * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view
230 - * rendering until the resource(s) are loaded.
231 - *
232 - * On failure, the promise is resolved with the {@link ng.$http http response} object, without
233 - * the `resource` property.
234 - *
235 - * If an interceptor object was provided, the promise will instead be resolved with the value
236 - * returned by the interceptor.
237 - *
238 - * - `$resolved`: `true` after first server interaction is completed (either with success or
239 - * rejection), `false` before that. Knowing if the Resource has been resolved is useful in
240 - * data-binding.
241 - *
242 - * @example
243 - *
244 - * # Credit card resource
245 - *
246 - * ```js
247 - // Define CreditCard class
248 - var CreditCard = $resource('/user/:userId/card/:cardId',
249 - {userId:123, cardId:'@id'}, {
250 - charge: {method:'POST', params:{charge:true}}
251 - });
252 -
253 - // We can retrieve a collection from the server
254 - var cards = CreditCard.query(function() {
255 - // GET: /user/123/card
256 - // server returns: [ {id:456, number:'1234', name:'Smith'} ];
257 -
258 - var card = cards[0];
259 - // each item is an instance of CreditCard
260 - expect(card instanceof CreditCard).toEqual(true);
261 - card.name = "J. Smith";
262 - // non GET methods are mapped onto the instances
263 - card.$save();
264 - // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
265 - // server returns: {id:456, number:'1234', name: 'J. Smith'};
266 -
267 - // our custom method is mapped as well.
268 - card.$charge({amount:9.99});
269 - // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
270 - });
271 -
272 - // we can create an instance as well
273 - var newCard = new CreditCard({number:'0123'});
274 - newCard.name = "Mike Smith";
275 - newCard.$save();
276 - // POST: /user/123/card {number:'0123', name:'Mike Smith'}
277 - // server returns: {id:789, number:'0123', name: 'Mike Smith'};
278 - expect(newCard.id).toEqual(789);
279 - * ```
280 - *
281 - * The object returned from this function execution is a resource "class" which has "static" method
282 - * for each action in the definition.
283 - *
284 - * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and
285 - * `headers`.
286 - * When the data is returned from the server then the object is an instance of the resource type and
287 - * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
288 - * operations (create, read, update, delete) on server-side data.
289 -
290 - ```js
291 - var User = $resource('/user/:userId', {userId:'@id'});
292 - User.get({userId:123}, function(user) {
293 - user.abc = true;
294 - user.$save();
295 - });
296 - ```
297 - *
298 - * It's worth noting that the success callback for `get`, `query` and other methods gets passed
299 - * in the response that came from the server as well as $http header getter function, so one
300 - * could rewrite the above example and get access to http headers as:
301 - *
302 - ```js
303 - var User = $resource('/user/:userId', {userId:'@id'});
304 - User.get({userId:123}, function(u, getResponseHeaders){
305 - u.abc = true;
306 - u.$save(function(u, putResponseHeaders) {
307 - //u => saved user object
308 - //putResponseHeaders => $http header getter
309 - });
310 - });
311 - ```
312 - *
313 - * You can also access the raw `$http` promise via the `$promise` property on the object returned
314 - *
315 - ```
316 - var User = $resource('/user/:userId', {userId:'@id'});
317 - User.get({userId:123})
318 - .$promise.then(function(user) {
319 - $scope.user = user;
320 - });
321 - ```
322 -
323 - * # Creating a custom 'PUT' request
324 - * In this example we create a custom method on our resource to make a PUT request
325 - * ```js
326 - * var app = angular.module('app', ['ngResource', 'ngRoute']);
327 - *
328 - * // Some APIs expect a PUT request in the format URL/object/ID
329 - * // Here we are creating an 'update' method
330 - * app.factory('Notes', ['$resource', function($resource) {
331 - * return $resource('/notes/:id', null,
332 - * {
333 - * 'update': { method:'PUT' }
334 - * });
335 - * }]);
336 - *
337 - * // In our controller we get the ID from the URL using ngRoute and $routeParams
338 - * // We pass in $routeParams and our Notes factory along with $scope
339 - * app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
340 - function($scope, $routeParams, Notes) {
341 - * // First get a note object from the factory
342 - * var note = Notes.get({ id:$routeParams.id });
343 - * $id = note.id;
344 - *
345 - * // Now call update passing in the ID first then the object you are updating
346 - * Notes.update({ id:$id }, note);
347 - *
348 - * // This will PUT /notes/ID with the note object in the request payload
349 - * }]);
350 - * ```
351 - */
352 -angular.module('ngResource', ['ng']).
353 - provider('$resource', function() {
354 - var provider = this;
355 -
356 - this.defaults = {
357 - // Strip slashes by default
358 - stripTrailingSlashes: true,
359 -
360 - // Default actions configuration
361 - actions: {
362 - 'get': {method: 'GET'},
363 - 'save': {method: 'POST'},
364 - 'query': {method: 'GET', isArray: true},
365 - 'remove': {method: 'DELETE'},
366 - 'delete': {method: 'DELETE'}
367 - }
368 - };
369 -
370 - this.$get = ['$http', '$q', function($http, $q) {
371 -
372 - var noop = angular.noop,
373 - forEach = angular.forEach,
374 - extend = angular.extend,
375 - copy = angular.copy,
376 - isFunction = angular.isFunction;
377 -
378 - /**
379 - * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
380 - * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set
381 - * (pchar) allowed in path segments:
382 - * segment = *pchar
383 - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
384 - * pct-encoded = "%" HEXDIG HEXDIG
385 - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
386 - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
387 - * / "*" / "+" / "," / ";" / "="
388 - */
389 - function encodeUriSegment(val) {
390 - return encodeUriQuery(val, true).
391 - replace(/%26/gi, '&').
392 - replace(/%3D/gi, '=').
393 - replace(/%2B/gi, '+');
394 - }
395 -
396 -
397 - /**
398 - * This method is intended for encoding *key* or *value* parts of query component. We need a
399 - * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
400 - * have to be encoded per http://tools.ietf.org/html/rfc3986:
401 - * query = *( pchar / "/" / "?" )
402 - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
403 - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
404 - * pct-encoded = "%" HEXDIG HEXDIG
405 - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
406 - * / "*" / "+" / "," / ";" / "="
407 - */
408 - function encodeUriQuery(val, pctEncodeSpaces) {
409 - return encodeURIComponent(val).
410 - replace(/%40/gi, '@').
411 - replace(/%3A/gi, ':').
412 - replace(/%24/g, '$').
413 - replace(/%2C/gi, ',').
414 - replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
415 - }
416 -
417 - function Route(template, defaults) {
418 - this.template = template;
419 - this.defaults = extend({}, provider.defaults, defaults);
420 - this.urlParams = {};
421 - }
422 -
423 - Route.prototype = {
424 - setUrlParams: function(config, params, actionUrl) {
425 - var self = this,
426 - url = actionUrl || self.template,
427 - val,
428 - encodedVal;
429 -
430 - var urlParams = self.urlParams = {};
431 - forEach(url.split(/\W/), function(param) {
432 - if (param === 'hasOwnProperty') {
433 - throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
434 - }
435 - if (!(new RegExp("^\\d+$").test(param)) && param &&
436 - (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
437 - urlParams[param] = true;
438 - }
439 - });
440 - url = url.replace(/\\:/g, ':');
441 -
442 - params = params || {};
443 - forEach(self.urlParams, function(_, urlParam) {
444 - val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
445 - if (angular.isDefined(val) && val !== null) {
446 - encodedVal = encodeUriSegment(val);
447 - url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
448 - return encodedVal + p1;
449 - });
450 - } else {
451 - url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
452 - leadingSlashes, tail) {
453 - if (tail.charAt(0) == '/') {
454 - return tail;
455 - } else {
456 - return leadingSlashes + tail;
457 - }
458 - });
459 - }
460 - });
461 -
462 - // strip trailing slashes and set the url (unless this behavior is specifically disabled)
463 - if (self.defaults.stripTrailingSlashes) {
464 - url = url.replace(/\/+$/, '') || '/';
465 - }
466 -
467 - // then replace collapse `/.` if found in the last URL path segment before the query
468 - // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
469 - url = url.replace(/\/\.(?=\w+($|\?))/, '.');
470 - // replace escaped `/\.` with `/.`
471 - config.url = url.replace(/\/\\\./, '/.');
472 -
473 -
474 - // set params - delegate param encoding to $http
475 - forEach(params, function(value, key) {
476 - if (!self.urlParams[key]) {
477 - config.params = config.params || {};
478 - config.params[key] = value;
479 - }
480 - });
481 - }
482 - };
483 -
484 -
485 - function resourceFactory(url, paramDefaults, actions, options) {
486 - var route = new Route(url, options);
487 -
488 - actions = extend({}, provider.defaults.actions, actions);
489 -
490 - function extractParams(data, actionParams) {
491 - var ids = {};
492 - actionParams = extend({}, paramDefaults, actionParams);
493 - forEach(actionParams, function(value, key) {
494 - if (isFunction(value)) { value = value(); }
495 - ids[key] = value && value.charAt && value.charAt(0) == '@' ?
496 - lookupDottedPath(data, value.substr(1)) : value;
497 - });
498 - return ids;
499 - }
500 -
501 - function defaultResponseInterceptor(response) {
502 - return response.resource;
503 - }
504 -
505 - function Resource(value) {
506 - shallowClearAndCopy(value || {}, this);
507 - }
508 -
509 - Resource.prototype.toJSON = function() {
510 - var data = extend({}, this);
511 - delete data.$promise;
512 - delete data.$resolved;
513 - return data;
514 - };
515 -
516 - forEach(actions, function(action, name) {
517 - var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
518 -
519 - Resource[name] = function(a1, a2, a3, a4) {
520 - var params = {}, data, success, error;
521 -
522 - /* jshint -W086 */ /* (purposefully fall through case statements) */
523 - switch (arguments.length) {
524 - case 4:
525 - error = a4;
526 - success = a3;
527 - //fallthrough
528 - case 3:
529 - case 2:
530 - if (isFunction(a2)) {
531 - if (isFunction(a1)) {
532 - success = a1;
533 - error = a2;
534 - break;
535 - }
536 -
537 - success = a2;
538 - error = a3;
539 - //fallthrough
540 - } else {
541 - params = a1;
542 - data = a2;
543 - success = a3;
544 - break;
545 - }
546 - case 1:
547 - if (isFunction(a1)) success = a1;
548 - else if (hasBody) data = a1;
549 - else params = a1;
550 - break;
551 - case 0: break;
552 - default:
553 - throw $resourceMinErr('badargs',
554 - "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
555 - arguments.length);
556 - }
557 - /* jshint +W086 */ /* (purposefully fall through case statements) */
558 -
559 - var isInstanceCall = this instanceof Resource;
560 - var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
561 - var httpConfig = {};
562 - var responseInterceptor = action.interceptor && action.interceptor.response ||
563 - defaultResponseInterceptor;
564 - var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
565 - undefined;
566 -
567 - forEach(action, function(value, key) {
568 - if (key != 'params' && key != 'isArray' && key != 'interceptor') {
569 - httpConfig[key] = copy(value);
570 - }
571 - });
572 -
573 - if (hasBody) httpConfig.data = data;
574 - route.setUrlParams(httpConfig,
575 - extend({}, extractParams(data, action.params || {}), params),
576 - action.url);
577 -
578 - var promise = $http(httpConfig).then(function(response) {
579 - var data = response.data,
580 - promise = value.$promise;
581 -
582 - if (data) {
583 - // Need to convert action.isArray to boolean in case it is undefined
584 - // jshint -W018
585 - if (angular.isArray(data) !== (!!action.isArray)) {
586 - throw $resourceMinErr('badcfg',
587 - 'Error in resource configuration for action `{0}`. Expected response to ' +
588 - 'contain an {1} but got an {2}', name, action.isArray ? 'array' : 'object',
589 - angular.isArray(data) ? 'array' : 'object');
590 - }
591 - // jshint +W018
592 - if (action.isArray) {
593 - value.length = 0;
594 - forEach(data, function(item) {
595 - if (typeof item === "object") {
596 - value.push(new Resource(item));
597 - } else {
598 - // Valid JSON values may be string literals, and these should not be converted
599 - // into objects. These items will not have access to the Resource prototype
600 - // methods, but unfortunately there
601 - value.push(item);
602 - }
603 - });
604 - } else {
605 - shallowClearAndCopy(data, value);
606 - value.$promise = promise;
607 - }
608 - }
609 -
610 - value.$resolved = true;
611 -
612 - response.resource = value;
613 -
614 - return response;
615 - }, function(response) {
616 - value.$resolved = true;
617 -
618 - (error || noop)(response);
619 -
620 - return $q.reject(response);
621 - });
622 -
623 - promise = promise.then(
624 - function(response) {
625 - var value = responseInterceptor(response);
626 - (success || noop)(value, response.headers);
627 - return value;
628 - },
629 - responseErrorInterceptor);
630 -
631 - if (!isInstanceCall) {
632 - // we are creating instance / collection
633 - // - set the initial promise
634 - // - return the instance / collection
635 - value.$promise = promise;
636 - value.$resolved = false;
637 -
638 - return value;
639 - }
640 -
641 - // instance call
642 - return promise;
643 - };
644 -
645 -
646 - Resource.prototype['$' + name] = function(params, success, error) {
647 - if (isFunction(params)) {
648 - error = success; success = params; params = {};
649 - }
650 - var result = Resource[name].call(this, params, this, success, error);
651 - return result.$promise || result;
652 - };
653 - });
654 -
655 - Resource.bind = function(additionalParamDefaults) {
656 - return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
657 - };
658 -
659 - return Resource;
660 - }
661 -
662 - return resourceFactory;
663 - }];
664 - });
665 -
666 -
667 -})(window, window.angular);
1 -/**
2 - * @license AngularJS v1.3.5
3 - * (c) 2010-2014 Google, Inc. http://angularjs.org
4 - * License: MIT
5 - */
6 -(function(window, angular, undefined) {'use strict';
7 -
8 -/**
9 - * @ngdoc module
10 - * @name ngRoute
11 - * @description
12 - *
13 - * # ngRoute
14 - *
15 - * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
16 - *
17 - * ## Example
18 - * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
19 - *
20 - *
21 - * <div doc-module-components="ngRoute"></div>
22 - */
23 - /* global -ngRouteModule */
24 -var ngRouteModule = angular.module('ngRoute', ['ng']).
25 - provider('$route', $RouteProvider),
26 - $routeMinErr = angular.$$minErr('ngRoute');
27 -
28 -/**
29 - * @ngdoc provider
30 - * @name $routeProvider
31 - *
32 - * @description
33 - *
34 - * Used for configuring routes.
35 - *
36 - * ## Example
37 - * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
38 - *
39 - * ## Dependencies
40 - * Requires the {@link ngRoute `ngRoute`} module to be installed.
41 - */
42 -function $RouteProvider() {
43 - function inherit(parent, extra) {
44 - return angular.extend(Object.create(parent), extra);
45 - }
46 -
47 - var routes = {};
48 -
49 - /**
50 - * @ngdoc method
51 - * @name $routeProvider#when
52 - *
53 - * @param {string} path Route path (matched against `$location.path`). If `$location.path`
54 - * contains redundant trailing slash or is missing one, the route will still match and the
55 - * `$location.path` will be updated to add or drop the trailing slash to exactly match the
56 - * route definition.
57 - *
58 - * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
59 - * to the next slash are matched and stored in `$routeParams` under the given `name`
60 - * when the route matches.
61 - * * `path` can contain named groups starting with a colon and ending with a star:
62 - * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
63 - * when the route matches.
64 - * * `path` can contain optional named groups with a question mark: e.g.`:name?`.
65 - *
66 - * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
67 - * `/color/brown/largecode/code/with/slashes/edit` and extract:
68 - *
69 - * * `color: brown`
70 - * * `largecode: code/with/slashes`.
71 - *
72 - *
73 - * @param {Object} route Mapping information to be assigned to `$route.current` on route
74 - * match.
75 - *
76 - * Object properties:
77 - *
78 - * - `controller` – `{(string|function()=}` – Controller fn that should be associated with
79 - * newly created scope or the name of a {@link angular.Module#controller registered
80 - * controller} if passed as a string.
81 - * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
82 - * published to scope under the `controllerAs` name.
83 - * - `template` – `{string=|function()=}` – html template as a string or a function that
84 - * returns an html template as a string which should be used by {@link
85 - * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
86 - * This property takes precedence over `templateUrl`.
87 - *
88 - * If `template` is a function, it will be called with the following parameters:
89 - *
90 - * - `{Array.<Object>}` - route parameters extracted from the current
91 - * `$location.path()` by applying the current route
92 - *
93 - * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
94 - * template that should be used by {@link ngRoute.directive:ngView ngView}.
95 - *
96 - * If `templateUrl` is a function, it will be called with the following parameters:
97 - *
98 - * - `{Array.<Object>}` - route parameters extracted from the current
99 - * `$location.path()` by applying the current route
100 - *
101 - * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
102 - * be injected into the controller. If any of these dependencies are promises, the router
103 - * will wait for them all to be resolved or one to be rejected before the controller is
104 - * instantiated.
105 - * If all the promises are resolved successfully, the values of the resolved promises are
106 - * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
107 - * fired. If any of the promises are rejected the
108 - * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
109 - * is:
110 - *
111 - * - `key` – `{string}`: a name of a dependency to be injected into the controller.
112 - * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
113 - * Otherwise if function, then it is {@link auto.$injector#invoke injected}
114 - * and the return value is treated as the dependency. If the result is a promise, it is
115 - * resolved before its value is injected into the controller. Be aware that
116 - * `ngRoute.$routeParams` will still refer to the previous route within these resolve
117 - * functions. Use `$route.current.params` to access the new route parameters, instead.
118 - *
119 - * - `redirectTo` – {(string|function())=} – value to update
120 - * {@link ng.$location $location} path with and trigger route redirection.
121 - *
122 - * If `redirectTo` is a function, it will be called with the following parameters:
123 - *
124 - * - `{Object.<string>}` - route parameters extracted from the current
125 - * `$location.path()` by applying the current route templateUrl.
126 - * - `{string}` - current `$location.path()`
127 - * - `{Object}` - current `$location.search()`
128 - *
129 - * The custom `redirectTo` function is expected to return a string which will be used
130 - * to update `$location.path()` and `$location.search()`.
131 - *
132 - * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
133 - * or `$location.hash()` changes.
134 - *
135 - * If the option is set to `false` and url in the browser changes, then
136 - * `$routeUpdate` event is broadcasted on the root scope.
137 - *
138 - * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
139 - *
140 - * If the option is set to `true`, then the particular route can be matched without being
141 - * case sensitive
142 - *
143 - * @returns {Object} self
144 - *
145 - * @description
146 - * Adds a new route definition to the `$route` service.
147 - */
148 - this.when = function(path, route) {
149 - //copy original route object to preserve params inherited from proto chain
150 - var routeCopy = angular.copy(route);
151 - if (angular.isUndefined(routeCopy.reloadOnSearch)) {
152 - routeCopy.reloadOnSearch = true;
153 - }
154 - if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) {
155 - routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch;
156 - }
157 - routes[path] = angular.extend(
158 - routeCopy,
159 - path && pathRegExp(path, routeCopy)
160 - );
161 -
162 - // create redirection for trailing slashes
163 - if (path) {
164 - var redirectPath = (path[path.length - 1] == '/')
165 - ? path.substr(0, path.length - 1)
166 - : path + '/';
167 -
168 - routes[redirectPath] = angular.extend(
169 - {redirectTo: path},
170 - pathRegExp(redirectPath, routeCopy)
171 - );
172 - }
173 -
174 - return this;
175 - };
176 -
177 - /**
178 - * @ngdoc property
179 - * @name $routeProvider#caseInsensitiveMatch
180 - * @description
181 - *
182 - * A boolean property indicating if routes defined
183 - * using this provider should be matched using a case insensitive
184 - * algorithm. Defaults to `false`.
185 - */
186 - this.caseInsensitiveMatch = false;
187 -
188 - /**
189 - * @param path {string} path
190 - * @param opts {Object} options
191 - * @return {?Object}
192 - *
193 - * @description
194 - * Normalizes the given path, returning a regular expression
195 - * and the original path.
196 - *
197 - * Inspired by pathRexp in visionmedia/express/lib/utils.js.
198 - */
199 - function pathRegExp(path, opts) {
200 - var insensitive = opts.caseInsensitiveMatch,
201 - ret = {
202 - originalPath: path,
203 - regexp: path
204 - },
205 - keys = ret.keys = [];
206 -
207 - path = path
208 - .replace(/([().])/g, '\\$1')
209 - .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
210 - var optional = option === '?' ? option : null;
211 - var star = option === '*' ? option : null;
212 - keys.push({ name: key, optional: !!optional });
213 - slash = slash || '';
214 - return ''
215 - + (optional ? '' : slash)
216 - + '(?:'
217 - + (optional ? slash : '')
218 - + (star && '(.+?)' || '([^/]+)')
219 - + (optional || '')
220 - + ')'
221 - + (optional || '');
222 - })
223 - .replace(/([\/$\*])/g, '\\$1');
224 -
225 - ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
226 - return ret;
227 - }
228 -
229 - /**
230 - * @ngdoc method
231 - * @name $routeProvider#otherwise
232 - *
233 - * @description
234 - * Sets route definition that will be used on route change when no other route definition
235 - * is matched.
236 - *
237 - * @param {Object|string} params Mapping information to be assigned to `$route.current`.
238 - * If called with a string, the value maps to `redirectTo`.
239 - * @returns {Object} self
240 - */
241 - this.otherwise = function(params) {
242 - if (typeof params === 'string') {
243 - params = {redirectTo: params};
244 - }
245 - this.when(null, params);
246 - return this;
247 - };
248 -
249 -
250 - this.$get = ['$rootScope',
251 - '$location',
252 - '$routeParams',
253 - '$q',
254 - '$injector',
255 - '$templateRequest',
256 - '$sce',
257 - function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) {
258 -
259 - /**
260 - * @ngdoc service
261 - * @name $route
262 - * @requires $location
263 - * @requires $routeParams
264 - *
265 - * @property {Object} current Reference to the current route definition.
266 - * The route definition contains:
267 - *
268 - * - `controller`: The controller constructor as define in route definition.
269 - * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
270 - * controller instantiation. The `locals` contain
271 - * the resolved values of the `resolve` map. Additionally the `locals` also contain:
272 - *
273 - * - `$scope` - The current route scope.
274 - * - `$template` - The current route template HTML.
275 - *
276 - * @property {Object} routes Object with all route configuration Objects as its properties.
277 - *
278 - * @description
279 - * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
280 - * It watches `$location.url()` and tries to map the path to an existing route definition.
281 - *
282 - * Requires the {@link ngRoute `ngRoute`} module to be installed.
283 - *
284 - * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
285 - *
286 - * The `$route` service is typically used in conjunction with the
287 - * {@link ngRoute.directive:ngView `ngView`} directive and the
288 - * {@link ngRoute.$routeParams `$routeParams`} service.
289 - *
290 - * @example
291 - * This example shows how changing the URL hash causes the `$route` to match a route against the
292 - * URL, and the `ngView` pulls in the partial.
293 - *
294 - * <example name="$route-service" module="ngRouteExample"
295 - * deps="angular-route.js" fixBase="true">
296 - * <file name="index.html">
297 - * <div ng-controller="MainController">
298 - * Choose:
299 - * <a href="Book/Moby">Moby</a> |
300 - * <a href="Book/Moby/ch/1">Moby: Ch1</a> |
301 - * <a href="Book/Gatsby">Gatsby</a> |
302 - * <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
303 - * <a href="Book/Scarlet">Scarlet Letter</a><br/>
304 - *
305 - * <div ng-view></div>
306 - *
307 - * <hr />
308 - *
309 - * <pre>$location.path() = {{$location.path()}}</pre>
310 - * <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
311 - * <pre>$route.current.params = {{$route.current.params}}</pre>
312 - * <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
313 - * <pre>$routeParams = {{$routeParams}}</pre>
314 - * </div>
315 - * </file>
316 - *
317 - * <file name="book.html">
318 - * controller: {{name}}<br />
319 - * Book Id: {{params.bookId}}<br />
320 - * </file>
321 - *
322 - * <file name="chapter.html">
323 - * controller: {{name}}<br />
324 - * Book Id: {{params.bookId}}<br />
325 - * Chapter Id: {{params.chapterId}}
326 - * </file>
327 - *
328 - * <file name="script.js">
329 - * angular.module('ngRouteExample', ['ngRoute'])
330 - *
331 - * .controller('MainController', function($scope, $route, $routeParams, $location) {
332 - * $scope.$route = $route;
333 - * $scope.$location = $location;
334 - * $scope.$routeParams = $routeParams;
335 - * })
336 - *
337 - * .controller('BookController', function($scope, $routeParams) {
338 - * $scope.name = "BookController";
339 - * $scope.params = $routeParams;
340 - * })
341 - *
342 - * .controller('ChapterController', function($scope, $routeParams) {
343 - * $scope.name = "ChapterController";
344 - * $scope.params = $routeParams;
345 - * })
346 - *
347 - * .config(function($routeProvider, $locationProvider) {
348 - * $routeProvider
349 - * .when('/Book/:bookId', {
350 - * templateUrl: 'book.html',
351 - * controller: 'BookController',
352 - * resolve: {
353 - * // I will cause a 1 second delay
354 - * delay: function($q, $timeout) {
355 - * var delay = $q.defer();
356 - * $timeout(delay.resolve, 1000);
357 - * return delay.promise;
358 - * }
359 - * }
360 - * })
361 - * .when('/Book/:bookId/ch/:chapterId', {
362 - * templateUrl: 'chapter.html',
363 - * controller: 'ChapterController'
364 - * });
365 - *
366 - * // configure html5 to get links working on jsfiddle
367 - * $locationProvider.html5Mode(true);
368 - * });
369 - *
370 - * </file>
371 - *
372 - * <file name="protractor.js" type="protractor">
373 - * it('should load and compile correct template', function() {
374 - * element(by.linkText('Moby: Ch1')).click();
375 - * var content = element(by.css('[ng-view]')).getText();
376 - * expect(content).toMatch(/controller\: ChapterController/);
377 - * expect(content).toMatch(/Book Id\: Moby/);
378 - * expect(content).toMatch(/Chapter Id\: 1/);
379 - *
380 - * element(by.partialLinkText('Scarlet')).click();
381 - *
382 - * content = element(by.css('[ng-view]')).getText();
383 - * expect(content).toMatch(/controller\: BookController/);
384 - * expect(content).toMatch(/Book Id\: Scarlet/);
385 - * });
386 - * </file>
387 - * </example>
388 - */
389 -
390 - /**
391 - * @ngdoc event
392 - * @name $route#$routeChangeStart
393 - * @eventType broadcast on root scope
394 - * @description
395 - * Broadcasted before a route change. At this point the route services starts
396 - * resolving all of the dependencies needed for the route change to occur.
397 - * Typically this involves fetching the view template as well as any dependencies
398 - * defined in `resolve` route property. Once all of the dependencies are resolved
399 - * `$routeChangeSuccess` is fired.
400 - *
401 - * The route change (and the `$location` change that triggered it) can be prevented
402 - * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on}
403 - * for more details about event object.
404 - *
405 - * @param {Object} angularEvent Synthetic event object.
406 - * @param {Route} next Future route information.
407 - * @param {Route} current Current route information.
408 - */
409 -
410 - /**
411 - * @ngdoc event
412 - * @name $route#$routeChangeSuccess
413 - * @eventType broadcast on root scope
414 - * @description
415 - * Broadcasted after a route dependencies are resolved.
416 - * {@link ngRoute.directive:ngView ngView} listens for the directive
417 - * to instantiate the controller and render the view.
418 - *
419 - * @param {Object} angularEvent Synthetic event object.
420 - * @param {Route} current Current route information.
421 - * @param {Route|Undefined} previous Previous route information, or undefined if current is
422 - * first route entered.
423 - */
424 -
425 - /**
426 - * @ngdoc event
427 - * @name $route#$routeChangeError
428 - * @eventType broadcast on root scope
429 - * @description
430 - * Broadcasted if any of the resolve promises are rejected.
431 - *
432 - * @param {Object} angularEvent Synthetic event object
433 - * @param {Route} current Current route information.
434 - * @param {Route} previous Previous route information.
435 - * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
436 - */
437 -
438 - /**
439 - * @ngdoc event
440 - * @name $route#$routeUpdate
441 - * @eventType broadcast on root scope
442 - * @description
443 - *
444 - * The `reloadOnSearch` property has been set to false, and we are reusing the same
445 - * instance of the Controller.
446 - */
447 -
448 - var forceReload = false,
449 - preparedRoute,
450 - preparedRouteIsUpdateOnly,
451 - $route = {
452 - routes: routes,
453 -
454 - /**
455 - * @ngdoc method
456 - * @name $route#reload
457 - *
458 - * @description
459 - * Causes `$route` service to reload the current route even if
460 - * {@link ng.$location $location} hasn't changed.
461 - *
462 - * As a result of that, {@link ngRoute.directive:ngView ngView}
463 - * creates new scope and reinstantiates the controller.
464 - */
465 - reload: function() {
466 - forceReload = true;
467 - $rootScope.$evalAsync(function() {
468 - // Don't support cancellation of a reload for now...
469 - prepareRoute();
470 - commitRoute();
471 - });
472 - },
473 -
474 - /**
475 - * @ngdoc method
476 - * @name $route#updateParams
477 - *
478 - * @description
479 - * Causes `$route` service to update the current URL, replacing
480 - * current route parameters with those specified in `newParams`.
481 - * Provided property names that match the route's path segment
482 - * definitions will be interpolated into the location's path, while
483 - * remaining properties will be treated as query params.
484 - *
485 - * @param {Object} newParams mapping of URL parameter names to values
486 - */
487 - updateParams: function(newParams) {
488 - if (this.current && this.current.$$route) {
489 - var searchParams = {}, self=this;
490 -
491 - angular.forEach(Object.keys(newParams), function(key) {
492 - if (!self.current.pathParams[key]) searchParams[key] = newParams[key];
493 - });
494 -
495 - newParams = angular.extend({}, this.current.params, newParams);
496 - $location.path(interpolate(this.current.$$route.originalPath, newParams));
497 - $location.search(angular.extend({}, $location.search(), searchParams));
498 - }
499 - else {
500 - throw $routeMinErr('norout', 'Tried updating route when with no current route');
501 - }
502 - }
503 - };
504 -
505 - $rootScope.$on('$locationChangeStart', prepareRoute);
506 - $rootScope.$on('$locationChangeSuccess', commitRoute);
507 -
508 - return $route;
509 -
510 - /////////////////////////////////////////////////////
511 -
512 - /**
513 - * @param on {string} current url
514 - * @param route {Object} route regexp to match the url against
515 - * @return {?Object}
516 - *
517 - * @description
518 - * Check if the route matches the current url.
519 - *
520 - * Inspired by match in
521 - * visionmedia/express/lib/router/router.js.
522 - */
523 - function switchRouteMatcher(on, route) {
524 - var keys = route.keys,
525 - params = {};
526 -
527 - if (!route.regexp) return null;
528 -
529 - var m = route.regexp.exec(on);
530 - if (!m) return null;
531 -
532 - for (var i = 1, len = m.length; i < len; ++i) {
533 - var key = keys[i - 1];
534 -
535 - var val = m[i];
536 -
537 - if (key && val) {
538 - params[key.name] = val;
539 - }
540 - }
541 - return params;
542 - }
543 -
544 - function prepareRoute($locationEvent) {
545 - var lastRoute = $route.current;
546 -
547 - preparedRoute = parseRoute();
548 - preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route
549 - && angular.equals(preparedRoute.pathParams, lastRoute.pathParams)
550 - && !preparedRoute.reloadOnSearch && !forceReload;
551 -
552 - if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) {
553 - if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) {
554 - if ($locationEvent) {
555 - $locationEvent.preventDefault();
556 - }
557 - }
558 - }
559 - }
560 -
561 - function commitRoute() {
562 - var lastRoute = $route.current;
563 - var nextRoute = preparedRoute;
564 -
565 - if (preparedRouteIsUpdateOnly) {
566 - lastRoute.params = nextRoute.params;
567 - angular.copy(lastRoute.params, $routeParams);
568 - $rootScope.$broadcast('$routeUpdate', lastRoute);
569 - } else if (nextRoute || lastRoute) {
570 - forceReload = false;
571 - $route.current = nextRoute;
572 - if (nextRoute) {
573 - if (nextRoute.redirectTo) {
574 - if (angular.isString(nextRoute.redirectTo)) {
575 - $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params)
576 - .replace();
577 - } else {
578 - $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search()))
579 - .replace();
580 - }
581 - }
582 - }
583 -
584 - $q.when(nextRoute).
585 - then(function() {
586 - if (nextRoute) {
587 - var locals = angular.extend({}, nextRoute.resolve),
588 - template, templateUrl;
589 -
590 - angular.forEach(locals, function(value, key) {
591 - locals[key] = angular.isString(value) ?
592 - $injector.get(value) : $injector.invoke(value, null, null, key);
593 - });
594 -
595 - if (angular.isDefined(template = nextRoute.template)) {
596 - if (angular.isFunction(template)) {
597 - template = template(nextRoute.params);
598 - }
599 - } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) {
600 - if (angular.isFunction(templateUrl)) {
601 - templateUrl = templateUrl(nextRoute.params);
602 - }
603 - templateUrl = $sce.getTrustedResourceUrl(templateUrl);
604 - if (angular.isDefined(templateUrl)) {
605 - nextRoute.loadedTemplateUrl = templateUrl;
606 - template = $templateRequest(templateUrl);
607 - }
608 - }
609 - if (angular.isDefined(template)) {
610 - locals['$template'] = template;
611 - }
612 - return $q.all(locals);
613 - }
614 - }).
615 - // after route change
616 - then(function(locals) {
617 - if (nextRoute == $route.current) {
618 - if (nextRoute) {
619 - nextRoute.locals = locals;
620 - angular.copy(nextRoute.params, $routeParams);
621 - }
622 - $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute);
623 - }
624 - }, function(error) {
625 - if (nextRoute == $route.current) {
626 - $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error);
627 - }
628 - });
629 - }
630 - }
631 -
632 -
633 - /**
634 - * @returns {Object} the current active route, by matching it against the URL
635 - */
636 - function parseRoute() {
637 - // Match a route
638 - var params, match;
639 - angular.forEach(routes, function(route, path) {
640 - if (!match && (params = switchRouteMatcher($location.path(), route))) {
641 - match = inherit(route, {
642 - params: angular.extend({}, $location.search(), params),
643 - pathParams: params});
644 - match.$$route = route;
645 - }
646 - });
647 - // No route matched; fallback to "otherwise" route
648 - return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
649 - }
650 -
651 - /**
652 - * @returns {string} interpolation of the redirect path with the parameters
653 - */
654 - function interpolate(string, params) {
655 - var result = [];
656 - angular.forEach((string || '').split(':'), function(segment, i) {
657 - if (i === 0) {
658 - result.push(segment);
659 - } else {
660 - var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/);
661 - var key = segmentMatch[1];
662 - result.push(params[key]);
663 - result.push(segmentMatch[2] || '');
664 - delete params[key];
665 - }
666 - });
667 - return result.join('');
668 - }
669 - }];
670 -}
671 -
672 -ngRouteModule.provider('$routeParams', $RouteParamsProvider);
673 -
674 -
675 -/**
676 - * @ngdoc service
677 - * @name $routeParams
678 - * @requires $route
679 - *
680 - * @description
681 - * The `$routeParams` service allows you to retrieve the current set of route parameters.
682 - *
683 - * Requires the {@link ngRoute `ngRoute`} module to be installed.
684 - *
685 - * The route parameters are a combination of {@link ng.$location `$location`}'s
686 - * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}.
687 - * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
688 - *
689 - * In case of parameter name collision, `path` params take precedence over `search` params.
690 - *
691 - * The service guarantees that the identity of the `$routeParams` object will remain unchanged
692 - * (but its properties will likely change) even when a route change occurs.
693 - *
694 - * Note that the `$routeParams` are only updated *after* a route change completes successfully.
695 - * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
696 - * Instead you can use `$route.current.params` to access the new route's parameters.
697 - *
698 - * @example
699 - * ```js
700 - * // Given:
701 - * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
702 - * // Route: /Chapter/:chapterId/Section/:sectionId
703 - * //
704 - * // Then
705 - * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
706 - * ```
707 - */
708 -function $RouteParamsProvider() {
709 - this.$get = function() { return {}; };
710 -}
711 -
712 -ngRouteModule.directive('ngView', ngViewFactory);
713 -ngRouteModule.directive('ngView', ngViewFillContentFactory);
714 -
715 -
716 -/**
717 - * @ngdoc directive
718 - * @name ngView
719 - * @restrict ECA
720 - *
721 - * @description
722 - * # Overview
723 - * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
724 - * including the rendered template of the current route into the main layout (`index.html`) file.
725 - * Every time the current route changes, the included view changes with it according to the
726 - * configuration of the `$route` service.
727 - *
728 - * Requires the {@link ngRoute `ngRoute`} module to be installed.
729 - *
730 - * @animations
731 - * enter - animation is used to bring new content into the browser.
732 - * leave - animation is used to animate existing content away.
733 - *
734 - * The enter and leave animation occur concurrently.
735 - *
736 - * @scope
737 - * @priority 400
738 - * @param {string=} onload Expression to evaluate whenever the view updates.
739 - *
740 - * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll
741 - * $anchorScroll} to scroll the viewport after the view is updated.
742 - *
743 - * - If the attribute is not set, disable scrolling.
744 - * - If the attribute is set without value, enable scrolling.
745 - * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated
746 - * as an expression yields a truthy value.
747 - * @example
748 - <example name="ngView-directive" module="ngViewExample"
749 - deps="angular-route.js;angular-animate.js"
750 - animations="true" fixBase="true">
751 - <file name="index.html">
752 - <div ng-controller="MainCtrl as main">
753 - Choose:
754 - <a href="Book/Moby">Moby</a> |
755 - <a href="Book/Moby/ch/1">Moby: Ch1</a> |
756 - <a href="Book/Gatsby">Gatsby</a> |
757 - <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
758 - <a href="Book/Scarlet">Scarlet Letter</a><br/>
759 -
760 - <div class="view-animate-container">
761 - <div ng-view class="view-animate"></div>
762 - </div>
763 - <hr />
764 -
765 - <pre>$location.path() = {{main.$location.path()}}</pre>
766 - <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
767 - <pre>$route.current.params = {{main.$route.current.params}}</pre>
768 - <pre>$routeParams = {{main.$routeParams}}</pre>
769 - </div>
770 - </file>
771 -
772 - <file name="book.html">
773 - <div>
774 - controller: {{book.name}}<br />
775 - Book Id: {{book.params.bookId}}<br />
776 - </div>
777 - </file>
778 -
779 - <file name="chapter.html">
780 - <div>
781 - controller: {{chapter.name}}<br />
782 - Book Id: {{chapter.params.bookId}}<br />
783 - Chapter Id: {{chapter.params.chapterId}}
784 - </div>
785 - </file>
786 -
787 - <file name="animations.css">
788 - .view-animate-container {
789 - position:relative;
790 - height:100px!important;
791 - position:relative;
792 - background:white;
793 - border:1px solid black;
794 - height:40px;
795 - overflow:hidden;
796 - }
797 -
798 - .view-animate {
799 - padding:10px;
800 - }
801 -
802 - .view-animate.ng-enter, .view-animate.ng-leave {
803 - -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
804 - transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
805 -
806 - display:block;
807 - width:100%;
808 - border-left:1px solid black;
809 -
810 - position:absolute;
811 - top:0;
812 - left:0;
813 - right:0;
814 - bottom:0;
815 - padding:10px;
816 - }
817 -
818 - .view-animate.ng-enter {
819 - left:100%;
820 - }
821 - .view-animate.ng-enter.ng-enter-active {
822 - left:0;
823 - }
824 - .view-animate.ng-leave.ng-leave-active {
825 - left:-100%;
826 - }
827 - </file>
828 -
829 - <file name="script.js">
830 - angular.module('ngViewExample', ['ngRoute', 'ngAnimate'])
831 - .config(['$routeProvider', '$locationProvider',
832 - function($routeProvider, $locationProvider) {
833 - $routeProvider
834 - .when('/Book/:bookId', {
835 - templateUrl: 'book.html',
836 - controller: 'BookCtrl',
837 - controllerAs: 'book'
838 - })
839 - .when('/Book/:bookId/ch/:chapterId', {
840 - templateUrl: 'chapter.html',
841 - controller: 'ChapterCtrl',
842 - controllerAs: 'chapter'
843 - });
844 -
845 - $locationProvider.html5Mode(true);
846 - }])
847 - .controller('MainCtrl', ['$route', '$routeParams', '$location',
848 - function($route, $routeParams, $location) {
849 - this.$route = $route;
850 - this.$location = $location;
851 - this.$routeParams = $routeParams;
852 - }])
853 - .controller('BookCtrl', ['$routeParams', function($routeParams) {
854 - this.name = "BookCtrl";
855 - this.params = $routeParams;
856 - }])
857 - .controller('ChapterCtrl', ['$routeParams', function($routeParams) {
858 - this.name = "ChapterCtrl";
859 - this.params = $routeParams;
860 - }]);
861 -
862 - </file>
863 -
864 - <file name="protractor.js" type="protractor">
865 - it('should load and compile correct template', function() {
866 - element(by.linkText('Moby: Ch1')).click();
867 - var content = element(by.css('[ng-view]')).getText();
868 - expect(content).toMatch(/controller\: ChapterCtrl/);
869 - expect(content).toMatch(/Book Id\: Moby/);
870 - expect(content).toMatch(/Chapter Id\: 1/);
871 -
872 - element(by.partialLinkText('Scarlet')).click();
873 -
874 - content = element(by.css('[ng-view]')).getText();
875 - expect(content).toMatch(/controller\: BookCtrl/);
876 - expect(content).toMatch(/Book Id\: Scarlet/);
877 - });
878 - </file>
879 - </example>
880 - */
881 -
882 -
883 -/**
884 - * @ngdoc event
885 - * @name ngView#$viewContentLoaded
886 - * @eventType emit on the current ngView scope
887 - * @description
888 - * Emitted every time the ngView content is reloaded.
889 - */
890 -ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
891 -function ngViewFactory($route, $anchorScroll, $animate) {
892 - return {
893 - restrict: 'ECA',
894 - terminal: true,
895 - priority: 400,
896 - transclude: 'element',
897 - link: function(scope, $element, attr, ctrl, $transclude) {
898 - var currentScope,
899 - currentElement,
900 - previousLeaveAnimation,
901 - autoScrollExp = attr.autoscroll,
902 - onloadExp = attr.onload || '';
903 -
904 - scope.$on('$routeChangeSuccess', update);
905 - update();
906 -
907 - function cleanupLastView() {
908 - if (previousLeaveAnimation) {
909 - $animate.cancel(previousLeaveAnimation);
910 - previousLeaveAnimation = null;
911 - }
912 -
913 - if (currentScope) {
914 - currentScope.$destroy();
915 - currentScope = null;
916 - }
917 - if (currentElement) {
918 - previousLeaveAnimation = $animate.leave(currentElement);
919 - previousLeaveAnimation.then(function() {
920 - previousLeaveAnimation = null;
921 - });
922 - currentElement = null;
923 - }
924 - }
925 -
926 - function update() {
927 - var locals = $route.current && $route.current.locals,
928 - template = locals && locals.$template;
929 -
930 - if (angular.isDefined(template)) {
931 - var newScope = scope.$new();
932 - var current = $route.current;
933 -
934 - // Note: This will also link all children of ng-view that were contained in the original
935 - // html. If that content contains controllers, ... they could pollute/change the scope.
936 - // However, using ng-view on an element with additional content does not make sense...
937 - // Note: We can't remove them in the cloneAttchFn of $transclude as that
938 - // function is called before linking the content, which would apply child
939 - // directives to non existing elements.
940 - var clone = $transclude(newScope, function(clone) {
941 - $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() {
942 - if (angular.isDefined(autoScrollExp)
943 - && (!autoScrollExp || scope.$eval(autoScrollExp))) {
944 - $anchorScroll();
945 - }
946 - });
947 - cleanupLastView();
948 - });
949 -
950 - currentElement = clone;
951 - currentScope = current.scope = newScope;
952 - currentScope.$emit('$viewContentLoaded');
953 - currentScope.$eval(onloadExp);
954 - } else {
955 - cleanupLastView();
956 - }
957 - }
958 - }
959 - };
960 -}
961 -
962 -// This directive is called during the $transclude call of the first `ngView` directive.
963 -// It will replace and compile the content of the element with the loaded template.
964 -// We need this directive so that the element content is already filled when
965 -// the link function of another directive on the same element as ngView
966 -// is called.
967 -ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
968 -function ngViewFillContentFactory($compile, $controller, $route) {
969 - return {
970 - restrict: 'ECA',
971 - priority: -400,
972 - link: function(scope, $element) {
973 - var current = $route.current,
974 - locals = current.locals;
975 -
976 - $element.html(locals.$template);
977 -
978 - var link = $compile($element.contents());
979 -
980 - if (current.controller) {
981 - locals.$scope = scope;
982 - var controller = $controller(current.controller, locals);
983 - if (current.controllerAs) {
984 - scope[current.controllerAs] = controller;
985 - }
986 - $element.data('$ngControllerController', controller);
987 - $element.children().data('$ngControllerController', controller);
988 - }
989 -
990 - link(scope);
991 - }
992 - };
993 -}
994 -
995 -
996 -})(window, window.angular);
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
1 -cp $ONOS_ROOT/apps/demo/cord-gui/target/cord-gui-1.8.0-SNAPSHOT.war .
1 -#######------------------------------------------------------------
2 -# CORD Demo
3 -# =========
4 -
5 -export LISTENPORT=8080
6 -export JETTY="-jar jetty-runner.jar"
7 -export CORD=./cord-gui-1.8.0-SNAPSHOT.war
8 -export LOGDBG=-Dorg.onosproject.cord.gui.LEVEL=DEBUG
9 -export DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n"
10 -export LOG=cord.log
11 -
12 -DBG=""
13 -if [ "$1" = "debug" ]
14 -then
15 - shift
16 - DBG=$DEBUG
17 -fi
18 -
19 -IP="$1"
20 -PORT="$2"
21 -
22 -if [ ! -z "$IP" ]
23 -then
24 - PARAM1="-Dheadnodeip=$IP"
25 -else
26 - PARAM1=""
27 -fi
28 -
29 -if [ ! -z "$PORT" ]
30 -then
31 - PARAM2="-Dheadnodeport=$PORT"
32 -else
33 - PARAM2=""
34 -fi
35 -
36 -java $PARAM1 $PARAM2 $LOGDBG $DBG $JETTY --port $LISTENPORT $CORD >$LOG 2>&1 &
37 -
38 -echo jetty-runner started {$PARAM1:$PARAM2}
39 -echo .. logging to $LOG
1 -# script to stop the cord gui server
2 -#
3 -PID=$(ps -ef | grep jetty-runner | grep -v grep | awk '{print $2}')
4 -if [ -z "$PID" ]
5 -then
6 - echo jetty-runner not running
7 - exit 0
8 -fi
9 -kill $PID
10 -sleep 1
11 -
12 -PID=$(ps -ef | grep jetty-runner | grep -v grep | awk '{print $2}')
13 -if [ ! -z "$PID" ]
14 -then
15 - echo jetty-runner still running ?
16 -else
17 - echo jetty-runner stopped
18 -fi
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui;
19 -
20 -import com.fasterxml.jackson.databind.JsonNode;
21 -import com.fasterxml.jackson.databind.ObjectMapper;
22 -import com.fasterxml.jackson.databind.node.ObjectNode;
23 -import org.junit.Before;
24 -import org.junit.Ignore;
25 -import org.junit.Test;
26 -import org.onosproject.cord.gui.model.BundleFactory;
27 -import org.onosproject.cord.gui.model.SubscriberUser;
28 -
29 -import java.io.IOException;
30 -import java.util.List;
31 -
32 -import static org.junit.Assert.assertEquals;
33 -import static org.junit.Assert.assertTrue;
34 -
35 -/**
36 - * Unit tests for {@link CordModelCache}.
37 - */
38 -@Ignore("How to test against a live XOS system??")
39 -public class CoreModelCacheTest {
40 -
41 - private CordModelCache cache;
42 -
43 - @Before
44 - public void setUp() {
45 - cache = new CordModelCache();
46 - }
47 -
48 - @Test
49 - public void basic() {
50 - assertEquals("wrong bundle", BundleFactory.BASIC_BUNDLE,
51 - cache.getCurrentBundle().descriptor());
52 - }
53 -
54 - @Test
55 - public void basicBundleJson() {
56 - ObjectNode node = BundleFactory.toObjectNode(cache.getCurrentBundle());
57 - String json = node.toString();
58 - System.out.println(json);
59 - assertTrue("bad basic json", sameJson(BASIC_BUNDLE_JSON, json));
60 - }
61 -
62 - @Test
63 - public void chooseFamilyBundle() {
64 - cache.setCurrentBundle("family");
65 - assertEquals("wrong bundle", BundleFactory.FAMILY_BUNDLE,
66 - cache.getCurrentBundle().descriptor());
67 - }
68 -
69 - @Test
70 - public void familyBundleJson() {
71 - cache.setCurrentBundle("family");
72 - ObjectNode node = BundleFactory.toObjectNode(cache.getCurrentBundle());
73 - String json = node.toString();
74 - System.out.println(json);
75 - assertTrue("bad family json", sameJson(FAMILY_BUNDLE_JSON, json));
76 - }
77 -
78 - @Test
79 - public void checkUsers() {
80 - List<SubscriberUser> users = cache.getUsers();
81 - assertEquals("wrong # users", 4, users.size());
82 - }
83 -
84 - @Test
85 - public void usersBasicJson() {
86 - String json = cache.jsonUsers();
87 - System.out.println(json);
88 - assertTrue("bad users basic json", sameJson(USERS_BASIC, json));
89 - }
90 -
91 - @Test
92 - public void usersFamilyJson() {
93 - cache.setCurrentBundle("family");
94 - String json = cache.jsonUsers();
95 - System.out.println(json);
96 - assertTrue("bad users family json", sameJson(USERS_FAMILY, json));
97 - }
98 -
99 - @Test
100 - public void setNewLevel() {
101 - cache.setCurrentBundle("family");
102 - JsonNode node = fromString(cache.jsonUsers());
103 - assertEquals("wrong level", "G", getMomsLevel(node));
104 -
105 - cache.applyPerUserParam("1", "url_filter", "level", "R");
106 -
107 - node = fromString(cache.jsonUsers());
108 - assertEquals("wrong level", "R", getMomsLevel(node));
109 - }
110 -
111 - private String getMomsLevel(JsonNode node) {
112 - JsonNode mom = node.get("users").elements().next();
113 - assertEquals("wrong ID", 1, mom.get("id").asInt());
114 - return mom.get("profile").get("url_filter").get("level").asText();
115 - }
116 -
117 -
118 - // =============
119 -
120 - private JsonNode fromString(String s) {
121 - try {
122 - return MAPPER.readTree(s);
123 - } catch (IOException e) {
124 - System.out.println("Exception: " + e);
125 - }
126 - return null;
127 - }
128 -
129 - private boolean sameJson(String s1, String s2) {
130 - try {
131 - JsonNode tree1 = MAPPER.readTree(s1);
132 - JsonNode tree2 = MAPPER.readTree(s2);
133 - return tree1.equals(tree2);
134 - } catch (IOException e) {
135 - System.out.println("Exception: " + e);
136 - }
137 - return false;
138 - }
139 -
140 - private static final ObjectMapper MAPPER = new ObjectMapper();
141 -
142 - private static final String BASIC_BUNDLE_JSON = "{\n" +
143 - " \"bundle\": {\n" +
144 - " \"id\": \"basic\",\n" +
145 - " \"name\": \"Basic Bundle\",\n" +
146 - " \"desc\": \"Provides basic internet and firewall functions.\",\n" +
147 - " \"functions\": [\n" +
148 - " {\n" +
149 - " \"id\": \"internet\",\n" +
150 - " \"name\": \"Internet\",\n" +
151 - " \"desc\": \"Basic internet connectivity.\",\n" +
152 - " \"params\": {}\n" +
153 - " },\n" +
154 - " {\n" +
155 - " \"id\": \"firewall\",\n" +
156 - " \"name\": \"Firewall\",\n" +
157 - " \"desc\": \"Normal firewall protection.\",\n" +
158 - " \"params\": {}\n" +
159 - " }\n" +
160 - " ]\n" +
161 - " },\n" +
162 - " \"bundles\": [\n" +
163 - " {\n" +
164 - " \"id\": \"basic\",\n" +
165 - " \"name\": \"Basic Bundle\",\n" +
166 - " \"desc\": \"Provides basic internet and firewall functions.\"\n" +
167 - " },\n" +
168 - " {\n" +
169 - " \"id\": \"family\",\n" +
170 - " \"name\": \"Family Bundle\",\n" +
171 - " \"desc\": \"Provides internet, firewall and parental control functions.\"\n" +
172 - " }\n" +
173 - " ]\n" +
174 - "}\n";
175 -
176 - private static final String FAMILY_BUNDLE_JSON = "{\n" +
177 - " \"bundle\": {\n" +
178 - " \"id\": \"family\",\n" +
179 - " \"name\": \"Family Bundle\",\n" +
180 - " \"desc\": \"Provides internet, firewall and parental control functions.\",\n" +
181 - " \"functions\": [\n" +
182 - " {\n" +
183 - " \"id\": \"internet\",\n" +
184 - " \"name\": \"Internet\",\n" +
185 - " \"desc\": \"Basic internet connectivity.\",\n" +
186 - " \"params\": {}\n" +
187 - " },\n" +
188 - " {\n" +
189 - " \"id\": \"firewall\",\n" +
190 - " \"name\": \"Firewall\",\n" +
191 - " \"desc\": \"Normal firewall protection.\",\n" +
192 - " \"params\": {}\n" +
193 - " },\n" +
194 - " {\n" +
195 - " \"id\": \"url_filter\",\n" +
196 - " \"name\": \"Parental Control\",\n" +
197 - " \"desc\": \"Variable levels of URL filtering.\",\n" +
198 - " \"params\": {\n" +
199 - " \"level\": \"G\",\n" +
200 - " \"levels\": [\n" +
201 - " \"OFF\",\n" +
202 - " \"G\",\n" +
203 - " \"PG\",\n" +
204 - " \"PG_13\",\n" +
205 - " \"R\",\n" +
206 - " \"NONE\"\n" +
207 - " ]\n" +
208 - " }\n" +
209 - " }\n" +
210 - " ]\n" +
211 - " },\n" +
212 - " \"bundles\": [\n" +
213 - " {\n" +
214 - " \"id\": \"basic\",\n" +
215 - " \"name\": \"Basic Bundle\",\n" +
216 - " \"desc\": \"Provides basic internet and firewall functions.\"\n" +
217 - " },\n" +
218 - " {\n" +
219 - " \"id\": \"family\",\n" +
220 - " \"name\": \"Family Bundle\",\n" +
221 - " \"desc\": \"Provides internet, firewall and parental control functions.\"\n" +
222 - " }\n" +
223 - " ]\n" +
224 - "}\n";
225 -
226 - private static final String USERS_BASIC = "{\n" +
227 - " \"users\": [\n" +
228 - " {\n" +
229 - " \"id\": 1,\n" +
230 - " \"name\": \"Mom's MacBook\",\n" +
231 - " \"mac\": \"010203040506\",\n" +
232 - " \"profile\": { }\n" +
233 - " },\n" +
234 - " {\n" +
235 - " \"id\": 2,\n" +
236 - " \"name\": \"Dad's iPad\",\n" +
237 - " \"mac\": \"010203040507\",\n" +
238 - " \"profile\": { }\n" +
239 - " },\n" +
240 - " {\n" +
241 - " \"id\": 3,\n" +
242 - " \"name\": \"Dick's laptop\",\n" +
243 - " \"mac\": \"010203040508\",\n" +
244 - " \"profile\": { }\n" +
245 - " },\n" +
246 - " {\n" +
247 - " \"id\": 4,\n" +
248 - " \"name\": \"Jane's laptop\",\n" +
249 - " \"mac\": \"010203040509\",\n" +
250 - " \"profile\": { }\n" +
251 - " }\n" +
252 - " ]\n" +
253 - "}\n";
254 -
255 - private static final String USERS_FAMILY = "{\n" +
256 - " \"users\": [\n" +
257 - " {\n" +
258 - " \"id\": 1,\n" +
259 - " \"name\": \"Mom's MacBook\",\n" +
260 - " \"mac\": \"010203040506\",\n" +
261 - " \"profile\": {\n" +
262 - " \"url_filter\": {\n" +
263 - " \"level\": \"G\"\n" +
264 - " }\n" +
265 - " }\n" +
266 - " },\n" +
267 - " {\n" +
268 - " \"id\": 2,\n" +
269 - " \"name\": \"Dad's iPad\",\n" +
270 - " \"mac\": \"010203040507\",\n" +
271 - " \"profile\": {\n" +
272 - " \"url_filter\": {\n" +
273 - " \"level\": \"G\"\n" +
274 - " }\n" +
275 - " }\n" +
276 - " },\n" +
277 - " {\n" +
278 - " \"id\": 3,\n" +
279 - " \"name\": \"Dick's laptop\",\n" +
280 - " \"mac\": \"010203040508\",\n" +
281 - " \"profile\": {\n" +
282 - " \"url_filter\": {\n" +
283 - " \"level\": \"G\"\n" +
284 - " }\n" +
285 - " }\n" +
286 - " },\n" +
287 - " {\n" +
288 - " \"id\": 4,\n" +
289 - " \"name\": \"Jane's laptop\",\n" +
290 - " \"mac\": \"010203040509\",\n" +
291 - " \"profile\": {\n" +
292 - " \"url_filter\": {\n" +
293 - " \"level\": \"G\"\n" +
294 - " }\n" +
295 - " }\n" +
296 - " }\n" +
297 - " ]\n" +
298 - "}\n";
299 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import org.junit.Test;
21 -
22 -import java.util.Set;
23 -
24 -import static org.junit.Assert.*;
25 -import static org.onosproject.cord.gui.model.BundleFactory.*;
26 -import static org.onosproject.cord.gui.model.XosFunctionDescriptor.*;
27 -
28 -/**
29 - * Unit tests for {@link BundleFactory}.
30 - */
31 -public class BundleFactoryTest {
32 -
33 - @Test
34 - public void bundleCount() {
35 - assertEquals("wrong count", 2, availableBundles().size());
36 - assertTrue("missing basic", availableBundles().contains(BASIC_BUNDLE));
37 - assertTrue("missing family", availableBundles().contains(FAMILY_BUNDLE));
38 - }
39 -
40 - @Test
41 - public void basicBundle() {
42 - BundleDescriptor bundle = BundleFactory.BASIC_BUNDLE;
43 - assertEquals("wrong id", "basic", bundle.id());
44 - assertEquals("wrong id", "Basic Bundle", bundle.displayName());
45 - Set<XosFunctionDescriptor> funcs = bundle.functions();
46 - assertTrue("missing internet", funcs.contains(INTERNET));
47 - assertTrue("missing firewall", funcs.contains(FIREWALL));
48 - assertFalse("unexpected url-f", funcs.contains(URL_FILTER));
49 - }
50 -
51 - @Test
52 - public void familyBundle() {
53 - BundleDescriptor bundle = BundleFactory.FAMILY_BUNDLE;
54 - assertEquals("wrong id", "family", bundle.id());
55 - assertEquals("wrong id", "Family Bundle", bundle.displayName());
56 - Set<XosFunctionDescriptor> funcs = bundle.functions();
57 - assertTrue("missing internet", funcs.contains(INTERNET));
58 - assertTrue("missing firewall", funcs.contains(FIREWALL));
59 - assertTrue("missing url-f", funcs.contains(URL_FILTER));
60 - }
61 -
62 - @Test
63 - public void bundleFromIdBasic() {
64 - assertEquals("wrong bundle", BASIC_BUNDLE, bundleFromId("basic"));
65 - }
66 -
67 - @Test
68 - public void bundleFromIdFamily() {
69 - assertEquals("wrong bundle", FAMILY_BUNDLE, bundleFromId("family"));
70 - }
71 -
72 - @Test(expected = IllegalArgumentException.class)
73 - public void bundleFromIdUnknown() {
74 - bundleFromId("unknown");
75 - }
76 -}
77 -
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import org.junit.Before;
21 -import org.junit.Test;
22 -
23 -import static org.junit.Assert.assertEquals;
24 -import static org.junit.Assert.assertTrue;
25 -
26 -/**
27 - * Unit tests for {@link UrlFilterFunction}.
28 - */
29 -public class UrlFilterFunctionTest {
30 -
31 - private SubscriberUser user = new SubscriberUser(1, "foo", "fooMAC", "levelX");
32 - private UrlFilterFunction fn;
33 -
34 - @Before
35 - public void setUp() {
36 - fn = new UrlFilterFunction();
37 - }
38 -
39 - @Test
40 - public void basic() {
41 - assertEquals("wrong enum const count",
42 - 6, UrlFilterFunction.Level.values().length);
43 - }
44 -
45 - @Test
46 - public void memento() {
47 - XosFunction.Memento memo = fn.createMemento();
48 - assertTrue("wrong class", memo instanceof UrlFilterFunction.UrlFilterMemento);
49 - UrlFilterFunction.UrlFilterMemento umemo =
50 - (UrlFilterFunction.UrlFilterMemento) memo;
51 - assertEquals("wrong default level", "G", umemo.level());
52 - }
53 -
54 - @Test
55 - public void memoNewLevel() {
56 - XosFunction.Memento memo = fn.createMemento();
57 - assertTrue("wrong class", memo instanceof UrlFilterFunction.UrlFilterMemento);
58 - UrlFilterFunction.UrlFilterMemento umemo =
59 - (UrlFilterFunction.UrlFilterMemento) memo;
60 - assertEquals("wrong default level", "G", umemo.level());
61 - umemo.setLevel(UrlFilterFunction.Level.R);
62 - assertEquals("wrong new level", "R", umemo.level());
63 - }
64 -
65 - @Test
66 - public void applyMemo() {
67 - UrlFilterFunction.UrlFilterMemento memo =
68 - (UrlFilterFunction.UrlFilterMemento) fn.createMemento();
69 - memo.setLevel(UrlFilterFunction.Level.PG_13);
70 - user.setMemento(XosFunctionDescriptor.URL_FILTER, memo);
71 -
72 - assertEquals("wrong URL suffix", "url_filter/PG_13", fn.xosUrlApply(user));
73 - }
74 -}
1 -/*
2 - * Copyright 2015-present 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 - *
16 - */
17 -
18 -package org.onosproject.cord.gui.model;
19 -
20 -import org.junit.Test;
21 -
22 -import static org.junit.Assert.*;
23 -import static org.onosproject.cord.gui.model.XosFunctionDescriptor.*;
24 -
25 -/**
26 - * Sanity unit tests for {@link XosFunctionDescriptor}.
27 - */
28 -public class XosFunctionDescriptorTest {
29 -
30 - @Test
31 - public void numberOfFunctions() {
32 - assertEquals("unexpected constant count", 4, values().length);
33 - }
34 -
35 - @Test
36 - public void internet() {
37 - assertEquals("wrong id", "internet", INTERNET.id());
38 - assertEquals("wrong display", "Internet", INTERNET.displayName());
39 - assertTrue("wrong desc", INTERNET.description().startsWith("Basic"));
40 - assertFalse("wrong backend", INTERNET.backend());
41 - }
42 -
43 - @Test
44 - public void firewall() {
45 - assertEquals("wrong id", "firewall", FIREWALL.id());
46 - assertEquals("wrong display", "Firewall", FIREWALL.displayName());
47 - assertTrue("wrong desc", FIREWALL.description().startsWith("Normal"));
48 - assertTrue("wrong backend", FIREWALL.backend());
49 - }
50 -
51 - @Test
52 - public void urlFilter() {
53 - assertEquals("wrong id", "url_filter", URL_FILTER.id());
54 - assertEquals("wrong display", "Parental Control", URL_FILTER.displayName());
55 - assertTrue("wrong desc", URL_FILTER.description().startsWith("Variable"));
56 - assertTrue("wrong backend", URL_FILTER.backend());
57 - }
58 -
59 - @Test
60 - public void cdn() {
61 - assertEquals("wrong id", "cdn", CDN.id());
62 - assertEquals("wrong display", "CDN", CDN.displayName());
63 - assertTrue("wrong desc", CDN.description().startsWith("Content"));
64 - assertTrue("wrong backend", CDN.backend());
65 - }
66 -}