/* * Copyright (C) 2013 The Android Open Source Project * * 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 com.android.navigation; import com.android.annotations.NonNull; import com.android.annotations.Transient; import java.util.*; public class NavigationModel { public static class Event { public enum Operation {INSERT, UPDATE, DELETE} public final Operation operation; public final Class<?> operandType; public Event(@NonNull Operation operation, @NonNull Class operandType) { this.operation = operation; this.operandType = operandType; } public static Event of(@NonNull Operation operation, @NonNull Class operandType) { return new Event(operation, operandType); } public static Event insert(@NonNull Class operandType) { return of(Operation.INSERT, operandType); } public static Event update(@NonNull Class operandType) { return of(Operation.UPDATE, operandType); } public static Event delete(@NonNull Class operandType) { return of(Operation.DELETE, operandType); } } private final EventDispatcher<Event> listeners = new EventDispatcher<Event>(); private final ArrayList<State> states = new ArrayList<State>(); private final ArrayList<Transition> transitions = new ArrayList<Transition>(); private final Map<State, Point> stateToLocation = new HashMap<State, Point>(); // todo change return type to List<State> @Transient public ArrayList<State> getStates() { return states; } @Transient public ArrayList<Transition> getTransitions() { return transitions; } @Transient public Map<State, Point> getStateToLocation() { return stateToLocation; } private static Entry<State, Point> toEntry(Map.Entry<State, Point> entry) { return new Entry<State, Point>(entry.getKey(), entry.getValue()); } public Collection<Entry<State,Point>> getLocations() { Collection<Entry<State, Point>> result = new ArrayList<Entry<State, Point>>(); for (Map.Entry<State, Point> entry : stateToLocation.entrySet()) { result.add(toEntry(entry)); } return result; } public void setLocations(Collection<Entry<State,Point>> locations) { for (Entry<State, Point> entry : locations) { stateToLocation.put(entry.key, entry.value); } } public void addState(State state) { if (states.contains(state)) { return; } states.add(state); listeners.notify(Event.insert(State.class)); } public void removeState(State state) { states.remove(state); for (Transition t : new ArrayList<Transition>(transitions)) { if (t.getSource().getState() == state || t.getDestination().getState() == state) { remove(t); } } listeners.notify(Event.delete(State.class)); } private void updateStates(State state) { if (!states.contains(state)) { states.add(state); } } public boolean add(Transition transition) { boolean result = transitions.add(transition); // todo remove this updateStates(transition.getSource().getState()); updateStates(transition.getDestination().getState()); listeners.notify(Event.insert(Transition.class)); return result; } public boolean remove(Transition transition) { boolean result = transitions.remove(transition); listeners.notify(Event.delete(Transition.class)); return result; } @Transient public Map<String, ActivityState> getActivities() { Map<String, ActivityState> activities = new HashMap<String, ActivityState>(); for (State state : states) { if (state instanceof ActivityState) { ActivityState activityState = (ActivityState)state; activities.put(activityState.getClassName(), activityState); } } return activities; } @Transient public Map<String, MenuState> getMenus() { Map<String, MenuState> menus = new HashMap<String, MenuState>(); for (State state : states) { if (state instanceof MenuState) { MenuState menuState = (MenuState)state; menus.put(menuState.getXmlResourceName(), menuState); } } return menus; } public void clear() { states.clear(); transitions.clear(); listeners.notify(Event.delete(Object.class)); } @Transient public EventDispatcher<Event> getListeners() { return listeners; } // todo either bury the superclass's API or re-implement all of its destructive methods to post an update event }