/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.webapp.gwt.notification; import org.onebusaway.webapp.gwt.common.rpc.JsonLibrary; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONBoolean; import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONValue; import com.google.gwt.user.client.Cookies; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class NotificationStateDAO { private static final String COOKIE_NAME = "OBANotifications"; private static final String DEFAULT_ID = "_"; private static final int MAX_NODE_COUNT = 5; /**** * JSON Keys ****/ private static final String KEY_ID = "id"; private static final String KEY_INDEX = "in"; private static final String KEY_STATE = "st"; private static final String KEY_MINUTES_BEFORE = "mb"; private static final String KEY_METHODS = "ms"; private static final String KEY_ENABLED = "en"; /**** * Public Methods ****/ public void setState(String stopId, NotificationState state, boolean isDefault) { List<NotificationStateNode> nodes = loadState(); NotificationStateNode match = null; for (NotificationStateNode node : nodes) { if ((isDefault && node.getStopId().equals(DEFAULT_ID)) || (!isDefault && node.getStopId().equals(stopId))) { match = node; break; } } if (match == null) { match = new NotificationStateNode(); match.setStopId(isDefault ? DEFAULT_ID : stopId); nodes.add(match); } match.setState(state); reorderNodes(nodes, match); saveState(nodes); } public NotificationState getState(String stopId) { List<NotificationStateNode> nodes = loadState(); NotificationStateNode defaultState = null; for (NotificationStateNode node : nodes) { if (stopId.equals(node.getStopId())) return node.getState(); else if (DEFAULT_ID.equals(node.getStopId())) defaultState = node; } if (defaultState != null) return defaultState.getState(); NotificationState state = new NotificationState(); state.setMinutesBefore(5); return state; } /**** * Private Methods ****/ private void reorderNodes(List<NotificationStateNode> nodes, NotificationStateNode match) { int min = Integer.MAX_VALUE; for (NotificationStateNode node : nodes) min = Math.min(node.getIndex(), min); match.setIndex(min - 1); for (NotificationStateNode node : nodes) { if (node.getStopId().equals(DEFAULT_ID)) node.setIndex(min - 2); } Collections.sort(nodes); while (nodes.size() > MAX_NODE_COUNT) nodes.remove(nodes.size() - 1); int index = 0; for (NotificationStateNode node : nodes) node.setIndex(index++); } private List<NotificationStateNode> loadState() { List<NotificationStateNode> nodes = new ArrayList<NotificationStateNode>(); String cookieValue = Cookies.getCookie(COOKIE_NAME); if (cookieValue != null) { System.out.println("loading=" + cookieValue); JSONValue p = JSONParser.parse(cookieValue); JSONArray array = p.isArray(); if (array != null) { for (int i = 0; i < array.size(); i++) { JSONValue entryValue = array.get(i); NotificationStateNode node = getJSONValueAsNode(entryValue); if (node != null) nodes.add(node); } } } return nodes; } private NotificationStateNode getJSONValueAsNode(JSONValue entryValue) { JSONObject object = entryValue.isObject(); if (object == null) return null; NotificationStateNode node = new NotificationStateNode(); String stopId = JsonLibrary.getJsonString(object, KEY_ID); if (stopId == null) return null; node.setStopId(stopId); Double index = JsonLibrary.getJsonDouble(object, KEY_INDEX); if (index == null) return null; node.setIndex(index.intValue()); JSONObject stateObject = JsonLibrary.getJsonObj(object, KEY_STATE); if (stateObject == null) return null; NotificationState state = getJSONObjectAsState(stateObject); if (state == null) return null; node.setState(state); return node; } private NotificationState getJSONObjectAsState(JSONObject object) { NotificationState state = new NotificationState(); Double minutesBefore = JsonLibrary.getJsonDouble(object, KEY_MINUTES_BEFORE); if (minutesBefore == null) return null; state.setMinutesBefore(minutesBefore.intValue()); JSONArray jsonArray = JsonLibrary.getJsonArray(object, KEY_METHODS); if (jsonArray != null) { for (int i = 0; i < jsonArray.size(); i++) { JSONValue value = jsonArray.get(i); JSONObject methodObject = value.isObject(); if (methodObject != null) { NotificationMethodState methodState = getJSONObjectAsMethodState(methodObject); if (methodState != null) state.getMethodStates().add(methodState); } } } return state; } private NotificationMethodState getJSONObjectAsMethodState(JSONObject object) { NotificationMethodState state = new NotificationMethodState(); String id = JsonLibrary.getJsonString(object, KEY_ID); if (id == null) return null; state.setId(id); Boolean enabled = JsonLibrary.getJsonBoolean(object, KEY_ENABLED); if (enabled == null) return null; state.setEnabled(enabled.booleanValue()); return state; } /**** * ****/ private void saveState(List<NotificationStateNode> nodes) { JSONArray array = new JSONArray(); int index = 0; for (NotificationStateNode node : nodes) array.set(index++, getNodeAsJSONObject(node)); System.out.println("saving=" + array.toString()); Cookies.setCookie(COOKIE_NAME, array.toString()); } private JSONObject getNodeAsJSONObject(NotificationStateNode node) { JSONObject obj = new JSONObject(); obj.put(KEY_ID, new JSONString(node.getStopId())); obj.put(KEY_INDEX, new JSONNumber(node.getIndex())); obj.put(KEY_STATE, getStateAsJSONObject(node.getState())); return obj; } private JSONObject getStateAsJSONObject(NotificationState state) { JSONObject obj = new JSONObject(); obj.put(KEY_MINUTES_BEFORE, new JSONNumber(state.getMinutesBefore())); JSONArray methods = new JSONArray(); int index = 0; for (NotificationMethodState methodState : state.getMethodStates()) { JSONObject methodObject = getMethodStateAsJSONObject(methodState); methods.set(index++, methodObject); } obj.put(KEY_METHODS, methods); return obj; } private JSONObject getMethodStateAsJSONObject(NotificationMethodState methodState) { JSONObject obj = new JSONObject(); obj.put(KEY_ID, new JSONString(methodState.getId())); obj.put(KEY_ENABLED, JSONBoolean.getInstance(methodState.isEnabled())); return obj; } }