Coverage Report - org.kuali.rice.krad.uif.view.View
 
Classes in this File Line Coverage Branch Coverage Complexity
View
0%
0/213
0%
0/62
1.366
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krad.uif.view;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.krad.uif.UifConstants;
 20  
 import org.kuali.rice.krad.uif.UifConstants.ViewStatus;
 21  
 import org.kuali.rice.krad.uif.UifConstants.ViewType;
 22  
 import org.kuali.rice.krad.uif.authorization.Authorizer;
 23  
 import org.kuali.rice.krad.uif.authorization.PresentationController;
 24  
 import org.kuali.rice.krad.uif.container.Container;
 25  
 import org.kuali.rice.krad.uif.container.ContainerBase;
 26  
 import org.kuali.rice.krad.uif.container.Group;
 27  
 import org.kuali.rice.krad.uif.container.NavigationGroup;
 28  
 import org.kuali.rice.krad.uif.container.PageGroup;
 29  
 import org.kuali.rice.krad.uif.component.BindingInfo;
 30  
 import org.kuali.rice.krad.uif.component.Component;
 31  
 import org.kuali.rice.krad.uif.component.ReferenceCopy;
 32  
 import org.kuali.rice.krad.uif.component.RequestParameter;
 33  
 import org.kuali.rice.krad.uif.field.HeaderField;
 34  
 import org.kuali.rice.krad.uif.field.LinkField;
 35  
 import org.kuali.rice.krad.uif.layout.LayoutManager;
 36  
 import org.kuali.rice.krad.uif.service.ViewHelperService;
 37  
 import org.kuali.rice.krad.uif.util.BooleanMap;
 38  
 import org.kuali.rice.krad.uif.util.ClientValidationUtils;
 39  
 import org.kuali.rice.krad.uif.widget.BreadCrumbs;
 40  
 import org.kuali.rice.krad.uif.widget.Growls;
 41  
 import org.kuali.rice.krad.util.ObjectUtils;
 42  
 
 43  
 import java.util.ArrayList;
 44  
 import java.util.HashMap;
 45  
 import java.util.HashSet;
 46  
 import java.util.List;
 47  
 import java.util.Map;
 48  
 import java.util.Set;
 49  
 
 50  
 /**
 51  
  * Root of the component tree which encompasses a set of related
 52  
  * <code>GroupContainer</code> instances tied together with a common page layout
 53  
  * and navigation.
 54  
  *
 55  
  * <p>
 56  
  * The <code>View</code> component ties together all the components and
 57  
  * configuration of the User Interface for a piece of functionality. In Rice
 58  
  * applications the view is typically associated with a <code>Document</code>
 59  
  * instance.
 60  
  * </p>
 61  
  *
 62  
  * <p>
 63  
  * The view template lays out the common header, footer, and navigation for the
 64  
  * related pages. In addition the view renders the HTML head element bringing in
 65  
  * common script files and style sheets, along with optionally rendering a form
 66  
  * element for pages that need to post data back to the server.
 67  
  * </p>
 68  
  *
 69  
  * <p>
 70  
  * Configuration of UIF features such as model validation is also done through
 71  
  * the <code>View</code>
 72  
  * </p>
 73  
  *
 74  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 75  
  */
 76  
 public class View extends ContainerBase {
 77  
     private static final long serialVersionUID = -1220009725554576953L;
 78  
 
 79  
     private String viewName;
 80  
 
 81  
     private int idSequence;
 82  
 
 83  
     // application
 84  
     private HeaderField applicationHeader;
 85  
     private Group applicationFooter;
 86  
 
 87  
     // Breadcrumbs
 88  
     private BreadCrumbs breadcrumbs;
 89  
     private String viewLabelFieldPropertyName;
 90  
     private String appendOption;
 91  
     private boolean breadcrumbsInApplicationHeader;
 92  
 
 93  
     // Growls support
 94  
     private Growls growls;
 95  
     private boolean growlMessagingEnabled;
 96  
 
 97  
     private String entryPageId;
 98  
 
 99  
     @RequestParameter
 100  
     private String currentPageId;
 101  
 
 102  
     private NavigationGroup navigation;
 103  
 
 104  
     private Class<?> formClass;
 105  
     private String defaultBindingObjectPath;
 106  
     private Map<String, Class<?>> abstractTypeClasses;
 107  
 
 108  
     private List<String> additionalScriptFiles;
 109  
     private List<String> additionalCssFiles;
 110  
 
 111  
     private ViewType viewTypeName;
 112  
     private Class<? extends ViewHelperService> viewHelperServiceClassName;
 113  
 
 114  
     private String viewStatus;
 115  
     private ViewIndex viewIndex;
 116  
     private Map<String, String> viewRequestParameters;
 117  
 
 118  
     private Class<? extends PresentationController> presentationControllerClass;
 119  
     private Class<? extends Authorizer> authorizerClass;
 120  
 
 121  
     private BooleanMap actionFlags;
 122  
     private BooleanMap editModes;
 123  
 
 124  
     private Map<String, String> expressionVariables;
 125  
 
 126  
     private boolean singlePageView;
 127  
     private PageGroup page;
 128  
 
 129  
     private List<? extends Group> items;
 130  
 
 131  
     private LinkField viewMenuLink;
 132  
     private String viewMenuGrouping;
 133  
 
 134  
     private boolean validateDirty;
 135  
     private boolean translateCodes;
 136  
     private String preLoadScript;
 137  
     private Map<String, Object> clientSideState;
 138  
 
 139  
     private boolean supportsReadOnlyFieldsOverride;
 140  
 
 141  
     @RequestParameter
 142  
     private boolean dialogMode;
 143  
 
 144  
     @ReferenceCopy
 145  
     private ViewHelperService viewHelperService;
 146  
 
 147  0
     public View() {
 148  0
         dialogMode = false;
 149  0
         singlePageView = false;
 150  0
         translateCodes = false;
 151  0
         viewTypeName = ViewType.DEFAULT;
 152  0
         viewStatus = UifConstants.ViewStatus.CREATED;
 153  0
         breadcrumbsInApplicationHeader = false;
 154  0
         supportsReadOnlyFieldsOverride = true;
 155  
 
 156  0
         idSequence = 0;
 157  0
         this.viewIndex = new ViewIndex();
 158  
 
 159  0
         additionalScriptFiles = new ArrayList<String>();
 160  0
         additionalCssFiles = new ArrayList<String>();
 161  0
         items = new ArrayList<Group>();
 162  0
         abstractTypeClasses = new HashMap<String, Class<?>>();
 163  0
         viewRequestParameters = new HashMap<String, String>();
 164  0
         expressionVariables = new HashMap<String, String>();
 165  0
         clientSideState = new HashMap<String, Object>();
 166  0
     }
 167  
 
 168  
     /**
 169  
      * The following initialization is performed:
 170  
      *
 171  
      * <ul>
 172  
      * <li>If a single paged view, set items in page group and put the page in
 173  
      * the items list</li>
 174  
      * </ul>
 175  
      *
 176  
      * @see org.kuali.rice.krad.uif.container.ContainerBase#performInitialization(View, java.lang.Object)
 177  
      */
 178  
     @SuppressWarnings("unchecked")
 179  
     @Override
 180  
     public void performInitialization(View view, Object model) {
 181  0
         super.performInitialization(view, model);
 182  
 
 183  
         // populate items on page for single paged view
 184  0
         if (singlePageView) {
 185  0
             if (page != null) {
 186  0
                 page.setItems(new ArrayList<Group>(items));
 187  
 
 188  
                 // reset the items list to include the one page
 189  0
                 items = new ArrayList<Group>();
 190  0
                 ((List<Group>) items).add(page);
 191  
             } else {
 192  0
                 throw new RuntimeException("For single paged views the page Group must be set.");
 193  
             }
 194  
         }
 195  
 
 196  
         // make sure all the pages have ids before selecting the current page
 197  0
         for (Group group : this.getItems()) {
 198  0
             if (StringUtils.isBlank(group.getId())) {
 199  0
                 group.setId(view.getNextId());
 200  
             }
 201  
         }
 202  0
     }
 203  
 
 204  
     /**
 205  
      * The following is performed:
 206  
      *
 207  
      * <ul>
 208  
      * <li>Adds to its document ready script the setupValidator js function for setting
 209  
      * up the validator for this view</li>
 210  
      * </ul>
 211  
      *
 212  
      * @see org.kuali.rice.krad.uif.container.ContainerBase#performFinalize(View,
 213  
      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
 214  
      */
 215  
     @Override
 216  
     public void performFinalize(View view, Object model, Component parent) {
 217  0
         super.performFinalize(view, model, parent);
 218  
 
 219  0
         String prefixScript = "";
 220  0
         if (this.getOnDocumentReadyScript() != null) {
 221  0
             prefixScript = this.getOnDocumentReadyScript();
 222  
         }
 223  0
         this.setOnDocumentReadyScript(prefixScript + "jQuery.extend(jQuery.validator.messages, " +
 224  
                 ClientValidationUtils.generateValidatorMessagesOption() + ");");
 225  0
     }
 226  
 
 227  
     /**
 228  
      * Assigns an id to the component if one was not configured
 229  
      *
 230  
      * @param component - component instance to assign id to
 231  
      */
 232  
     public void assignComponentIds(Component component) {
 233  0
         if (component == null) {
 234  0
             return;
 235  
         }
 236  
 
 237  
         // assign IDs if necessary
 238  0
         if (StringUtils.isBlank(component.getId())) {
 239  0
             component.setId(getNextId());
 240  
 
 241  
         }
 242  0
         if (StringUtils.isBlank(component.getFactoryId())) {
 243  0
             component.setFactoryId(component.getId());
 244  
         }
 245  
 
 246  0
         if (component instanceof Container) {
 247  0
             LayoutManager layoutManager = ((Container) component).getLayoutManager();
 248  0
             if ((layoutManager != null) && StringUtils.isBlank(layoutManager.getId())) {
 249  0
                 layoutManager.setId(getNextId());
 250  
             }
 251  
         }
 252  
 
 253  
         // check if component has already been initialized to prevent cyclic references
 254  
         // TODO: move to VHS initialize
 255  
         //        if (initializedComponentIds.contains(component.getId())) {
 256  
         //            throw new RiceRuntimeException(
 257  
         //                    "Circular reference or duplicate id found for component with id: " + component.getId());
 258  
         //        }
 259  
         //        initializedComponentIds.add(component.getId());
 260  
 
 261  
         // assign id to nested components
 262  0
         List<Component> allNested = new ArrayList<Component>(component.getComponentsForLifecycle());
 263  0
         allNested.addAll(component.getComponentPrototypes());
 264  0
         for (Component nestedComponent : allNested) {
 265  0
             assignComponentIds(nestedComponent);
 266  
         }
 267  0
     }
 268  
 
 269  
     /**
 270  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
 271  
      */
 272  
     @Override
 273  
     public List<Component> getComponentsForLifecycle() {
 274  0
         List<Component> components = super.getComponentsForLifecycle();
 275  
 
 276  0
         components.add(applicationHeader);
 277  0
         components.add(applicationFooter);
 278  0
         components.add(navigation);
 279  0
         components.add(breadcrumbs);
 280  0
         components.add(growls);
 281  0
         components.add(viewMenuLink);
 282  
 
 283  
         // remove all pages that are not the current page
 284  0
         if (!singlePageView) {
 285  0
             for (Group group : this.getItems()) {
 286  0
                 if ((group instanceof PageGroup) && !StringUtils.equals(group.getId(), getCurrentPageId()) && components
 287  
                         .contains(group)) {
 288  0
                     components.remove(group);
 289  
                 }
 290  
             }
 291  
         }
 292  
 
 293  0
         return components;
 294  
     }
 295  
 
 296  
     /**
 297  
      * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes()
 298  
      */
 299  
     @Override
 300  
     public List<Component> getComponentPrototypes() {
 301  0
         List<Component> components = super.getComponentPrototypes();
 302  
 
 303  0
         components.add(page);
 304  
 
 305  0
         return components;
 306  
     }
 307  
 
 308  
     /**
 309  
      * @see org.kuali.rice.krad.uif.container.Container#getSupportedComponents()
 310  
      */
 311  
     @Override
 312  
     public Set<Class<? extends Component>> getSupportedComponents() {
 313  0
         Set<Class<? extends Component>> supportedComponents = new HashSet<Class<? extends Component>>();
 314  0
         supportedComponents.add(Group.class);
 315  
 
 316  0
         return supportedComponents;
 317  
     }
 318  
 
 319  
     /**
 320  
      * @see org.kuali.rice.krad.uif.component.Component#getComponentTypeName()
 321  
      */
 322  
     @Override
 323  
     public String getComponentTypeName() {
 324  0
         return "view";
 325  
     }
 326  
 
 327  
     /**
 328  
      * Iterates through the contained page items and returns the Page that
 329  
      * matches the set current page id
 330  
      *
 331  
      * @return Page instance
 332  
      */
 333  
     public PageGroup getCurrentPage() {
 334  0
         for (Group pageGroup : this.getItems()) {
 335  0
             if (StringUtils.equals(pageGroup.getId(), getCurrentPageId()) && pageGroup instanceof PageGroup) {
 336  0
                 return (PageGroup) pageGroup;
 337  
             }
 338  
         }
 339  
 
 340  0
         return null;
 341  
     }
 342  
 
 343  
     /**
 344  
      * View name provides an identifier for a view within a type. That is if a
 345  
      * set of <code>View</code> instances have the same values for the
 346  
      * properties that are used to retrieve them by their type, the name can be
 347  
      * given to further qualify the view that should be retrieved.
 348  
      * <p>
 349  
      * A view type like the <code>LookupView</code> might have several views for
 350  
      * the same object class, but one that is the 'default' lookup and another
 351  
      * that is the 'advanced' lookup. Therefore the name on the first could be
 352  
      * set to 'default', and likewise the name for the second 'advanced'.
 353  
      * </p>
 354  
      *
 355  
      * @return String name of view
 356  
      */
 357  
     public String getViewName() {
 358  0
         return this.viewName;
 359  
     }
 360  
 
 361  
     /**
 362  
      * Setter for the view's name
 363  
      *
 364  
      * @param viewName
 365  
      */
 366  
     public void setViewName(String viewName) {
 367  0
         this.viewName = viewName;
 368  0
     }
 369  
 
 370  
     /**
 371  
      * Header for the application containing the view
 372  
      *
 373  
      * <p>
 374  
      * When deploying outside a portal, the application header and footer property can be configured to
 375  
      * display a consistent header/footer across all views. Here application logos, menus, login controls
 376  
      * and so on can be rendered.
 377  
      * </p>
 378  
      *
 379  
      * @return HeaderField application header
 380  
      */
 381  
     public HeaderField getApplicationHeader() {
 382  0
         return applicationHeader;
 383  
     }
 384  
 
 385  
     /**
 386  
      * Setter for the application header
 387  
      *
 388  
      * @param applicationHeader
 389  
      */
 390  
     public void setApplicationHeader(HeaderField applicationHeader) {
 391  0
         this.applicationHeader = applicationHeader;
 392  0
     }
 393  
 
 394  
     /**
 395  
      * Footer for the application containing the view
 396  
      *
 397  
      * <p>
 398  
      * When deploying outside a portal, the application header and footer property can be configured to
 399  
      * display a consistent header/footer across all views. Here such things as application links, copyrights
 400  
      * and so on can be rendered.
 401  
      * </p>
 402  
      *
 403  
      * @return Group application footer
 404  
      */
 405  
     public Group getApplicationFooter() {
 406  0
         return applicationFooter;
 407  
     }
 408  
 
 409  
     /**
 410  
      * Setter for the application footer
 411  
      *
 412  
      * @param applicationFooter
 413  
      */
 414  
     public void setApplicationFooter(Group applicationFooter) {
 415  0
         this.applicationFooter = applicationFooter;
 416  0
     }
 417  
 
 418  
     /**
 419  
      * Returns the next unique id available for components within the view instance
 420  
      *
 421  
      * @return String next id available
 422  
      */
 423  
     public String getNextId() {
 424  0
         return Integer.toString(idSequence++);
 425  
     }
 426  
 
 427  
     /**
 428  
      * Specifies what page should be rendered by default. This is the page that
 429  
      * will be rendered when the <code>View</code> is first rendered or when the
 430  
      * current page is not set
 431  
      *
 432  
      * @return String id of the page to render by default
 433  
      */
 434  
     public String getEntryPageId() {
 435  0
         return this.entryPageId;
 436  
     }
 437  
 
 438  
     /**
 439  
      * Setter for default Page id
 440  
      *
 441  
      * @param entryPageId
 442  
      */
 443  
     public void setEntryPageId(String entryPageId) {
 444  0
         this.entryPageId = entryPageId;
 445  0
     }
 446  
 
 447  
     /**
 448  
      * The id for the page within the view that should be displayed in the UI.
 449  
      * Other pages of the view will not be rendered
 450  
      *
 451  
      * <p>
 452  
      * If current page id is not set, it is set to the configured entry page or first item in list id
 453  
      * </p>
 454  
      *
 455  
      * @return String id of the page that should be displayed
 456  
      */
 457  
     public String getCurrentPageId() {
 458  
         // default current page if not set
 459  0
         if (StringUtils.isBlank(currentPageId)) {
 460  0
             if (StringUtils.isNotBlank(entryPageId)) {
 461  0
                 currentPageId = entryPageId;
 462  0
             } else if ((getItems() != null) && !getItems().isEmpty()) {
 463  0
                 Group firstPageGroup = getItems().get(0);
 464  0
                 currentPageId = firstPageGroup.getId();
 465  
             }
 466  
         }
 467  
 
 468  0
         return this.currentPageId;
 469  
     }
 470  
 
 471  
     /**
 472  
      * Setter for the page id to display
 473  
      *
 474  
      * @param currentPageId
 475  
      */
 476  
     public void setCurrentPageId(String currentPageId) {
 477  0
         this.currentPageId = currentPageId;
 478  0
     }
 479  
 
 480  
     /**
 481  
      * <code>NavigationGroup</code> instance for the <code>View</code>
 482  
      * <p>
 483  
      * Provides configuration necessary to render the navigation. This includes
 484  
      * navigation items in addition to configuration for the navigation
 485  
      * renderer.
 486  
      * </p>
 487  
      *
 488  
      * @return NavigationGroup
 489  
      */
 490  
     public NavigationGroup getNavigation() {
 491  0
         return this.navigation;
 492  
     }
 493  
 
 494  
     /**
 495  
      * Setter for the View's <code>NavigationGroup</code>
 496  
      *
 497  
      * @param navigation
 498  
      */
 499  
     public void setNavigation(NavigationGroup navigation) {
 500  0
         this.navigation = navigation;
 501  0
     }
 502  
 
 503  
     /**
 504  
      * Class of the Form that should be used with the <code>View</code>
 505  
      * instance. The form is the top level object for all the view's data and is
 506  
      * used to present and accept data in the user interface. All form classes
 507  
      * should extend UifFormBase
 508  
      *
 509  
      * @return Class<?> class for the view's form
 510  
      * @see org.kuali.rice.krad.web.form.UifFormBase
 511  
      */
 512  
     public Class<?> getFormClass() {
 513  0
         return this.formClass;
 514  
     }
 515  
 
 516  
     /**
 517  
      * Setter for the form class
 518  
      *
 519  
      * @param formClass
 520  
      */
 521  
     public void setFormClass(Class<?> formClass) {
 522  0
         this.formClass = formClass;
 523  0
     }
 524  
 
 525  
     /**
 526  
      * For <code>View</code> types that work primarily with one nested object of
 527  
      * the form (for instance document, or bo) the default binding object path
 528  
      * can be set for each of the views <code>DataBinding</code> components. If
 529  
      * the component does not set its own binding object path it will inherit
 530  
      * the default
 531  
      *
 532  
      * @return String binding path to the object from the form
 533  
      * @see org.kuali.rice.krad.uif.BindingInfo.getBindingObjectPath()
 534  
      */
 535  
     public String getDefaultBindingObjectPath() {
 536  0
         return this.defaultBindingObjectPath;
 537  
     }
 538  
 
 539  
     /**
 540  
      * Setter for the default binding object path to use for the view
 541  
      *
 542  
      * @param defaultBindingObjectPath
 543  
      */
 544  
     public void setDefaultBindingObjectPath(String defaultBindingObjectPath) {
 545  0
         this.defaultBindingObjectPath = defaultBindingObjectPath;
 546  0
     }
 547  
 
 548  
     /**
 549  
      * Configures the concrete classes that will be used for properties in the
 550  
      * form object graph that have an abstract or interface type
 551  
      *
 552  
      * <p>
 553  
      * For properties that have an abstract or interface type, it is not
 554  
      * possible to perform operations like getting/settings property values and
 555  
      * getting information from the dictionary. When these properties are
 556  
      * encountered in the object graph, this <code>Map</code> will be consulted
 557  
      * to determine the concrete type to use.
 558  
      * </p>
 559  
      *
 560  
      * <p>
 561  
      * e.g. Suppose we have a property document.accountingLine.accountNumber and
 562  
      * the accountingLine property on the document instance has an interface
 563  
      * type 'AccountingLine'. We can then put an entry into this map with key
 564  
      * 'document.accountingLine', and value
 565  
      * 'org.kuali.rice.sampleapp.TravelAccountingLine'. When getting the
 566  
      * property type or an entry from the dictionary for accountNumber, the
 567  
      * TravelAccountingLine class will be used.
 568  
      * </p>
 569  
      *
 570  
      * @return Map<String, Class> of class implementations keyed by path
 571  
      */
 572  
     public Map<String, Class<?>> getAbstractTypeClasses() {
 573  0
         return this.abstractTypeClasses;
 574  
     }
 575  
 
 576  
     /**
 577  
      * Setter for the Map of class implementations keyed by path
 578  
      *
 579  
      * @param abstractTypeClasses
 580  
      */
 581  
     public void setAbstractTypeClasses(Map<String, Class<?>> abstractTypeClasses) {
 582  0
         this.abstractTypeClasses = abstractTypeClasses;
 583  0
     }
 584  
 
 585  
     /**
 586  
      * Declares additional script files that should be included with the
 587  
      * <code>View</code>. These files are brought into the HTML page along with
 588  
      * common script files configured for the Rice application. Each entry
 589  
      * contain the path to the CSS file, either a relative path, path from web
 590  
      * root, or full URI
 591  
      * <p>
 592  
      * e.g. '/krad/scripts/myScript.js', '../scripts/myScript.js',
 593  
      * 'http://my.edu/web/myScript.js'
 594  
      * </p>
 595  
      *
 596  
      * @return List<String> script file locations
 597  
      */
 598  
     public List<String> getAdditionalScriptFiles() {
 599  0
         return this.additionalScriptFiles;
 600  
     }
 601  
 
 602  
     /**
 603  
      * Setter for the List of additional script files to included with the
 604  
      * <code>View</code>
 605  
      *
 606  
      * @param additionalScriptFiles
 607  
      */
 608  
     public void setAdditionalScriptFiles(List<String> additionalScriptFiles) {
 609  0
         this.additionalScriptFiles = additionalScriptFiles;
 610  0
     }
 611  
 
 612  
     /**
 613  
      * Declares additional CSS files that should be included with the
 614  
      * <code>View</code>. These files are brought into the HTML page along with
 615  
      * common CSS files configured for the Rice application. Each entry should
 616  
      * contain the path to the CSS file, either a relative path, path from web
 617  
      * root, or full URI
 618  
      * <p>
 619  
      * e.g. '/krad/css/stacked-view.css', '../css/stacked-view.css',
 620  
      * 'http://my.edu/web/stacked-view.css'
 621  
      * </p>
 622  
      *
 623  
      * @return List<String> CSS file locations
 624  
      */
 625  
     public List<String> getAdditionalCssFiles() {
 626  0
         return this.additionalCssFiles;
 627  
     }
 628  
 
 629  
     /**
 630  
      * Setter for the List of additional CSS files to included with the
 631  
      * <code>View</code>
 632  
      *
 633  
      * @param additionalCssFiles
 634  
      */
 635  
     public void setAdditionalCssFiles(List<String> additionalCssFiles) {
 636  0
         this.additionalCssFiles = additionalCssFiles;
 637  0
     }
 638  
 
 639  
     public boolean isDialogMode() {
 640  0
         return this.dialogMode;
 641  
     }
 642  
 
 643  
     public void setDialogMode(boolean dialogMode) {
 644  0
         this.dialogMode = dialogMode;
 645  0
     }
 646  
 
 647  
     /**
 648  
      * View type name the view is associated with the view instance
 649  
      *
 650  
      * <p>
 651  
      * Views that share common features and functionality can be grouped by the
 652  
      * view type. Usually view types extend the <code>View</code> class to
 653  
      * provide additional configuration and to set defaults. View types can also
 654  
      * implement the <code>ViewTypeService</code> to add special indexing and
 655  
      * retrieval of views.
 656  
      * </p>
 657  
      *
 658  
      * @return String view type name for the view
 659  
      */
 660  
     public ViewType getViewTypeName() {
 661  0
         return this.viewTypeName;
 662  
     }
 663  
 
 664  
     /**
 665  
      * Setter for the view's type name
 666  
      *
 667  
      * @param viewTypeName
 668  
      */
 669  
     public void setViewTypeName(ViewType viewTypeName) {
 670  0
         this.viewTypeName = viewTypeName;
 671  0
     }
 672  
 
 673  
     /**
 674  
      * Class name of the <code>ViewHelperService</code> that handles the various
 675  
      * phases of the Views lifecycle
 676  
      *
 677  
      * @return Class for the spring bean
 678  
      * @see org.kuali.rice.krad.uif.service.ViewHelperService
 679  
      */
 680  
     public Class<? extends ViewHelperService> getViewHelperServiceClassName() {
 681  0
         return this.viewHelperServiceClassName;
 682  
     }
 683  
 
 684  
     /**
 685  
      * Setter for the <code>ViewHelperService</code> class name
 686  
      *
 687  
      * @param viewLifecycleService
 688  
      */
 689  
     public void setViewHelperServiceClassName(Class<? extends ViewHelperService> viewHelperServiceClassName) {
 690  0
         this.viewHelperServiceClassName = viewHelperServiceClassName;
 691  0
     }
 692  
 
 693  
     /**
 694  
      * Creates the <code>ViewHelperService</code> associated with the View
 695  
      *
 696  
      * @return ViewHelperService instance
 697  
      */
 698  
     public ViewHelperService getViewHelperService() {
 699  0
         if (this.viewHelperService == null) {
 700  0
             viewHelperService = ObjectUtils.newInstance(viewHelperServiceClassName);
 701  
         }
 702  
 
 703  0
         return viewHelperService;
 704  
     }
 705  
 
 706  
     /**
 707  
      * Invoked to produce a ViewIndex of the current view's components
 708  
      */
 709  
     public void index() {
 710  0
         if (this.viewIndex == null) {
 711  0
             this.viewIndex = new ViewIndex();
 712  
         }
 713  0
         this.viewIndex.index(this);
 714  0
     }
 715  
 
 716  
     /**
 717  
      * Holds field indexes of the <code>View</code> instance for retrieval
 718  
      *
 719  
      * @return ViewIndex instance
 720  
      */
 721  
     public ViewIndex getViewIndex() {
 722  0
         return this.viewIndex;
 723  
     }
 724  
 
 725  
     /**
 726  
      * Map of parameters from the request that set view options, used to rebuild
 727  
      * the view on each post
 728  
      * <p>
 729  
      * Views can be configured by parameters. These might impact which parts of
 730  
      * the view are rendered or how the view behaves. Generally these would get
 731  
      * passed in when a new view is requested (by request parameters). These
 732  
      * will be used to initially populate the view properties. In addition, on a
 733  
      * post the view will be rebuilt and properties reset again by the allow
 734  
      * request parameters.
 735  
      * </p>
 736  
      * <p>
 737  
      * Example parameter would be for MaintenaceView whether a New, Edit, or
 738  
      * Copy was requested (maintenance mode)
 739  
      * </p>
 740  
      *
 741  
      * @return
 742  
      */
 743  
     public Map<String, String> getViewRequestParameters() {
 744  0
         return this.viewRequestParameters;
 745  
     }
 746  
 
 747  
     /**
 748  
      * Setter for the view's request parameters map
 749  
      *
 750  
      * @param viewRequestParameters
 751  
      */
 752  
     public void setViewRequestParameters(Map<String, String> viewRequestParameters) {
 753  0
         this.viewRequestParameters = viewRequestParameters;
 754  0
     }
 755  
 
 756  
     /**
 757  
      * PresentationController class that should be used for the
 758  
      * <code>View</code> instance
 759  
      * <p>
 760  
      * The presentation controller is consulted to determine component (group,
 761  
      * field) state such as required, read-only, and hidden. The presentation
 762  
      * controller does not take into account user permissions. The presentation
 763  
      * controller can also output action flags and edit modes that will be set
 764  
      * onto the view instance and can be referred to by conditional expressions
 765  
      * </p>
 766  
      *
 767  
      * @return Class<? extends PresentationController>
 768  
      * @see View.getActionFlags()
 769  
      * @see View.getEditModes()
 770  
      */
 771  
     public Class<? extends PresentationController> getPresentationControllerClass() {
 772  0
         return this.presentationControllerClass;
 773  
     }
 774  
 
 775  
     /**
 776  
      * Setter for the view's presentation controller
 777  
      *
 778  
      * @param presentationControllerClass
 779  
      */
 780  
     public void setPresentationControllerClass(Class<? extends PresentationController> presentationControllerClass) {
 781  0
         this.presentationControllerClass = presentationControllerClass;
 782  0
     }
 783  
 
 784  
     /**
 785  
      * Authorizer class that should be used for the <code>View</code> instance
 786  
      * <p>
 787  
      * The authorizer class is consulted to determine component (group, field)
 788  
      * state such as required, read-only, and hidden based on the users
 789  
      * permissions. It typically communicates with the Kuali Identity Management
 790  
      * system to determine roles and permissions. It is used with the
 791  
      * presentation controller and dictionary conditional logic to determine the
 792  
      * final component state. The authorizer can also output action flags and
 793  
      * edit modes that will be set onto the view instance and can be referred to
 794  
      * by conditional expressions
 795  
      * </p>
 796  
      *
 797  
      * @return Class<? extends Authorizer>
 798  
      * @see View.getActionFlags()
 799  
      * @see View.getEditModes()
 800  
      */
 801  
     public Class<? extends Authorizer> getAuthorizerClass() {
 802  0
         return this.authorizerClass;
 803  
     }
 804  
 
 805  
     /**
 806  
      * Setter for the view's authorizer
 807  
      *
 808  
      * @param authorizerClass
 809  
      */
 810  
     public void setAuthorizerClass(Class<? extends Authorizer> authorizerClass) {
 811  0
         this.authorizerClass = authorizerClass;
 812  0
     }
 813  
 
 814  
     /**
 815  
      * Map of strings that flag what actions can be taken in the UI
 816  
      * <p>
 817  
      * These can be used in conditional expressions in the dictionary or by
 818  
      * other UI logic
 819  
      * </p>
 820  
      *
 821  
      * @return BooleanMap action flags
 822  
      */
 823  
     public BooleanMap getActionFlags() {
 824  0
         return this.actionFlags;
 825  
     }
 826  
 
 827  
     /**
 828  
      * Setter for the action flags Map
 829  
      *
 830  
      * @param actionFlags
 831  
      */
 832  
     public void setActionFlags(BooleanMap actionFlags) {
 833  0
         this.actionFlags = actionFlags;
 834  0
     }
 835  
 
 836  
     /**
 837  
      * Map of edit modes that enabled for the view
 838  
      * <p>
 839  
      * These can be used in conditional expressions in the dictionary or by
 840  
      * other UI logic
 841  
      * </p>
 842  
      *
 843  
      * @return BooleanMap edit modes
 844  
      */
 845  
     public BooleanMap getEditModes() {
 846  0
         return this.editModes;
 847  
     }
 848  
 
 849  
     /**
 850  
      * Setter for the edit modes Map
 851  
      *
 852  
      * @param editModes
 853  
      */
 854  
     public void setEditModes(BooleanMap editModes) {
 855  0
         this.editModes = editModes;
 856  0
     }
 857  
 
 858  
     /**
 859  
      * Map that contains expressions to evaluate and make available as variables
 860  
      * for conditional expressions within the view
 861  
      * <p>
 862  
      * Each Map entry contains one expression variables, where the map key gives
 863  
      * the name for the variable, and the map value gives the variable
 864  
      * expression. The variables expressions will be evaluated before
 865  
      * conditional logic is run and made available as variables for other
 866  
      * conditional expressions. Variable expressions can be based on the model
 867  
      * and any object contained in the view's context
 868  
      * </p>
 869  
      *
 870  
      * @return Map<String, String> variable expressions
 871  
      */
 872  
     public Map<String, String> getExpressionVariables() {
 873  0
         return this.expressionVariables;
 874  
     }
 875  
 
 876  
     /**
 877  
      * Setter for the view's map of variable expressions
 878  
      *
 879  
      * @param expressionVariables
 880  
      */
 881  
     public void setExpressionVariables(Map<String, String> expressionVariables) {
 882  0
         this.expressionVariables = expressionVariables;
 883  0
     }
 884  
 
 885  
     /**
 886  
      * Indicates whether the <code>View</code> only has a single page
 887  
      * <code>Group</code> or contains multiple page <code>Group</code>
 888  
      * instances. In the case of a single page it is assumed the group's items
 889  
      * list contains the section groups for the page, and the page itself is
 890  
      * given by the page property ({@link #getPage()}. This is for convenience
 891  
      * of configuration and also can drive other configuration like styling.
 892  
      *
 893  
      * @return boolean true if the view only contains one page group, false if
 894  
      *         it contains multple pages
 895  
      */
 896  
     public boolean isSinglePageView() {
 897  0
         return this.singlePageView;
 898  
     }
 899  
 
 900  
     /**
 901  
      * Setter for the single page indicator
 902  
      *
 903  
      * @param singlePageView
 904  
      */
 905  
     public void setSinglePageView(boolean singlePageView) {
 906  0
         this.singlePageView = singlePageView;
 907  0
     }
 908  
 
 909  
     /**
 910  
      * For single paged views ({@link #isSinglePageView()}, gives the page
 911  
      * <code>Group</code> the view should render. The actual items for the page
 912  
      * is taken from the group's items list ({@link #getItems()}, and set onto
 913  
      * the give page group. This is for convenience of configuration.
 914  
      *
 915  
      * @return Group page group for single page views
 916  
      */
 917  
     public PageGroup getPage() {
 918  0
         return this.page;
 919  
     }
 920  
 
 921  
     /**
 922  
      * Setter for the page group for single page views
 923  
      *
 924  
      * @param page
 925  
      */
 926  
     public void setPage(PageGroup page) {
 927  0
         this.page = page;
 928  0
     }
 929  
 
 930  
     /**
 931  
      * @see org.kuali.rice.krad.uif.container.ContainerBase#getItems()
 932  
      */
 933  
     @Override
 934  
     public List<? extends Group> getItems() {
 935  0
         return this.items;
 936  
     }
 937  
 
 938  
     /**
 939  
      * Setter for the view's <code>Group</code> instances
 940  
      *
 941  
      * @param items
 942  
      */
 943  
     @Override
 944  
     public void setItems(List<? extends Component> items) {
 945  
         // TODO: fix this generic issue
 946  0
         this.items = (List<? extends Group>) items;
 947  0
     }
 948  
 
 949  
     /**
 950  
      * Provides configuration for displaying a link to the view from an
 951  
      * application menu
 952  
      *
 953  
      * @return LinkField view link field
 954  
      */
 955  
     public LinkField getViewMenuLink() {
 956  0
         return this.viewMenuLink;
 957  
     }
 958  
 
 959  
     /**
 960  
      * Setter for the views link field
 961  
      *
 962  
      * @param viewMenuLink
 963  
      */
 964  
     public void setViewMenuLink(LinkField viewMenuLink) {
 965  0
         this.viewMenuLink = viewMenuLink;
 966  0
     }
 967  
 
 968  
     /**
 969  
      * Provides a grouping string for the view to group its menu link (within a
 970  
      * portal for instance)
 971  
      *
 972  
      * @return String menu grouping
 973  
      */
 974  
     public String getViewMenuGrouping() {
 975  0
         return this.viewMenuGrouping;
 976  
     }
 977  
 
 978  
     /**
 979  
      * Setter for the views menu grouping
 980  
      *
 981  
      * @param viewMenuGrouping
 982  
      */
 983  
     public void setViewMenuGrouping(String viewMenuGrouping) {
 984  0
         this.viewMenuGrouping = viewMenuGrouping;
 985  0
     }
 986  
 
 987  
     /**
 988  
      * Indicates what lifecycle phase the View instance is in
 989  
      * <p>
 990  
      * The view lifecycle begins with the CREATED status. In this status a new
 991  
      * instance of the view has been retrieved from the dictionary, but no
 992  
      * further processing has been done. After the initialize phase has been run
 993  
      * the status changes to INITIALIZED. After the model has been applied and
 994  
      * the view is ready for render the status changes to FINAL
 995  
      * </p>
 996  
      *
 997  
      * @return String view status
 998  
      * @see org.kuali.rice.krad.uif.UifConstants.ViewStatus
 999  
      */
 1000  
     public String getViewStatus() {
 1001  0
         return this.viewStatus;
 1002  
     }
 1003  
 
 1004  
     /**
 1005  
      * Setter for the view status
 1006  
      *
 1007  
      * @param viewStatus
 1008  
      */
 1009  
     public void setViewStatus(String viewStatus) {
 1010  0
         this.viewStatus = viewStatus;
 1011  0
     }
 1012  
 
 1013  
     /**
 1014  
      * Indicates whether the view has been initialized
 1015  
      *
 1016  
      * @return boolean true if the view has been initialized, false if not
 1017  
      */
 1018  
     public boolean isInitialized() {
 1019  0
         return StringUtils.equals(viewStatus, ViewStatus.INITIALIZED) ||
 1020  
                 StringUtils.equals(viewStatus, ViewStatus.FINAL);
 1021  
     }
 1022  
 
 1023  
     /**
 1024  
      * Indicates whether the view has been updated from the model and final
 1025  
      * updates made
 1026  
      *
 1027  
      * @return boolean true if the view has been updated, false if not
 1028  
      */
 1029  
     public boolean isFinal() {
 1030  0
         return StringUtils.equals(viewStatus, ViewStatus.FINAL);
 1031  
     }
 1032  
 
 1033  
     /**
 1034  
      * onSubmit script configured on the <code>View</code> gets placed on the
 1035  
      * form element
 1036  
      *
 1037  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getSupportsOnSubmit()
 1038  
      */
 1039  
     @Override
 1040  
     public boolean getSupportsOnSubmit() {
 1041  0
         return true;
 1042  
     }
 1043  
 
 1044  
     /**
 1045  
      * onLoad script configured on the <code>View</code> gets placed in a load
 1046  
      * call
 1047  
      *
 1048  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getSupportsOnLoad()
 1049  
      */
 1050  
     @Override
 1051  
     public boolean getSupportsOnLoad() {
 1052  0
         return true;
 1053  
     }
 1054  
 
 1055  
     /**
 1056  
      * onDocumentReady script configured on the <code>View</code> gets placed in
 1057  
      * a document ready jQuery block
 1058  
      *
 1059  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getSupportsOnLoad()
 1060  
      */
 1061  
     @Override
 1062  
     public boolean getSupportsOnDocumentReady() {
 1063  0
         return true;
 1064  
     }
 1065  
 
 1066  
     /**
 1067  
      * Breadcrumb widget used for displaying homeward path and history
 1068  
      *
 1069  
      * @return the breadcrumbs
 1070  
      */
 1071  
     public BreadCrumbs getBreadcrumbs() {
 1072  0
         return this.breadcrumbs;
 1073  
     }
 1074  
 
 1075  
     /**
 1076  
      * @param breadcrumbs the breadcrumbs to set
 1077  
      */
 1078  
     public void setBreadcrumbs(BreadCrumbs breadcrumbs) {
 1079  0
         this.breadcrumbs = breadcrumbs;
 1080  0
     }
 1081  
 
 1082  
     /**
 1083  
      * Indicates whether the breadcrumbs are rendered in the application header and should not
 1084  
      * be rendered as part of the view template
 1085  
      *
 1086  
      * <p>
 1087  
      * For layout purposes it is sometimes necessary to render the breadcrumbs in the application header. This flag
 1088  
      * indicates that is being done and therefore should not be rendered in the view template.
 1089  
      * </p>
 1090  
      *
 1091  
      * @return boolean true if breadcrumbs are rendered in the application header, false if not and they should be
 1092  
      *         rendered with the view
 1093  
      */
 1094  
     public boolean isBreadcrumbsInApplicationHeader() {
 1095  0
         return breadcrumbsInApplicationHeader;
 1096  
     }
 1097  
 
 1098  
     /**
 1099  
      * Setter for the breadcrumbs in application header indicator
 1100  
      *
 1101  
      * @param breadcrumbsInApplicationHeader
 1102  
      */
 1103  
     public void setBreadcrumbsInApplicationHeader(boolean breadcrumbsInApplicationHeader) {
 1104  0
         this.breadcrumbsInApplicationHeader = breadcrumbsInApplicationHeader;
 1105  0
     }
 1106  
 
 1107  
     /**
 1108  
      * Growls widget which sets up global settings for the growls used in this
 1109  
      * view and its pages
 1110  
      *
 1111  
      * @return the growls
 1112  
      */
 1113  
     public Growls getGrowls() {
 1114  0
         return this.growls;
 1115  
     }
 1116  
 
 1117  
     /**
 1118  
      * @param growls the growls to set
 1119  
      */
 1120  
     public void setGrowls(Growls growls) {
 1121  0
         this.growls = growls;
 1122  0
     }
 1123  
 
 1124  
     /**
 1125  
      * Growls use the messages contained in the message map. If enabled, info
 1126  
      * messages in their entirety will be displayed in growls, for warning and
 1127  
      * error messages a growl message will notify the user that these messages
 1128  
      * exist on the page. If this setting is disabled, it is recommended that
 1129  
      * infoMessage display be enabled for the page ErrorsField bean in order to
 1130  
      * display relevant information to the user. Note: the growl scripts are
 1131  
      * built out in the PageGroup class.
 1132  
      *
 1133  
      * @return the growlMessagingEnabled
 1134  
      */
 1135  
     public boolean isGrowlMessagingEnabled() {
 1136  0
         return this.growlMessagingEnabled;
 1137  
     }
 1138  
 
 1139  
     /**
 1140  
      * @param growlMessagingEnabled the growlMessagingEnabled to set
 1141  
      */
 1142  
     public void setGrowlMessagingEnabled(boolean growlMessagingEnabled) {
 1143  0
         this.growlMessagingEnabled = growlMessagingEnabled;
 1144  0
     }
 1145  
 
 1146  
     /**
 1147  
      * Indicates whether the form should be validated for dirtyness
 1148  
      *
 1149  
      * <p>
 1150  
      * For FormView, it's necessary to validate when the user tries to navigate out of the form. If set, all the
 1151  
      * InputFields will be validated on refresh, navigate, cancel or close Action or on form
 1152  
      * unload and if dirty, displays a message and user can decide whether to continue with
 1153  
      * the action or stay on the form. For lookup and inquiry, it's not needed to validate.
 1154  
      * </p>
 1155  
      *
 1156  
      * @return true if dirty validation is set
 1157  
      */
 1158  
     public boolean isValidateDirty() {
 1159  0
         return this.validateDirty;
 1160  
     }
 1161  
 
 1162  
     /**
 1163  
      * Setter for dirty validation.
 1164  
      */
 1165  
     public void setValidateDirty(boolean validateDirty) {
 1166  0
         this.validateDirty = validateDirty;
 1167  0
     }
 1168  
 
 1169  
     /**
 1170  
      * Indicates whether the Name of the Code should be displayed when a property is of type <code>KualiCode</code>
 1171  
      *
 1172  
      * @param translateCodes - indicates whether <code>KualiCode</code>'s name should be included
 1173  
      */
 1174  
     public void setTranslateCodes(boolean translateCodes) {
 1175  0
         this.translateCodes = translateCodes;
 1176  0
     }
 1177  
 
 1178  
     /**
 1179  
      * Returns whether the current view supports displaying <code>KualiCode</code>'s name as additional display value
 1180  
      *
 1181  
      * @return true if the current view supports
 1182  
      */
 1183  
     public boolean isTranslateCodes() {
 1184  0
         return translateCodes;
 1185  
     }
 1186  
 
 1187  
     /**
 1188  
      * The property name to be used to determine what will be used in the
 1189  
      * breadcrumb title of this view
 1190  
      *
 1191  
      * <p>
 1192  
      * The title can be determined from a combination of this and viewLabelFieldbindingInfo: If only
 1193  
      * viewLabelFieldPropertyName is set, the title we be determined against the
 1194  
      * defaultBindingObjectPath. If only viewLabelFieldbindingInfo is set it
 1195  
      * must provide information about what object(bindToForm or explicit) and
 1196  
      * path to use. If both viewLabelFieldbindingInfo and viewLabelFieldPropertyName are set,
 1197  
      * the bindingInfo will be used with a
 1198  
      * the viewLabelFieldPropertyName as its bindingPath. If neither are set,
 1199  
      * the default title attribute from the dataObject's metadata (determined by the
 1200  
      * defaultBindingObjectPath's object) will be used.
 1201  
      * </p>
 1202  
      *
 1203  
      * @return String property name whose value should be displayed in view label
 1204  
      */
 1205  
     public String getViewLabelFieldPropertyName() {
 1206  0
         return this.viewLabelFieldPropertyName;
 1207  
     }
 1208  
 
 1209  
     /**
 1210  
      * Setter for the view label property name
 1211  
      *
 1212  
      * @param viewLabelFieldPropertyName the viewLabelFieldPropertyName to set
 1213  
      */
 1214  
     public void setViewLabelFieldPropertyName(String viewLabelFieldPropertyName) {
 1215  0
         this.viewLabelFieldPropertyName = viewLabelFieldPropertyName;
 1216  0
     }
 1217  
 
 1218  
     /**
 1219  
      * The option to use when appending the view label on the breadcrumb title.
 1220  
      * Available options: 'dash', 'parenthesis', and 'replace'(don't append -
 1221  
      * simply replace the title). MUST be set for the viewLabelField to be used
 1222  
      * in the breadcrumb, if not set no appendage will be added.
 1223  
      *
 1224  
      * @return the appendOption
 1225  
      */
 1226  
     public String getAppendOption() {
 1227  0
         return this.appendOption;
 1228  
     }
 1229  
 
 1230  
     /**
 1231  
      * Setter for the append option
 1232  
      *
 1233  
      * @param appendOption the appendOption to set
 1234  
      * @see View#setViewLabelFieldPropertyName(String)
 1235  
      * @see View#setViewLabelFieldBindingInfo(BindingInfo)
 1236  
      */
 1237  
     public void setAppendOption(String appendOption) {
 1238  0
         this.appendOption = appendOption;
 1239  0
     }
 1240  
 
 1241  
     /**
 1242  
      * Map of key name/value pairs that will be exposed on the client with JavaScript
 1243  
      *
 1244  
      * <p>
 1245  
      * Any state contained in the Map will be in addition to general state added by the
 1246  
      * <code>ViewHelperService</code> and also state generated from the component properties
 1247  
      * annotated with <code>ClientSideState</code>. If this map does contain a key that is
 1248  
      * the same as the generated state, it will override the generated, with the exception
 1249  
      * of keys that refer to component ids and have a nested map as value, which will be merged
 1250  
      * </p>
 1251  
      *
 1252  
      * @return Map<String, Object> contains key name/value pairs to expose on client
 1253  
      */
 1254  
     public Map<String, Object> getClientSideState() {
 1255  0
         return clientSideState;
 1256  
     }
 1257  
 
 1258  
     /**
 1259  
      * Setter for the client side state map
 1260  
      *
 1261  
      * @param clientSideState
 1262  
      */
 1263  
     public void setClientSideState(Map<String, Object> clientSideState) {
 1264  0
         this.clientSideState = clientSideState;
 1265  0
     }
 1266  
 
 1267  
     /**
 1268  
      * Adds a variable name/value pair to the client side state map associated with the given
 1269  
      * component id
 1270  
      *
 1271  
      * @param componentId - id of the component the state is associated with
 1272  
      * @param variableName - name to expose the state as
 1273  
      * @param value - initial value for the variable on the client
 1274  
      */
 1275  
     public void addToClientSideState(String componentId, String variableName, Object value) {
 1276  0
         Map<String, Object> componentClientState = new HashMap<String, Object>();
 1277  
 
 1278  
         // find any existing client state for component
 1279  0
         if (clientSideState.containsKey(componentId)) {
 1280  0
             Object clientState = clientSideState.get(componentId);
 1281  0
             if ((clientState != null) && (clientState instanceof Map)) {
 1282  0
                 componentClientState = (Map<String, Object>) clientState;
 1283  
             } else {
 1284  0
                 throw new IllegalArgumentException("Client side state for component: " + componentId + " is not a Map");
 1285  
             }
 1286  
         }
 1287  
 
 1288  
         // add variables to component state and reinsert into view's client state
 1289  0
         componentClientState.put(variableName, value);
 1290  0
         clientSideState.put(componentId, componentClientState);
 1291  0
     }
 1292  
 
 1293  
     /**
 1294  
      * Indicates whether the view allows read only fields to be specified on the request URL which will
 1295  
      * override the view setting
 1296  
      *
 1297  
      * <p>
 1298  
      * If enabled, the readOnlyFields request parameter can be sent to indicate fields that should be set read only
 1299  
      * </p>
 1300  
      *
 1301  
      * @return boolean true if read only request overrides are allowed, false if not
 1302  
      */
 1303  
     public boolean isSupportsReadOnlyFieldsOverride() {
 1304  0
         return supportsReadOnlyFieldsOverride;
 1305  
     }
 1306  
 
 1307  
     /**
 1308  
      * Setter for the the read only field override indicator
 1309  
      *
 1310  
      * @param supportsReadOnlyFieldsOverride
 1311  
      */
 1312  
     public void setSupportsReadOnlyFieldsOverride(boolean supportsReadOnlyFieldsOverride) {
 1313  0
         this.supportsReadOnlyFieldsOverride = supportsReadOnlyFieldsOverride;
 1314  0
     }
 1315  
 
 1316  
     /**
 1317  
      * Script that is executed at the beginning of page load (before any other script)
 1318  
      *
 1319  
      * <p>
 1320  
      * Many used to set server variables client side
 1321  
      * </p>
 1322  
      *
 1323  
      * @return String pre load script
 1324  
      */
 1325  
     public String getPreLoadScript() {
 1326  0
         return preLoadScript;
 1327  
     }
 1328  
 
 1329  
     /**
 1330  
      * Setter for the pre load script
 1331  
      *
 1332  
      * @param preLoadScript
 1333  
      */
 1334  
     public void setPreLoadScript(String preLoadScript) {
 1335  0
         this.preLoadScript = preLoadScript;
 1336  0
     }
 1337  
 }