Java tutorial
/* * Copyright 2010 kk-electronic a/s. * * This file is part of KKPortal. * * KKPortal is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * KKPortal is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with KKPortal. If not, see <http://www.gnu.org/licenses/>. * */ package com.kk_electronic.kkportal.core; import java.util.HashMap; import java.util.Map; import com.google.gwt.core.client.GWT; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.History; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.inject.name.Named; import com.kk_electronic.kkportal.core.activity.LocationInfo; import com.kk_electronic.kkportal.core.inject.ConstructFromLiteral; import com.kk_electronic.kkportal.core.inject.FlexInjector; import com.kk_electronic.kkportal.core.reflection.ActivityMap; import com.kk_electronic.kkportal.core.ui.ApplicationLayout; /** * This class is responsible for history management in a browser and for * selection the entry point class. * * The History token is encoded like this: * value;key=value;key=value;key=value... where key is unique and null if not * specified. * * The null key value (that is the value without a key) is used the the * selecting main navigation. * * This is done using the ActivityMap which maps strings to the Activity class * * @author Jes Andersen */ @ConstructFromLiteral /* We make this class can be created using the injection framework */ @Singleton /* And hint that only one such class such exist */ public class ActivityManager implements ValueChangeHandler<String> { private final ApplicationLayout display; private final FlexInjector injector; private final ActivityMap activityMap; private final String defaultplace; private final LocationInfo locationInfo; @Inject public ActivityManager(ApplicationLayout layout, FlexInjector injector, ActivityMap activityMap, @Named("DefaultHistoryToken") String defaultplace, LocationInfo locationInfo) { this.injector = injector; this.activityMap = activityMap; this.defaultplace = defaultplace; this.display = layout; this.locationInfo = locationInfo; /* * We create the initial GUI elements needed for displaying activities. */ layout.go(); History.addValueChangeHandler(this); /* * If we do not have anything in the history stack de go to the default * view TODO: Decide if we should redirect like here or just show it */ if ("".equals(History.getToken())) { goHome(); } else { /* * If we have a history token we fire the change event which handles * setup of the activity */ History.fireCurrentHistoryState(); } } /** * Return the application to the default home activity */ public void goHome() { History.newItem(defaultplace); } /** * Change location to the new place * * @param place * new location to go to */ public void go(Class<? extends Activity> place) { String placename = activityMap.getKeyFromClass(place); if (placename == null) { GWT.log("Place not found for activity: " + place.getName()); } History.newItem(placename); } /** * This is called either when the user loads the page for the first time or * when the user switches places. * * It is not meant to be called directly, but implicit via * {@link #go(Class)} */ @Override public void onValueChange(ValueChangeEvent<String> event) { Map<String, String> tokens = parseToken(event.getValue()); if (!tokens.containsKey(null)) { GWT.log("History Token has no location - returning to home page"); goHome(); } else { Class<? extends Activity> mainActivity = getActityFromLocation(tokens); if (mainActivity != null) { injector.create(mainActivity, new AsyncCallback<Activity>() { @Override public void onFailure(Throwable caught) { GWT.log("Unable to start requested Presenter", caught); } @Override public void onSuccess(Activity result) { display.displayActivity(result); } }); } else { GWT.log("Unknown location - returning to home page"); goHome(); return; } } } /** * This one trims the place name a bit before using activitymap to lookup * the name. It is done to provide some nice looking urls. Everything after * $ or / is cut off * * @param tokens * a map if input tokens, where the null key is the main * navigation element * @return the class matching the token set */ private Class<? extends Activity> getActityFromLocation(Map<String, String> tokens) { String location = tokens.get(null); String[] matches = location.split("[/$]", 2); GWT.log("mainplace: " + matches[0]); if (matches.length > 1) { switch (location.charAt(matches[0].length())) { case '/': locationInfo.setSubint(null); locationInfo.setSubpath(matches[1]); break; case '$': locationInfo.setSubpath(null); locationInfo.setSubint(Integer.valueOf(matches[1])); break; default: GWT.log("ActivityManager:Problems with history token" + location); } } return activityMap.getClassFromKey(matches[0]); } /** * Decode the map like described in {@link ActivityManager} * * If an invalid rawString is provided it returns to the home activity * * @param rawHistoryString * the anchor part of the current url * @return a map of parameters */ private Map<String, String> parseToken(String rawHistoryString) { HashMap<String, String> parameterMap = new HashMap<String, String>(); parameterMap.clear(); String[] values = rawHistoryString.split(";"); for (String placestring : values) { String[] l = placestring.split("[=]", 2); if (l.length > 1) { assert (!parameterMap.containsKey(l[0])); parameterMap.put(l[0], l[1]); } else { if (!parameterMap.containsKey(null)) { parameterMap.put(null, l[0]); } else { if (!parameterMap.containsKey(l[0])) { GWT.log("History Contains Duplicate items - returning to home page"); goHome(); } parameterMap.put(l[0], ""); } } } return parameterMap; } }