Coverage Report - org.kuali.student.common.ui.client.application.ApplicationContext
 
Classes in this File Line Coverage Branch Coverage Complexity
ApplicationContext
0%
0/169
0%
0/96
2.688
ApplicationContext$1
0%
0/6
N/A
2.688
ApplicationContext$2
0%
0/1
N/A
2.688
 
 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.application;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.HashSet;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 import java.util.Map.Entry;
 25  
 
 26  
 import org.kuali.student.common.assembly.data.Metadata;
 27  
 import org.kuali.student.common.assembly.data.MetadataInterrogator;
 28  
 import org.kuali.student.common.messages.dto.Message;
 29  
 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
 30  
 import org.kuali.student.common.ui.client.mvc.Callback;
 31  
 import org.kuali.student.common.ui.client.mvc.HasCrossConstraints;
 32  
 import org.kuali.student.common.ui.client.security.SecurityContext;
 33  
 import org.kuali.student.common.ui.client.service.ServerPropertiesRpcService;
 34  
 import org.kuali.student.common.ui.client.service.ServerPropertiesRpcServiceAsync;
 35  
 import org.kuali.student.common.ui.client.validator.ValidationMessageKeys;
 36  
 import org.kuali.student.common.util.MessageUtils;
 37  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 38  
 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
 39  
 
 40  
 import com.google.gwt.core.client.GWT;
 41  
 
 42  
 /**
 43  
  * The application contains information about who is currently logged in, the security context, and access
 44  
  * to messages loaded from the message service in the app.  It provides and a static way to obtain this
 45  
  * information across the entire app.
 46  
  * 
 47  
  * @author Kuali Student
 48  
  *
 49  
  */
 50  0
 public class ApplicationContext {
 51  0
         private ServerPropertiesRpcServiceAsync serverPropertiesRpcService = GWT.create(ServerPropertiesRpcService.class);                        
 52  0
         private String version = "KS";
 53  
         
 54  0
         private Map<String, Map<String, String>> messages = new HashMap<String, Map<String,String>>();
 55  0
         private Map<String, String> flatMessages = new HashMap<String, String>();
 56  0
         private List<Message> messagesList = new ArrayList<Message>();
 57  
         
 58  
         private SecurityContext securityContext;
 59  
         private String applicationContextUrl;
 60  
         
 61  
         //These maps are used to store query paths to their corresponding fieldDefinitions, and also whcih fields have cross constraints
 62  0
         private String parentPath = "";
 63  0
         private HashMap<String,HashMap<String,FieldDescriptor>> pathToFieldMapping = new HashMap<String,HashMap<String,FieldDescriptor>>();
 64  0
         private HashMap<String,HashMap<String,HashSet<HasCrossConstraints>>> crossConstraints = new HashMap<String,HashMap<String,HashSet<HasCrossConstraints>>>();
 65  0
         private List<ValidationResultInfo> validationWarnings = new ArrayList<ValidationResultInfo>();
 66  
 
 67  
         /**
 68  
          * This constructor should only be visible to the common application package. If ApplicationContext is 
 69  
          * required outside this package do Application.getApplicationContext();
 70  
          */
 71  0
         protected ApplicationContext() {                
 72  0
         }
 73  
 
 74  
         /**
 75  
          * This makes server side calls to initialize the application and application security context.
 76  
          * 
 77  
          */
 78  
         public void initializeContext(final Callback<Boolean> contextIntializedCallback){
 79  0
                 serverPropertiesRpcService.getContextPath(new KSAsyncCallback<String>(){
 80  
 
 81  
                         @Override
 82  
                         public void onFailure(Throwable caught) {
 83  0
                                 throw new RuntimeException("Fatal - Unable to initialze application context");
 84  
                         }
 85  
 
 86  
                         @Override
 87  
                         public void onSuccess(String result) {
 88  0
                                 applicationContextUrl = result;
 89  0
                                 securityContext = new SecurityContext();
 90  0
                                 securityContext.initializeSecurityContext(contextIntializedCallback);
 91  0
                         }                        
 92  
                 });
 93  0
         }
 94  
         
 95  
         /**
 96  
      * Adds the messages in the list of messages to the map of the messages
 97  
      * @param messages
 98  
      */
 99  
     public void addMessages(List<Message> messages) {
 100  0
                 messagesList.addAll(messages);
 101  0
             for (Message m : messages) {
 102  0
                 String groupName = m.getGroupName();
 103  0
                 Map<String, String> group = this.messages.get(groupName);
 104  0
                 if (group == null) {
 105  0
                     group = new HashMap<String, String>();
 106  0
                     this.messages.put(groupName, group);
 107  
                 }
 108  0
                 group.put(m.getId(), m.getValue());
 109  0
                 flatMessages.put(m.getId(), m.getValue());
 110  0
             }
 111  0
         }
 112  
         
 113  
         /**
 114  
          * Get a message by a unique id
 115  
          */
 116  
         public String getMessage(String messageId) {
 117  0
             return flatMessages.get(messageId);
 118  
     }
 119  
     
 120  
         /**
 121  
          * Returns all the messages in the ApplicationContext
 122  
          */
 123  
         public List<Message> getMessages() {
 124  0
             return messagesList;
 125  
     }
 126  
     
 127  
         
 128  
         /**
 129  
          * Get message by the group it is in and its unique id within that group
 130  
          */
 131  
         public String getMessage(String groupName, String messageId) {
 132  
                         
 133  0
             String result = null;
 134  
             
 135  0
             Map<String, String> group = this.messages.get(groupName);
 136  0
             if (group != null) {
 137  0
                 result = group.get(messageId);
 138  
             }
 139  
             
 140  0
             return result;
 141  
         }
 142  
         
 143  
     /**
 144  
      * 
 145  
      * This method looks up a UI Label in the messages cache.  
 146  
      * First looks for a label specific to the type and state of the field.
 147  
      * If none found try for a generalized label.
 148  
      * Otherwise return the supplied fieldId
 149  
      * Groups provide namespace for same label ids within different LUs
 150  
      * 
 151  
      * @param groupName - for example 'course' or 'program'
 152  
      * @param type
 153  
      * @param state
 154  
      * @param fieldId
 155  
      * @return
 156  
      */
 157  
          public String getUILabel(String groupName, String type, String state, String fieldId) {
 158  
 
 159  0
         String label = getMessage(groupName, type + ":" + state + ":" + fieldId);
 160  
         
 161  0
         if (label == null)
 162  0
             label = getMessage(groupName, fieldId);
 163  
         
 164  0
         if (label == null)
 165  0
             label =  fieldId;
 166  
         
 167  0
         return label;
 168  
         
 169  
     }
 170  
          
 171  
         /**
 172  
          * Same as getUILabel(String groupName, String type, String state, String fieldId) with no
 173  
          * type and state needed
 174  
          */
 175  
         public String getUILabel(String groupName, String fieldId) {
 176  
 
 177  0
                 String label = getMessage(groupName, fieldId);
 178  
                 
 179  0
                 if (label == null)
 180  0
                     label =  fieldId;
 181  
                 
 182  0
                 return label;
 183  
                 
 184  
         }
 185  
         
 186  
     public String getUILabel(String groupName, String type, String state, String fieldId, Metadata metadata) {
 187  
 
 188  0
         String label = getMessage(groupName, type + ":" + state + ":" + fieldId);
 189  
 
 190  0
         if (label == null)
 191  0
             label = getMessage(groupName, fieldId);
 192  
 
 193  0
         if (label == null)
 194  0
             label = fieldId;
 195  
 
 196  0
         return MessageUtils.interpolate(label, getConstraintInfo(metadata, label));
 197  
 
 198  
     }
 199  
         
 200  
     public String getUILabel(String groupName, String fieldId, Metadata metadata) {
 201  
 
 202  0
         String label = getMessage(groupName, fieldId);
 203  
 
 204  0
         if (label == null)
 205  0
             label = fieldId;
 206  
 
 207  0
         return MessageUtils.interpolate(label, getConstraintInfo(metadata, label));
 208  
 
 209  
     }
 210  
         
 211  
     public String getUILabel(String groupName, String fieldId, Map<String, Object> parameters) {
 212  
 
 213  0
         String label = getMessage(groupName, fieldId);
 214  
 
 215  0
         if (label == null)
 216  0
             label = fieldId;
 217  
 
 218  0
         return MessageUtils.interpolate(label, parameters);
 219  
 
 220  
     }
 221  
 
 222  
     /**
 223  
      * Get the security context for the app
 224  
      * @return SecurityContext
 225  
      */
 226  
     public SecurityContext getSecurityContext() {
 227  0
         return securityContext;
 228  
     }
 229  
 
 230  
     public void setSecurityContext(SecurityContext securityContext) {
 231  0
         this.securityContext = securityContext;
 232  0
     }
 233  
         
 234  
         /**
 235  
          * Application URL based on the serverPropertiesRPC service result
 236  
          */
 237  
         public String getApplicationContextUrl() {
 238  0
                 return applicationContextUrl;
 239  
         }
 240  
 
 241  
         public void setVersion(String version) {
 242  0
                 this.version = version;
 243  0
         }
 244  
 
 245  
         public String getVersion() {
 246  0
                 return version;
 247  
         }
 248  
         
 249  
         /**
 250  
          * Adds a mapping from path to a list of field descriptors for a given namespace
 251  
          * namespace defaults to _default if null
 252  
          * @param path
 253  
          * @param fd
 254  
          */
 255  
         public void putCrossConstraint(String namespace, String path, HasCrossConstraints fd){
 256  0
                 if(namespace==null){
 257  0
                         namespace="_default";
 258  
                 }
 259  
                 
 260  0
                 HashMap<String,HashSet<HasCrossConstraints>> crossConstraintMap = crossConstraints.get(namespace);
 261  0
                 if(crossConstraintMap==null){
 262  0
                         crossConstraintMap = new HashMap<String,HashSet<HasCrossConstraints>>();
 263  0
                         crossConstraints.put(namespace, crossConstraintMap);
 264  
                 }
 265  0
                 HashSet<HasCrossConstraints> fieldDescriptors = crossConstraintMap.get(path);
 266  0
                 if(fieldDescriptors == null){
 267  0
                         fieldDescriptors = new HashSet<HasCrossConstraints>();
 268  0
                         crossConstraintMap.put(path, fieldDescriptors);
 269  
                 }
 270  0
                 fieldDescriptors.add(fd);
 271  0
         }
 272  
 
 273  
         
 274  
         
 275  
         public HashSet<HasCrossConstraints> getCrossConstraint(String namespace, String path){
 276  0
                 if(namespace==null){
 277  0
                         namespace="_default";
 278  
                 }
 279  0
                 HashMap<String,HashSet<HasCrossConstraints>> crossConstraintMap = crossConstraints.get(namespace);
 280  0
                 if(crossConstraintMap!=null){
 281  0
                         return crossConstraintMap.get(path);
 282  
                 }
 283  0
                 return null;
 284  
         }
 285  
         public void clearCrossConstraintMap(String namespace){
 286  0
                 if(namespace==null){
 287  0
                         namespace="_default";
 288  
                 }
 289  0
                 crossConstraints.remove(namespace);
 290  0
         }
 291  
         public void putPathToFieldMapping(String namespace, String path, FieldDescriptor fd){
 292  0
                 if(namespace==null){
 293  0
                         namespace="_default";
 294  
                 }
 295  
                 
 296  0
                 HashMap<String,FieldDescriptor> pathToField = pathToFieldMapping.get(namespace);
 297  0
                 if(pathToField==null){
 298  0
                         pathToField = new HashMap<String,FieldDescriptor>();
 299  0
                         pathToFieldMapping.put(namespace, pathToField);
 300  
                 }
 301  0
                 pathToField.put(path, fd);
 302  0
         }
 303  
 
 304  
         public FieldDescriptor getPathToFieldMapping(String namespace, String path){
 305  0
                 if(namespace==null){
 306  0
                         namespace="_default";
 307  
                 }
 308  
                 
 309  0
                 HashMap<String,FieldDescriptor> pathToField = pathToFieldMapping.get(namespace);
 310  0
                 if(pathToField!=null){
 311  0
                         return pathToField.get(path);
 312  
                 }
 313  0
                 return null;
 314  
         }
 315  
         public void clearPathToFieldMapping(String namespace){
 316  0
                 if(namespace==null){
 317  0
                         namespace="_default";
 318  
                 }
 319  0
                 pathToFieldMapping.remove(namespace);
 320  0
         }
 321  
 
 322  
         /**
 323  
          * Removes the bidirectional mapping for all paths that start with the path prefix
 324  
          * This means if Field A had a dependency on Field B, and you cleared A, first all mappings with
 325  
          * dependencies to A would be removed, then all mappings with dependencies to A would be removed. 
 326  
          * @param namespace
 327  
          * @param pathPrefix
 328  
          */
 329  
         public void clearCrossConstraintsWithStartingPath(String namespace, String pathPrefix){
 330  0
                 if(namespace==null){
 331  0
                         namespace="_default";
 332  
                 }
 333  
                 //First delete any cross constraint mappings based on this field
 334  0
                 HashMap<String,HashSet<HasCrossConstraints>> crossConstraintMap = crossConstraints.get(namespace);
 335  0
                 if(crossConstraintMap!=null){
 336  0
                         Iterator<Map.Entry<String,HashSet<HasCrossConstraints>>> constraintMapIter = crossConstraintMap.entrySet().iterator();
 337  0
                         while(constraintMapIter.hasNext()){
 338  0
                                 Map.Entry<String,HashSet<HasCrossConstraints>> entry = constraintMapIter.next();
 339  0
                                 if(entry.getKey().startsWith(pathPrefix)){
 340  0
                                         constraintMapIter.remove();
 341  
                                 }
 342  0
                         }
 343  
 
 344  
                         //Find all the fieldDescriptors that start with the prefix and remove the cross constraint mapping to them 
 345  0
                         HashMap<String,FieldDescriptor> pathToField = pathToFieldMapping.get(namespace);
 346  0
                         if(pathToField!=null){
 347  0
                                 Iterator<Entry<String, FieldDescriptor>> pathMapIter = pathToField.entrySet().iterator();
 348  0
                                 while(pathMapIter.hasNext()){
 349  0
                                         Entry<String, FieldDescriptor> entry = pathMapIter.next();
 350  0
                                         if(entry.getKey().startsWith(pathPrefix)){
 351  0
                                                 FieldDescriptor fd = entry.getValue();
 352  0
                                                 if(fd.getFieldWidget()!=null && fd.getFieldWidget() instanceof HasCrossConstraints && ((HasCrossConstraints)fd.getFieldWidget()).getCrossConstraints()!=null){
 353  
                                                         //Loop through the constraint paths and remove any mapping to the existing field descriptor
 354  0
                                                         for(String path:((HasCrossConstraints)fd.getFieldWidget()).getCrossConstraints()){
 355  0
                                                                 HashSet<HasCrossConstraints> set = crossConstraintMap.get(path);
 356  0
                                                                 if(set!=null){
 357  0
                                                                         set.remove(fd.getFieldWidget());
 358  
                                                                 }
 359  0
                                                         }
 360  
                                                 }
 361  
                                         }
 362  0
                                 }
 363  
                         }
 364  
                 }
 365  0
         }
 366  
         
 367  
         public HashSet<HasCrossConstraints> getCrossConstraints(String namespace) {
 368  0
                 if(namespace==null){
 369  0
                         namespace="_default";
 370  
                 }
 371  0
                 HashSet<HasCrossConstraints> results = new HashSet<HasCrossConstraints>();
 372  0
                 HashMap<String,HashSet<HasCrossConstraints>> crossConstraintMap = crossConstraints.get(namespace);
 373  0
                 if(crossConstraintMap!=null){
 374  0
                         for(HashSet<HasCrossConstraints> fds: crossConstraintMap.values()){
 375  0
                                 results.addAll(fds);
 376  
                         }
 377  
                 }
 378  0
                 return results;
 379  
         }
 380  
 
 381  
         
 382  
         public List<ValidationResultInfo> getValidationWarnings() {
 383  0
                 return validationWarnings;
 384  
         }
 385  
 
 386  
         /**
 387  
          * Adds warnings from the validationResults to the application context.
 388  
          * 
 389  
          * @param validationResults
 390  
          */
 391  
         public void addValidationWarnings(List<ValidationResultInfo> validationResults) {
 392  0
                 if (validationResults != null){
 393  0
                         for (ValidationResultInfo vr:validationResults){
 394  0
                                 if (vr.getErrorLevel() == ErrorLevel.WARN){
 395  0
                                         this.validationWarnings.add(vr);
 396  
                                 }
 397  
                         }
 398  
                 }
 399  0
         }
 400  
 
 401  
         public void clearValidationWarnings(){
 402  0
                 validationWarnings.clear();
 403  0
         }
 404  
         
 405  
         public String getParentPath() {
 406  0
                 return parentPath;
 407  
         }
 408  
 
 409  
         public void setParentPath(String parentPath) {
 410  0
                 this.parentPath = parentPath;
 411  0
         }
 412  
         
 413  
     private Map<String, Object> getConstraintInfo(Metadata metadata, String label) {
 414  0
         Map<String, Object> constraintInfo = new HashMap<String, Object>();
 415  
         
 416  0
         if (metadata != null) {
 417  0
             for (ValidationMessageKeys vKey : ValidationMessageKeys.values()) {
 418  0
                 if (!vKey.getProperty().isEmpty() && label.contains("${" + vKey.getProperty() + "}")) {
 419  0
                     switch (vKey) {
 420  
                         case MIN_OCCURS:
 421  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getLargestMinOccurs(metadata));
 422  0
                             break;
 423  
                         case MAX_OCCURS:
 424  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getSmallestMaxOccurs(metadata));
 425  0
                             break;
 426  
                         case MAX_VALUE:
 427  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getSmallestMaxValue(metadata));
 428  0
                             break;
 429  
                         case MIN_VALUE:
 430  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getLargestMinValue(metadata));
 431  0
                             break;
 432  
                         case MAX_LENGTH:
 433  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getSmallestMaxLength(metadata));
 434  0
                             break;
 435  
                         case MIN_LENGTH:
 436  0
                             constraintInfo.put(vKey.getProperty(), MetadataInterrogator.getLargestMinLength(metadata));
 437  0
                             break;                         
 438  
                         case VALID_CHARS:
 439  0
                             String validChars = metadata.getConstraints().get(0).getValidChars();
 440  0
                             if (validChars.startsWith("regex:")) {
 441  0
                                 validChars = validChars.substring(6);
 442  
                             }
 443  0
                             constraintInfo.put(vKey.getProperty(), validChars);
 444  
                         default :
 445  
                             break;
 446  
                     }
 447  
                 }
 448  
             }
 449  
         }
 450  0
         return constraintInfo;
 451  
     }
 452  
         
 453  
 }