001 package org.kuali.student.common.ui.client.mvc.breadcrumb;
002
003 import java.util.ArrayList;
004 import java.util.List;
005
006 import org.kuali.student.common.ui.client.mvc.Controller;
007 import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
008 import org.kuali.student.common.ui.client.widgets.field.layout.element.SpanPanel;
009
010 import com.google.gwt.user.client.ui.ComplexPanel;
011 import com.google.gwt.user.client.ui.Composite;
012 import com.google.gwt.user.client.ui.Hyperlink;
013 import com.google.gwt.user.client.ui.InlineLabel;
014 import com.google.gwt.user.client.ui.Panel;
015 import com.google.gwt.user.client.ui.Widget;
016
017 /**
018 * Manages breadcrumbs for the application
019 *
020 * @author Kuali Student Team
021 *
022 */
023 public class BreadcrumbManager extends Composite{
024
025 public static List<Hyperlink> links = new ArrayList<Hyperlink>();
026
027 private static List<String> names = new ArrayList<String>();
028
029 private static Controller root;
030 private static ComplexPanel panel = new SpanPanel();
031 private static boolean panelEmpty = true;
032
033 private static Panel parentPanel;
034
035 private static class BreadcrumbData{
036 private String name;
037 private String path;
038 public BreadcrumbData(String name, String path) {
039 super();
040 this.name = name;
041 this.path = path;
042 }
043 }
044
045 /**
046 * Binds the controller as the top level controller to call collectBreadcrumbNames on.
047 *
048 * @param controller
049 */
050 public static void bind(Controller controller){
051 root = controller;
052 }
053
054 /**
055 * Updates the breadcrumb panel with the current breadcrumb by walking the controller hierarchy by calling
056 * collectBreadcrumbNames on the root controller bound to the BreadcrumbManager.
057 *
058 * @param historyStack
059 */
060 public static void updateLinks(String historyStack){
061 if (root == null){
062 return;
063 }
064
065 links.clear();
066 panel.clear();
067 panelEmpty = true;
068 names.clear();
069 root.collectBreadcrumbNames(names);
070
071 String[] arr = HistoryManager.splitHistoryStack(historyStack);
072 List<BreadcrumbData> breadcrumbs = new ArrayList<BreadcrumbData>();
073
074 if(arr.length == names.size()){
075 String path = "";
076 //account for applicationController - skip first item from both
077 for(int i = 1; i < names.size(); i++){
078 path = path + "/" + arr[i];
079 String name = names.get(i);
080 //Views with empty names do not appear on the breadcrumbs
081 if(name != null && !name.isEmpty()){
082 breadcrumbs.add(new BreadcrumbData(name, path));
083 }
084 }
085 }
086 //Special link, a controller is adding a breadcrumb outside the scope of the current controller
087 //in format name@path
088 else if(names.size() > arr.length){
089 String path = "";
090 int j = 1;
091 //account for applicationController - skip first item from both
092 for(int i = 1; i < names.size(); i++){
093 String name = names.get(i);
094 if(name.contains("@")){
095 String[] split = name.split("@");
096 name = split[0];
097 if(name != null && !name.isEmpty()){
098 //In the special case the path is the second part of the split
099 breadcrumbs.add(new BreadcrumbData(name, split[1]));
100 }
101 }
102 else{
103 if(j == arr.length){
104 break;
105 }
106 path = path + "/" + arr[j];
107 j++;
108 if(name != null && !name.isEmpty()){
109 breadcrumbs.add(new BreadcrumbData(name, path));
110 }
111 }
112 }
113 }
114
115 if(parentPanel != null){
116 if(breadcrumbs.size() == 1){
117 panel.getParent().setVisible(false);
118 }
119 else{
120 panel.getParent().setVisible(true);
121
122 }
123 }
124
125 for(int i = 0; i < breadcrumbs.size(); i++){
126 if(i < breadcrumbs.size() - 1){
127 createLink(breadcrumbs.get(i).name, breadcrumbs.get(i).path);
128 }
129 else{
130 createLabel(breadcrumbs.get(i).name);
131 //WindowTitleUtils.setSubtitle(breadcrumbs.get(i).name);
132 }
133 }
134 }
135
136 private static void createLabel(String name){
137 addToPanel(new InlineLabel(name));
138 }
139
140 private static void createLink(String name, final String viewPath){
141 Hyperlink link = new Hyperlink(name, viewPath);
142 links.add(link);
143 addToPanel(link);
144 }
145
146 private static void addToPanel(Widget w){
147 if(panelEmpty){
148 panel.add(w);
149 panelEmpty = false;
150 }
151 else{
152 panel.add(new InlineLabel(" \u00BB "));
153 panel.add(w);
154 }
155 }
156
157 /**
158 * @return the breadcrumb panel which contains the breadcrumb links dynamically updated by the
159 * BreadcrumbManager
160 */
161 public static ComplexPanel getBreadcrumbPanel(){
162 return panel;
163 }
164
165 public static void setParentPanel(Panel panel){
166 parentPanel = panel;
167 parentPanel.setVisible(false);
168 }
169
170 }