Coverage Report - org.kuali.student.common.ui.client.mvc.history.HistoryManager
 
Classes in this File Line Coverage Branch Coverage Complexity
HistoryManager
0%
0/93
0%
0/58
3.357
HistoryManager$1
0%
0/5
0%
0/2
3.357
HistoryManager$NavigationEventMonitor
0%
0/9
0%
0/2
3.357
HistoryManager$NavigationEventMonitor$1
0%
0/6
0%
0/2
3.357
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.mvc.history;
 17  
 
 18  
 import java.util.HashMap;
 19  
 import java.util.Iterator;
 20  
 import java.util.Map;
 21  
 
 22  
 import org.kuali.student.common.ui.client.application.ViewContext;
 23  
 import org.kuali.student.common.ui.client.mvc.Controller;
 24  
 import org.kuali.student.common.ui.client.mvc.breadcrumb.BreadcrumbManager;
 25  
 
 26  
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 27  
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
 28  
 import com.google.gwt.user.client.DOM;
 29  
 import com.google.gwt.user.client.Element;
 30  
 import com.google.gwt.user.client.History;
 31  
 import com.google.gwt.user.client.Timer;
 32  
 import com.google.gwt.user.client.Window;
 33  
 import com.google.gwt.user.client.ui.Hidden;
 34  
 
 35  0
 public class HistoryManager {
 36  0
     private static final NavigationEventMonitor monitor = new NavigationEventMonitor();
 37  0
         public static String VIEW_ATR = "view";
 38  
     private static Controller root;
 39  0
     private static boolean logNavigationHistory = true;
 40  
     private static Locations locations;
 41  
     
 42  
     public static void bind(Controller controller, Locations views) {
 43  0
             locations = views;
 44  0
         root = controller;
 45  0
         root.addApplicationEventHandler(NavigationEvent.TYPE, monitor);
 46  0
         History.addValueChangeHandler(new ValueChangeHandler<String>() {
 47  
 
 48  
             @Override
 49  
             public void onValueChange(ValueChangeEvent<String> event) {
 50  0
                 String token = event.getValue();
 51  0
                 if (token != null) {
 52  0
                     root.onHistoryEvent(token);
 53  
                 }
 54  0
             }
 55  
             
 56  
         });
 57  0
     }
 58  
     
 59  
     public static String[] splitHistoryStack(String historyStack){
 60  0
             return historyStack.split("/");
 61  
     }
 62  
     
 63  
     public static Map<String, String> getTokenMap(String token){
 64  0
             Map<String, String> pairs = new HashMap<String, String>();
 65  0
             String[] arr = token.split("&");
 66  0
             for (String s : arr) {
 67  0
                     if(s.contains("=")){
 68  0
                             String[] tmp = s.split("=");
 69  0
                             if(tmp.length == 2){
 70  0
                                     pairs.put(tmp[0], tmp[1]);
 71  
                             }
 72  0
                     }
 73  
                     else{
 74  
                             //view name do not have = sign required; for better readability
 75  
                             //putting a token without = sign as the view key
 76  0
                             pairs.put("view", s);
 77  
                     }
 78  
             }
 79  0
             return pairs;
 80  
     }
 81  
     
 82  
     public static String nextHistoryStack(String historyStack){
 83  0
             String[] arr= historyStack.split("/", 2);
 84  0
             if(arr.length == 2){
 85  0
                     return arr[1];
 86  
             }
 87  
             else{
 88  0
                     return "";
 89  
             }
 90  
     }
 91  
     
 92  
     public static void processWindowLocation(){
 93  0
             boolean navigateSuccess = false;
 94  0
             Element loc = DOM.getElementById("locationHash");
 95  
             //String value = loc.getValue().trim();
 96  0
             String value = loc.getAttribute("value");
 97  0
             if(value != null && !value.equals("") && value.startsWith("/")){
 98  0
                     navigate(value);
 99  
             }
 100  0
             else if(Window.Location.getQueryString() != null && 
 101  
                             !Window.Location.getQueryString().isEmpty()){
 102  0
                     String view = Window.Location.getParameter(VIEW_ATR);
 103  0
                     String docId = Window.Location.getParameter(ViewContext.ID_ATR);
 104  0
                     String idType = Window.Location.getParameter(ViewContext.ID_TYPE_ATR);
 105  0
                     if(view != null && docId != null && idType != null){
 106  0
                             String path = locations.getLocation(view);
 107  0
                             if(path != null){
 108  0
                                     ViewContext context = new ViewContext();
 109  0
                                     context.setIdType(idType);
 110  0
                                     context.setId(docId);
 111  0
                                     navigate(path, context);
 112  0
                                     navigateSuccess = true;
 113  
                             }
 114  0
                     }else if(view != null && docId != null){
 115  0
                             String path = locations.getLocation(view);
 116  0
                             if(path != null){
 117  0
                                     ViewContext context = new ViewContext();
 118  0
                                     context.setId(docId);
 119  0
                                     navigate(path, context);
 120  0
                                     navigateSuccess = true;
 121  
                             }
 122  0
                     }
 123  0
                     else if(view != null){
 124  0
                             String path = locations.getLocation(view);
 125  0
                             navigate(path);
 126  0
                                 navigateSuccess = true;
 127  
                     }
 128  
             }
 129  0
             if(!navigateSuccess){
 130  0
                     navigate(Window.Location.getHash().trim());
 131  
             }
 132  0
     }
 133  
     
 134  
     public static void navigate(String path){
 135  0
             if(path != null && !path.isEmpty() && path.startsWith("/")){
 136  0
                     logNavigationHistory = false;
 137  0
                     root.onHistoryEvent(path);
 138  0
                     logHistoryChange();
 139  0
                     logNavigationHistory = true;
 140  
             }
 141  0
     }
 142  
     
 143  
     public static String collectHistoryStack() {
 144  0
         String result = root.collectHistory("");
 145  0
                 if(result == null){
 146  0
                         result = "";
 147  
                 }
 148  0
         return result;
 149  
     }
 150  
     
 151  
     public static void logHistoryChange() {
 152  0
         String historyStack = collectHistoryStack();
 153  0
         if(historyStack.endsWith("/")){
 154  0
                 historyStack = historyStack.substring(0, historyStack.length()-1);
 155  
         }
 156  0
         String currentToken = History.getToken();
 157  0
         if(!currentToken.equals(historyStack)){
 158  0
                 History.newItem(historyStack, false);
 159  
         }
 160  0
         BreadcrumbManager.updateLinks(historyStack);
 161  0
     }
 162  
     
 163  0
     private static class NavigationEventMonitor implements NavigationEventHandler{
 164  
         private static final int EVENT_DELAY = 100;
 165  0
         private long lastEvent = -1;
 166  
         
 167  0
         private final Timer timer = new Timer() {
 168  
 
 169  
             @Override
 170  
             public void run() {
 171  0
                 if (lastEvent < (System.currentTimeMillis()-EVENT_DELAY)) {
 172  0
                     this.cancel();
 173  0
                     lastEvent = -1;
 174  0
                     logHistoryChange();
 175  
                 }
 176  0
             }
 177  
             
 178  
         };
 179  
         
 180  
         @Override
 181  
         public void onNavigationEvent(NavigationEvent event) {
 182  0
                 if(logNavigationHistory){
 183  0
                         logHistoryChange();
 184  
                 }
 185  
                 else{
 186  0
                         String historyStack = collectHistoryStack();
 187  0
                         BreadcrumbManager.updateLinks(historyStack);
 188  0
                         HistoryManager.setLogNavigationHistory(true);
 189  
                 }
 190  0
         }
 191  
     }
 192  
     
 193  
     public static void setLogNavigationHistory(boolean log){
 194  0
             logNavigationHistory = log;
 195  0
     }
 196  
 
 197  
         public static void navigate(String path, ViewContext context) {
 198  0
                 path = appendContext(path, context);
 199  0
                 navigate(path);
 200  
                 
 201  0
         }
 202  
 
 203  
         public static String appendContext(String path, ViewContext context) {
 204  0
                 if(context.getId() != null && !context.getId().isEmpty()){
 205  0
                         path = path + "&" + ViewContext.ID_ATR + "=" + context.getId();
 206  
                 }
 207  0
                 if(context.getIdType() != null){
 208  0
                         path = path + "&" + ViewContext.ID_TYPE_ATR + "=" + context.getIdType();
 209  
                 }
 210  0
                 if(!context.getAttributes().isEmpty()){
 211  0
                         Map<String,String> attributes = context.getAttributes();
 212  0
                         Iterator<String> it = attributes.keySet().iterator();
 213  0
                         while(it.hasNext()){
 214  0
                                 String key = it.next();
 215  0
                                 String value = attributes.get(key);
 216  0
                                 path = path + "&" + key + "=" + value;
 217  0
                         }
 218  
                 }
 219  
                 //TODO add the ability for view context to add a variety of additional attributes
 220  0
                 return path;
 221  
         }
 222  
 }