Coverage Report - org.kuali.rice.kns.web.spring.controller.DocumentControllerBase
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentControllerBase
0%
0/106
0%
0/42
2.333
 
 1  
 /*
 2  
  * Copyright 2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.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/ecl1.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.kns.web.spring.controller;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.Map;
 21  
 
 22  
 import javax.servlet.http.HttpServletRequest;
 23  
 import javax.servlet.http.HttpServletResponse;
 24  
 
 25  
 import org.apache.commons.lang.ArrayUtils;
 26  
 import org.kuali.rice.core.framework.parameter.ParameterConstants;
 27  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 28  
 import org.kuali.rice.core.util.RiceKeyConstants;
 29  
 import org.kuali.rice.kew.exception.WorkflowException;
 30  
 import org.kuali.rice.kew.util.KEWConstants;
 31  
 import org.kuali.rice.kns.bo.AdHocRouteRecipient;
 32  
 import org.kuali.rice.kns.document.Document;
 33  
 import org.kuali.rice.kns.exception.DocumentAuthorizationException;
 34  
 import org.kuali.rice.kns.exception.UnknownDocumentIdException;
 35  
 import org.kuali.rice.kns.exception.ValidationException;
 36  
 import org.kuali.rice.kns.question.ConfirmationQuestion;
 37  
 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
 38  
 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
 39  
 import org.kuali.rice.kns.service.BusinessObjectService;
 40  
 import org.kuali.rice.kns.service.DataDictionaryService;
 41  
 import org.kuali.rice.kns.service.DocumentHelperService;
 42  
 import org.kuali.rice.kns.service.DocumentService;
 43  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 44  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 45  
 import org.kuali.rice.kns.util.GlobalVariables;
 46  
 import org.kuali.rice.kns.util.KNSConstants;
 47  
 import org.kuali.rice.kns.util.KNSPropertyConstants;
 48  
 import org.kuali.rice.kns.util.SessionTicket;
 49  
 import org.kuali.rice.kns.util.WebUtils;
 50  
 import org.kuali.rice.kns.web.spring.form.DocumentFormBase;
 51  
 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
 52  
 import org.springframework.validation.BindingResult;
 53  
 import org.springframework.web.bind.annotation.ModelAttribute;
 54  
 import org.springframework.web.bind.annotation.RequestMapping;
 55  
 import org.springframework.web.servlet.ModelAndView;
 56  
 
 57  
 /**
 58  
  * Base controller class for all KRAD <code>DocumentView</code> screens working
 59  
  * with <code>Document</code> models
 60  
  * 
 61  
  * <p>
 62  
  * Provides default controller implementations for the standard document actions
 63  
  * including: doc handler (retrieve from doc search and action list), save,
 64  
  * route (and other KEW actions)
 65  
  * </p>
 66  
  * 
 67  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 68  
  */
 69  0
 public abstract class DocumentControllerBase extends UifControllerBase {
 70  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentControllerBase.class);
 71  
 
 72  
         // COMMAND constants which cause docHandler to load an existing document
 73  
         // instead of creating a new one
 74  0
         protected static final String[] DOCUMENT_LOAD_COMMANDS = { KEWConstants.ACTIONLIST_COMMAND,
 75  
                         KEWConstants.DOCSEARCH_COMMAND, KEWConstants.SUPERUSER_COMMAND, KEWConstants.HELPDESK_ACTIONLIST_COMMAND };
 76  
 
 77  
         private BusinessObjectService businessObjectService;
 78  
         private BusinessObjectAuthorizationService businessObjectAuthorizationService;
 79  
         private BusinessObjectMetaDataService businessObjectMetaDataService;
 80  
         private DataDictionaryService dataDictionaryService;
 81  
         private DocumentService documentService;
 82  
         private DocumentHelperService documentHelperService;
 83  
 
 84  
         @Override
 85  
         public abstract DocumentFormBase createInitialForm(HttpServletRequest request);
 86  
 
 87  
         /**
 88  
          * Used to funnel all document handling through, we could do useful things
 89  
          * like log and record various openings and status Additionally it may be
 90  
          * nice to have a single dispatcher that can know how to dispatch to a
 91  
          * redirect url for document specific handling but we may not need that as
 92  
          * all we should need is the document to be able to load itself based on
 93  
          * document id and then which action forward or redirect is pertinent for
 94  
          * the document type.
 95  
          */
 96  
         @RequestMapping(params = "methodToCall=docHandler")
 97  
         public ModelAndView docHandler(@ModelAttribute("KualiForm") DocumentFormBase form, BindingResult result, HttpServletRequest request,
 98  
                         HttpServletResponse response) throws Exception {
 99  0
                 String command = form.getCommand();
 100  
 
 101  
                 // in all of the following cases we want to load the document
 102  0
                 if (ArrayUtils.contains(DOCUMENT_LOAD_COMMANDS, command) && form.getDocId() != null) {
 103  0
                         loadDocument(form);
 104  
                 }
 105  0
                 else if (KEWConstants.INITIATE_COMMAND.equals(command)) {
 106  0
                         createDocument(form);
 107  
                 }
 108  
                 else {
 109  0
                         LOG.error("docHandler called with invalid parameters");
 110  0
                         throw new IllegalStateException("docHandler called with invalid parameters");
 111  
                 }
 112  
 
 113  
                 // TODO: authorization on document actions
 114  
                 // if (KEWConstants.SUPERUSER_COMMAND.equalsIgnoreCase(command)) {
 115  
                 // form.setSuppressAllButtons(true);
 116  
                 // }
 117  
 
 118  0
                 return getUIFModelAndView(form);
 119  
         }
 120  
 
 121  
         /**
 122  
          * Loads the document by its provided document header id. This has been
 123  
          * abstracted out so that it can be overridden in children if the need
 124  
          * arises.
 125  
          * 
 126  
          * @param form
 127  
          *            - form instance that contains the doc id parameter and where
 128  
          *            the retrieved document instance should be set
 129  
          */
 130  
         protected void loadDocument(DocumentFormBase form) throws WorkflowException {
 131  0
                 String docId = form.getDocId();
 132  
 
 133  0
                 Document doc = null;
 134  0
                 doc = getDocumentService().getByDocumentHeaderId(docId);
 135  0
                 if (doc == null) {
 136  0
                         throw new UnknownDocumentIdException(
 137  
                                         "Document no longer exists.  It may have been cancelled before being saved.");
 138  
                 }
 139  
 
 140  0
                 KualiWorkflowDocument workflowDocument = doc.getDocumentHeader().getWorkflowDocument();
 141  0
                 if (!getDocumentHelperService().getDocumentAuthorizer(doc).canOpen(doc,
 142  
                                 GlobalVariables.getUserSession().getPerson())) {
 143  0
                         throw buildAuthorizationException("open", doc);
 144  
                 }
 145  
 
 146  
                 // re-retrieve the document using the current user's session - remove
 147  
                 // the system user from the WorkflowDcument object
 148  0
                 if (workflowDocument != doc.getDocumentHeader().getWorkflowDocument()) {
 149  0
                         LOG.warn("Workflow document changed via canOpen check");
 150  0
                         doc.getDocumentHeader().setWorkflowDocument(workflowDocument);
 151  
                 }
 152  
 
 153  0
                 form.setDocument(doc);
 154  0
                 KualiWorkflowDocument workflowDoc = doc.getDocumentHeader().getWorkflowDocument();
 155  0
                 form.setDocTypeName(workflowDoc.getDocumentType());
 156  
 
 157  0
                 KNSServiceLocatorWeb.getSessionDocumentService().addDocumentToUserSession(GlobalVariables.getUserSession(), workflowDoc);
 158  0
         }
 159  
 
 160  
         /**
 161  
          * Creates a new document of the type specified by the docTypeName property
 162  
          * of the given form. This has been abstracted out so that it can be
 163  
          * overridden in children if the need arises.
 164  
          * 
 165  
          * @param form
 166  
          *            - form instance that contains the doc type parameter and where
 167  
          *            the new document instance should be set
 168  
          */
 169  
         protected void createDocument(DocumentFormBase form) throws WorkflowException {
 170  0
                 Document doc = getDocumentService().getNewDocument(form.getDocTypeName());
 171  
 
 172  0
                 form.setDocument(doc);
 173  0
                 form.setDocTypeName(doc.getDocumentHeader().getWorkflowDocument().getDocumentType());
 174  0
         }
 175  
 
 176  
         /**
 177  
          * Saves the <code>Document</code> instance
 178  
          */
 179  
         @RequestMapping(params = "methodToCall=save")
 180  
         public ModelAndView save(@ModelAttribute("KualiForm") DocumentFormBase form, BindingResult result, HttpServletRequest request,
 181  
                         HttpServletResponse response) throws Exception {
 182  
 
 183  0
                 doProcessingAfterPost(form, request);
 184  
 
 185  
                 // get any possible changes to to adHocWorkgroups
 186  
                 // TODO turn this back on
 187  
                 // refreshAdHocRoutingWorkgroupLookups(request, form);
 188  
 
 189  0
                 Document document = form.getDocument();
 190  
 
 191  0
                 String viewName = checkAndWarnAboutSensitiveData(form, request, response,
 192  
                                 KNSPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "save", "");
 193  
                 // TODO if the happens we may need to save form to session or account
 194  
                 // for it
 195  0
                 if (viewName != null) {
 196  0
                         return new ModelAndView(viewName);
 197  
                 }
 198  
 
 199  
                 try {
 200  
                     // save in workflow
 201  0
                     getDocumentService().saveDocument(document);
 202  
     
 203  0
                     GlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_SAVED);
 204  0
                     form.setAnnotation("");
 205  
                 }
 206  0
                 catch(ValidationException vex) {
 207  
                     // if errors in map, swallow exception so screen will draw with errors
 208  
                         // if not then throw runtime because something bad happened
 209  0
                         if(GlobalVariables.getMessageMap().hasNoErrors()) {
 210  0
                                 throw new RuntimeException("Validation Exception with no error message.", vex);
 211  
                         }
 212  0
                 }
 213  
 
 214  0
                 return getUIFModelAndView(form);
 215  
         }
 216  
 
 217  
         /**
 218  
          * Routes the <code>Document</code> instance using the document service
 219  
          */
 220  
         @RequestMapping(params = "methodToCall=route")
 221  
         public ModelAndView route(@ModelAttribute("KualiForm") DocumentFormBase form, BindingResult result, HttpServletRequest request,
 222  
                         HttpServletResponse response) throws Exception {
 223  0
                 doProcessingAfterPost(form, request);
 224  
 
 225  
                 // TODO: prerules
 226  
                 // kualiDocumentFormBase.setDerivedValuesOnForm(request);
 227  
                 // ActionForward preRulesForward = promptBeforeValidation(mapping, form,
 228  
                 // request, response);
 229  
                 // if (preRulesForward != null) {
 230  
                 // return preRulesForward;
 231  
                 // }
 232  
 
 233  0
                 Document document = form.getDocument();
 234  
 
 235  0
                 String viewName = checkAndWarnAboutSensitiveData(form, request, response,
 236  
                                 KNSPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "route", "");
 237  0
                 if (viewName != null) {
 238  0
                         return new ModelAndView(viewName);
 239  
                 }
 240  
 
 241  
                 // TODO: adhoc recipients
 242  
                 // getDocumentService().routeDocument(document, form.getAnnotation(),
 243  
                 // combineAdHocRecipients(kualiDocumentFormBase));
 244  0
                 getDocumentService().routeDocument(document, form.getAnnotation(), new ArrayList<AdHocRouteRecipient>());
 245  
 
 246  0
                 GlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL);
 247  0
                 form.setAnnotation("");
 248  
 
 249  
                 // GlobalVariables.getUserSession().addObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_COMPLETE_OBJECT_KEY,Boolean.TRUE);
 250  0
                 return getUIFModelAndView(form);
 251  
         }
 252  
 
 253  
         /**
 254  
          * Does all special processing on a document that should happen on each HTTP
 255  
          * post (ie, save, route, approve, etc).
 256  
          * 
 257  
          * @param form
 258  
          * @param request
 259  
          */
 260  
         protected void doProcessingAfterPost(DocumentFormBase form, HttpServletRequest request) {
 261  0
                 getBusinessObjectService().linkUserFields(form.getDocument());
 262  0
         }
 263  
 
 264  
         // TODO this needs more analysis before porting can finish
 265  
         /*
 266  
          * protected void refreshAdHocRoutingWorkgroupLookups(HttpServletRequest
 267  
          * request, DocumentFormBase form) throws WorkflowException { for
 268  
          * (Enumeration<String> i = request.getParameterNames();
 269  
          * i.hasMoreElements();) { String parameterName = i.nextElement();
 270  
          * 
 271  
          * // TODO does this really belong in the loop if
 272  
          * (parameterName.equals("newAdHocRouteWorkgroup.recipientName") &&
 273  
          * !"".equals(request.getParameter(parameterName))) { //check for namespace
 274  
          * String namespace = KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE; if
 275  
          * (request.getParameter("newAdHocRouteWorkgroup.recipientNamespaceCode") !=
 276  
          * null &&
 277  
          * !"".equals(request.getParameter("newAdHocRouteWorkgroup.recipientName"
 278  
          * ).trim())) {
 279  
          * 
 280  
          * namespace =
 281  
          * request.getParameter("newAdHocRouteWorkgroup.recipientNamespaceCode"
 282  
          * ).trim(); } Group group =
 283  
          * getIdentityManagementService().getGroupByName(namespace,
 284  
          * request.getParameter(parameterName)); if (group != null) {
 285  
          * form.getNewAdHocRouteWorkgroup().setId(group.getGroupId());
 286  
          * form.getNewAdHocRouteWorkgroup().setRecipientName(group.getGroupName());
 287  
          * form
 288  
          * .getNewAdHocRouteWorkgroup().setRecipientNamespaceCode(group.getNamespaceCode
 289  
          * ()); } else { throw new
 290  
          * RuntimeException("Invalid workgroup id passed as parameter."); } }
 291  
          * 
 292  
          * // TODO need to look at screen, will most of this just be bound to the
 293  
          * form by spring? if (parameterName.startsWith("adHocRouteWorkgroup[") &&
 294  
          * !"".equals(request.getParameter(parameterName))) { if
 295  
          * (parameterName.endsWith(".recipientName")) { int lineNumber =
 296  
          * Integer.parseInt(StringUtils.substringBetween(parameterName, "[", "]"));
 297  
          * //check for namespace String namespaceParam = "adHocRouteWorkgroup[" +
 298  
          * lineNumber + "].recipientNamespaceCode"; String namespace =
 299  
          * KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE; if
 300  
          * (request.getParameter(namespaceParam) != null &&
 301  
          * !"".equals(request.getParameter(namespaceParam).trim())) { namespace =
 302  
          * request.getParameter(namespaceParam).trim(); } Group group =
 303  
          * getIdentityManagementService().getGroupByName(namespace,
 304  
          * request.getParameter(parameterName)); if (group != null) {
 305  
          * form.getAdHocRouteWorkgroup(lineNumber).setId(group.getGroupId());
 306  
          * form.getAdHocRouteWorkgroup
 307  
          * (lineNumber).setRecipientName(group.getGroupName());
 308  
          * form.getAdHocRouteWorkgroup
 309  
          * (lineNumber).setRecipientNamespaceCode(group.getNamespaceCode()); } else
 310  
          * { throw new
 311  
          * RuntimeException("Invalid workgroup id passed as parameter."); } } } } }
 312  
          */
 313  
 
 314  
         /**
 315  
          * Checks if the given value matches patterns that indicate sensitive data
 316  
          * and if configured to give a warning for sensitive data will prompt the
 317  
          * user to continue.
 318  
          * 
 319  
          * @param form
 320  
          * @param request
 321  
          * @param response
 322  
          * @param fieldName
 323  
          *            - name of field with value being checked
 324  
          * @param fieldValue
 325  
          *            - value to check for sensitive data
 326  
          * @param caller
 327  
          *            - method that should be called back from question
 328  
          * @param context
 329  
          *            - additional context that needs to be passed back with the
 330  
          *            question response
 331  
          * @return - view for spring to forward to, or null if processing should
 332  
          *         continue
 333  
          * @throws Exception
 334  
          */
 335  
         protected String checkAndWarnAboutSensitiveData(DocumentFormBase form, HttpServletRequest request,
 336  
                         HttpServletResponse response, String fieldName, String fieldValue, String caller, String context)
 337  
                         throws Exception {
 338  
 
 339  0
                 String viewName = null;
 340  0
                 Document document = form.getDocument();
 341  
 
 342  0
                 boolean containsSensitiveData = WebUtils.containsSensitiveDataPatternMatch(fieldValue);
 343  
 
 344  
                 // check if warning is configured in which case we will prompt, or if
 345  
                 // not business rules will thrown an error
 346  0
                 boolean warnForSensitiveData = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
 347  
                                 KNSConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
 348  
                                 KNSConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS_WARNING_IND);
 349  
 
 350  
                 // determine if the question has been asked yet
 351  0
                 Map<String, String> ticketContext = new HashMap<String, String>();
 352  0
                 ticketContext.put(KNSPropertyConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
 353  0
                 ticketContext.put(KNSConstants.CALLING_METHOD, caller);
 354  0
                 ticketContext.put(KNSPropertyConstants.NAME, fieldName);
 355  
 
 356  0
                 boolean questionAsked = GlobalVariables.getUserSession().hasMatchingSessionTicket(
 357  
                                 KNSConstants.SENSITIVE_DATA_QUESTION_SESSION_TICKET, ticketContext);
 358  
 
 359  
                 // start in logic for confirming the sensitive data
 360  0
                 if (containsSensitiveData && warnForSensitiveData && !questionAsked) {
 361  0
                         Object question = request.getParameter(KNSConstants.QUESTION_INST_ATTRIBUTE_NAME);
 362  0
                         if (question == null || !KNSConstants.DOCUMENT_SENSITIVE_DATA_QUESTION.equals(question)) {
 363  
 
 364  
                                 // TODO not ready for question framework yet
 365  
                                 /*
 366  
                                  * // question hasn't been asked, prompt to continue return
 367  
                                  * this.performQuestionWithoutInput(mapping, form, request,
 368  
                                  * response, KNSConstants.DOCUMENT_SENSITIVE_DATA_QUESTION,
 369  
                                  * getKualiConfigurationService()
 370  
                                  * .getPropertyString(RiceKeyConstants
 371  
                                  * .QUESTION_SENSITIVE_DATA_DOCUMENT),
 372  
                                  * KNSConstants.CONFIRMATION_QUESTION, caller, context);
 373  
                                  */
 374  0
                                 viewName = "ask_user_questions";
 375  
                         }
 376  
                         else {
 377  0
                                 Object buttonClicked = request.getParameter(KNSConstants.QUESTION_CLICKED_BUTTON);
 378  
 
 379  
                                 // if no button clicked just reload the doc
 380  0
                                 if (ConfirmationQuestion.NO.equals(buttonClicked)) {
 381  
                                         // TODO figure out what to return
 382  0
                                         viewName = "user_says_no";
 383  
                                 }
 384  
 
 385  
                                 // answered yes, create session ticket so we not to ask question
 386  
                                 // again if there are further question requests
 387  0
                                 SessionTicket ticket = new SessionTicket(KNSConstants.SENSITIVE_DATA_QUESTION_SESSION_TICKET);
 388  0
                                 ticket.setTicketContext(ticketContext);
 389  0
                                 GlobalVariables.getUserSession().putSessionTicket(ticket);
 390  
                         }
 391  
                 }
 392  
 
 393  
                 // returning null will indicate processing should continue (no redirect)
 394  0
                 return viewName;
 395  
         }
 396  
 
 397  
         /**
 398  
          * Convenience method for building authorization exceptions
 399  
          * 
 400  
          * @param action
 401  
          *            - the action that was requested
 402  
          * @param document
 403  
          *            - document instance the action was requested for
 404  
          */
 405  
         protected DocumentAuthorizationException buildAuthorizationException(String action, Document document) {
 406  0
                 return new DocumentAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(),
 407  
                                 action, document.getDocumentNumber());
 408  
         }
 409  
 
 410  
         public BusinessObjectService getBusinessObjectService() {
 411  0
                 if (this.businessObjectService == null) {
 412  0
                         this.businessObjectService = KNSServiceLocator.getBusinessObjectService();
 413  
                 }
 414  0
                 return this.businessObjectService;
 415  
         }
 416  
 
 417  
         public void setBusinessObjectService(BusinessObjectService businessObjectService) {
 418  0
                 this.businessObjectService = businessObjectService;
 419  0
         }
 420  
 
 421  
         public BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
 422  0
                 if (this.businessObjectAuthorizationService == null) {
 423  0
                         this.businessObjectAuthorizationService = KNSServiceLocatorWeb.getBusinessObjectAuthorizationService();
 424  
                 }
 425  0
                 return this.businessObjectAuthorizationService;
 426  
         }
 427  
 
 428  
         public void setBusinessObjectAuthorizationService(
 429  
                         BusinessObjectAuthorizationService businessObjectAuthorizationService) {
 430  0
                 this.businessObjectAuthorizationService = businessObjectAuthorizationService;
 431  0
         }
 432  
 
 433  
         public BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
 434  0
                 if (this.businessObjectMetaDataService == null) {
 435  0
                         this.businessObjectMetaDataService = KNSServiceLocatorWeb.getBusinessObjectMetaDataService();
 436  
                 }
 437  0
                 return this.businessObjectMetaDataService;
 438  
         }
 439  
 
 440  
         public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
 441  0
                 this.businessObjectMetaDataService = businessObjectMetaDataService;
 442  0
         }
 443  
 
 444  
         public DataDictionaryService getDataDictionaryService() {
 445  0
                 if (this.dataDictionaryService == null) {
 446  0
                         this.dataDictionaryService = KNSServiceLocatorWeb.getDataDictionaryService();
 447  
                 }
 448  0
                 return this.dataDictionaryService;
 449  
         }
 450  
 
 451  
         public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
 452  0
                 this.dataDictionaryService = dataDictionaryService;
 453  0
         }
 454  
 
 455  
         public DocumentService getDocumentService() {
 456  0
                 if (this.documentService == null) {
 457  0
                         this.documentService = KNSServiceLocatorWeb.getDocumentService();
 458  
                 }
 459  0
                 return this.documentService;
 460  
         }
 461  
 
 462  
         public void setDocumentService(DocumentService documentService) {
 463  0
                 this.documentService = documentService;
 464  0
         }
 465  
 
 466  
         public DocumentHelperService getDocumentHelperService() {
 467  0
                 if (this.documentHelperService == null) {
 468  0
                         this.documentHelperService = KNSServiceLocatorWeb.getDocumentHelperService();
 469  
                 }
 470  0
                 return this.documentHelperService;
 471  
         }
 472  
 
 473  
         public void setDocumentHelperService(DocumentHelperService documentHelperService) {
 474  0
                 this.documentHelperService = documentHelperService;
 475  0
         }
 476  
 }