Coverage Report - org.kuali.rice.krad.web.spring.form.InquiryForm
 
Classes in this File Line Coverage Branch Coverage Complexity
InquiryForm
0%
0/142
0%
0/56
3.688
 
 1  
 /*
 2  
  * Copyright 2007 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.krad.web.spring.form;
 17  
 
 18  
 import java.security.GeneralSecurityException;
 19  
 import java.util.ArrayList;
 20  
 import java.util.HashMap;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 
 24  
 import javax.servlet.http.HttpServletRequest;
 25  
 
 26  
 import org.apache.log4j.Logger;
 27  
 import org.kuali.rice.core.api.CoreApiServiceLocator;
 28  
 import org.kuali.rice.core.api.encryption.EncryptionService;
 29  
 import org.kuali.rice.krad.bo.Exporter;
 30  
 import org.kuali.rice.krad.datadictionary.DataObjectEntry;
 31  
 import org.kuali.rice.krad.datadictionary.exception.UnknownBusinessClassAttributeException;
 32  
 import org.kuali.rice.krad.inquiry.Inquirable;
 33  
 import org.kuali.rice.krad.inquiry.KualiInquirableImpl;
 34  
 import org.kuali.rice.krad.service.BusinessObjectAuthorizationService;
 35  
 import org.kuali.rice.krad.service.BusinessObjectMetaDataService;
 36  
 import org.kuali.rice.krad.service.DataDictionaryService;
 37  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 38  
 import org.kuali.rice.krad.service.KualiModuleService;
 39  
 import org.kuali.rice.krad.service.ModuleService;
 40  
 import org.kuali.rice.krad.uif.UifConstants;
 41  
 import org.kuali.rice.krad.uif.UifConstants.ViewType;
 42  
 import org.kuali.rice.krad.util.KRADConstants;
 43  
 
 44  
 /**
 45  
  * Form class for <code>InquiryView</code> screens
 46  
  * 
 47  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 48  
  */
 49  
 public class InquiryForm extends UifFormBase {
 50  
         private static final long serialVersionUID = 4733144086378429410L;
 51  
 
 52  0
         private static final Logger LOG = Logger.getLogger(InquiryForm.class);
 53  
 
 54  
         private String dataObjectClassName;
 55  
         private boolean canExport;
 56  
 
 57  
         /**
 58  
          * The following map is used to pass primary key values between invocations
 59  
          * of the inquiry screens after the start method has been called. Values in
 60  
          * this map will remain encrypted if the value was passed in as encrypted
 61  
          */
 62  
         private Map<String, String> inquiryPrimaryKeys;
 63  
 
 64  
         private Map<String, String> inquiryDecryptedPrimaryKeys;
 65  
 
 66  
         private Object bo;
 67  
         private Inquirable inquirable;
 68  
         
 69  0
         public InquiryForm() {
 70  0
                 setViewTypeName(ViewType.INQUIRY);
 71  0
         }
 72  
 
 73  
         @Override
 74  
     public void postBind(HttpServletRequest request) {
 75  
                 // if the action is download attachment then skip the following populate
 76  
                 // logic
 77  0
         if (!KRADConstants.DOWNLOAD_BO_ATTACHMENT_METHOD.equals(getMethodToCall())
 78  
                 && !UifConstants.MethodToCallNames.NAVIGATE.equals(getMethodToCall())
 79  
                 && !KRADConstants.CLOSE_METHOD.equals(getMethodToCall())) {
 80  0
                         super.postBind(request);
 81  
 
 82  0
                         inquirable = (Inquirable) getView().getViewHelperService();
 83  
                         try {
 84  0
                                 inquirable.setDataObjectClass(Class.forName(dataObjectClassName));
 85  
                         }
 86  0
                         catch (ClassNotFoundException e) {
 87  0
                                 throw new RuntimeException("Unable to get new instance for object class: " + dataObjectClassName, e);
 88  0
                         }
 89  
 
 90  
                         // the following variable is true if the method to call is not
 91  
                         // start, meaning that we already called start
 92  0
                         boolean passedFromPreviousInquiry = !KRADConstants.START_METHOD.equals(getMethodToCall())
 93  
                                         && !KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL.equals(getMethodToCall())
 94  
                                         && !KRADConstants.DOWNLOAD_CUSTOM_BO_ATTACHMENT_METHOD.equals(getMethodToCall());
 95  
 
 96  
                         // There is no requirement that an inquiry screen must display the
 97  
                         // primary key values. However, when clicking on
 98  
                         // hide/show (without javascript) and
 99  
                         // hide/show inactive, the PK values are needed to allow the server
 100  
                         // to properly render results after the user
 101  
                         // clicks on a hide/show button that results
 102  
                         // in server processing. This line will populate the form with the
 103  
                         // PK values so that they may be used in
 104  
                         // subsequent requests. Note that encrypted
 105  
                         // values will remain encrypted in this map.
 106  0
                         this.inquiryPrimaryKeys = new HashMap<String, String>();
 107  0
                         this.inquiryDecryptedPrimaryKeys = new HashMap<String, String>();
 108  
 
 109  
 
 110  
                         
 111  0
                         if (inquirable instanceof KualiInquirableImpl){
 112  0
                                 populateBusinessObjectPKFieldValues(request, getDataObjectClassName(), passedFromPreviousInquiry);
 113  
                                 // populateInactiveRecordsInIntoInquirable(inquirable, request);
 114  0
                                 populateExportCapabilities(getDataObjectClassName());
 115  
                         } else {
 116  0
                                 populateObjectPKFieldValues(request, getDataObjectClassName(), passedFromPreviousInquiry);
 117  
                         }
 118  
                 }
 119  0
         }
 120  
 
 121  
         protected void populateBusinessObjectPKFieldValues(HttpServletRequest request, String boClassName,
 122  
                         boolean passedFromPreviousInquiry) {
 123  
                 try {
 124  0
                         EncryptionService encryptionService = CoreApiServiceLocator.getEncryptionService();
 125  0
                         DataDictionaryService dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
 126  0
                         BusinessObjectAuthorizationService businessObjectAuthorizationService = KRADServiceLocatorWeb
 127  
                         .getBusinessObjectAuthorizationService();
 128  
 
 129  
 
 130  
                         @SuppressWarnings("unchecked")
 131  0
                         Class businessObjectClass =  Class.forName(boClassName);
 132  
                         
 133  0
                         BusinessObjectMetaDataService businessObjectMetaDataService = KRADServiceLocatorWeb
 134  
                         .getBusinessObjectMetaDataService();
 135  
 
 136  
                         // build list of key values from request, if all keys not given
 137  
                         // throw error
 138  0
                         List<String> boPKeys  = businessObjectMetaDataService.listPrimaryKeyFieldNames(businessObjectClass);
 139  
                         
 140  0
                         final List<List<String>> altKeys = this.getAltkeys(businessObjectClass);
 141  
 
 142  0
                         altKeys.add(boPKeys);
 143  0
                         boolean bFound = false;
 144  0
                         for (List<String> boKeys : altKeys) {
 145  0
                                 if (bFound)
 146  0
                                         break;
 147  0
                                 int keyCount = boKeys.size();
 148  0
                                 int foundCount = 0;
 149  0
                                 for (String boKey : boKeys) {
 150  0
                                         String pkParamName = boKey;
 151  0
                                         if (passedFromPreviousInquiry) {
 152  0
                                                 pkParamName = KRADConstants.INQUIRY_PK_VALUE_PASSED_FROM_PREVIOUS_REQUEST_PREFIX + pkParamName;
 153  
                                         }
 154  
 
 155  0
                                         if (request.getParameter(pkParamName) != null) {
 156  0
                                                 foundCount++;
 157  0
                                                 String parameter = request.getParameter(pkParamName);
 158  
 
 159  0
                                                 Boolean forceUppercase = Boolean.FALSE;
 160  
                                                 try {
 161  0
                                                         forceUppercase = dataDictionaryService.getAttributeForceUppercase(businessObjectClass,
 162  
                                                                         boKey);
 163  
                                                 }
 164  0
                                                 catch (UnknownBusinessClassAttributeException ex) {
 165  
                                                         // swallowing exception because this check for
 166  
                                                         // ForceUppercase would
 167  
                                                         // require a DD entry for the attribute. it is only
 168  
                                                         // checking keys
 169  
                                                         // so most likely there should be an entry.
 170  0
                                                         LOG.warn("BO class " + dataObjectClassName + " property " + boKey
 171  
                                                                         + " should probably have a DD definition.", ex);
 172  0
                                                 }
 173  
 
 174  0
                                                 if (forceUppercase.booleanValue()) {
 175  0
                                                         parameter = parameter.toUpperCase();
 176  
                                                 }
 177  
 
 178  0
                                                 inquiryPrimaryKeys.put(boKey, parameter);
 179  0
                                                 if (businessObjectAuthorizationService.attributeValueNeedsToBeEncryptedOnFormsAndLinks(
 180  
                                                                 businessObjectClass, boKey)) {
 181  
                                                         try {
 182  0
                                                                 inquiryDecryptedPrimaryKeys.put(boKey, encryptionService.decrypt(parameter));
 183  
                                                         }
 184  0
                                                         catch (GeneralSecurityException e) {
 185  0
                                                                 LOG.error("BO class " + dataObjectClassName + " property " + boKey
 186  
                                                                                 + " should have been encrypted, but there was a problem decrypting it.");
 187  0
                                                                 throw e;
 188  0
                                                         }
 189  
                                                 }
 190  
                                                 else {
 191  0
                                                         inquiryDecryptedPrimaryKeys.put(boKey, parameter);
 192  
                                                 }
 193  
                                         }
 194  0
                                 }
 195  0
                                 if (foundCount == keyCount) {
 196  0
                                         bFound = true;
 197  
                                 }
 198  0
                         }
 199  0
                         if (!bFound) {
 200  0
                                 LOG.error("All keys not given to lookup for bo class name " + businessObjectClass.getName());
 201  0
                                 throw new RuntimeException("All keys not given to lookup for bo class name "
 202  
                                                 + businessObjectClass.getName());
 203  
                         }
 204  
                 }
 205  0
                 catch (ClassNotFoundException e) {
 206  0
                         LOG.error("Can't instantiate class: " + boClassName, e);
 207  0
                         throw new RuntimeException("Can't instantiate class: " + boClassName);
 208  
                 }
 209  0
                 catch (GeneralSecurityException e) {
 210  0
                         LOG.error("Can't decrypt value", e);
 211  0
                         throw new RuntimeException("Can't decrypt value");
 212  0
                 }
 213  0
         }
 214  
         
 215  
         protected void populateObjectPKFieldValues(HttpServletRequest request, String boClassName,
 216  
                         boolean passedFromPreviousInquiry) {
 217  
                 try {
 218  0
                         DataDictionaryService dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
 219  
 
 220  
                         
 221  0
                         Class<?> inquiryObjectClass =  Class.forName(boClassName);
 222  
 
 223  0
                         BusinessObjectMetaDataService businessObjectMetaDataService = KRADServiceLocatorWeb
 224  
             .getBusinessObjectMetaDataService();
 225  0
                         List<String> primaryKeys  = businessObjectMetaDataService.listPrimaryKeyFieldNames(inquiryObjectClass);
 226  
                                                 
 227  0
                         final List<List<String>> altKeys = this.getAltkeys(inquiryObjectClass);
 228  
 
 229  0
                         altKeys.add(primaryKeys);
 230  0
                         boolean bFound = false;
 231  0
                         for (List<String> boKeys : altKeys) {
 232  0
                                 if (bFound)
 233  0
                                         break;
 234  0
                                 int keyCount = boKeys.size();
 235  0
                                 int foundCount = 0;
 236  0
                                 for (String boKey : boKeys) {
 237  0
                                         String pkParamName = boKey;
 238  0
                                         if (passedFromPreviousInquiry) {
 239  0
                                                 pkParamName = KRADConstants.INQUIRY_PK_VALUE_PASSED_FROM_PREVIOUS_REQUEST_PREFIX + pkParamName;
 240  
                                         }
 241  
 
 242  0
                                         if (request.getParameter(pkParamName) != null) {
 243  0
                                                 foundCount++;
 244  0
                                                 String parameter = request.getParameter(pkParamName);
 245  
 
 246  0
                                                 Boolean forceUppercase = Boolean.FALSE;
 247  
                                                 try {
 248  0
                                                         forceUppercase = dataDictionaryService.getAttributeForceUppercase(inquiryObjectClass,
 249  
                                                                         boKey);
 250  
                                                 }
 251  0
                                                 catch (UnknownBusinessClassAttributeException ex) {
 252  
                                                         // swallowing exception because this check for
 253  
                                                         // ForceUppercase would
 254  
                                                         // require a DD entry for the attribute. it is only
 255  
                                                         // checking keys
 256  
                                                         // so most likely there should be an entry.
 257  0
                                                         LOG.warn("BO class " + dataObjectClassName + " property " + boKey
 258  
                                                                         + " should probably have a DD definition.", ex);
 259  0
                                                 }
 260  
 
 261  0
                                                 if (forceUppercase.booleanValue()) {
 262  0
                                                         parameter = parameter.toUpperCase();
 263  
                                                 }
 264  
 
 265  0
                                                 inquiryPrimaryKeys.put(boKey, parameter);
 266  0
                                                 inquiryDecryptedPrimaryKeys.put(boKey, parameter);
 267  
                                         }
 268  0
                                 }
 269  0
                                 if (foundCount == keyCount) {
 270  0
                                         bFound = true;
 271  
                                 }
 272  0
                         }
 273  0
                         if (!bFound) {
 274  0
                                 LOG.error("All keys not given to lookup for bo class name " + inquiryObjectClass.getName());
 275  0
                                 throw new RuntimeException("All keys not given to lookup for bo class name "
 276  
                                                 + inquiryObjectClass.getName());
 277  
                         }
 278  
                 }
 279  0
                 catch (ClassNotFoundException e) {
 280  0
                         LOG.error("Can't instantiate class: " + boClassName, e);
 281  0
                         throw new RuntimeException("Can't instantiate class: " + boClassName);
 282  0
                 }
 283  0
         }
 284  
 
 285  
         
 286  
         /**
 287  
          * Examines the BusinessObject's data dictionary entry to determine if it
 288  
          * supports XML export or not and set's canExport appropriately.
 289  
          */
 290  
         protected void populateExportCapabilities(String boClassName) {
 291  0
                 setCanExport(false);
 292  0
                 DataObjectEntry dataObjectEntry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary()
 293  
                                 .getDataObjectEntry(boClassName);
 294  0
                 Class<? extends Exporter> exporterClass = dataObjectEntry.getExporterClass();
 295  0
                 if (exporterClass != null) {
 296  
                         try {
 297  0
                                 Exporter exporter = exporterClass.newInstance();
 298  0
                                 if (exporter.getSupportedFormats(dataObjectEntry.getObjectClass()).contains(
 299  
                                                 KRADConstants.XML_FORMAT)) {
 300  0
                                         setCanExport(true);
 301  
                                 }
 302  
                         }
 303  0
                         catch (Exception e) {
 304  0
                                 LOG.error("Failed to locate or create exporter class: " + exporterClass, e);
 305  0
                                 throw new RuntimeException("Failed to locate or create exporter class: " + exporterClass);
 306  0
                         }
 307  
                 }
 308  0
         }
 309  
 
 310  
         /**
 311  
          * Gets the alt keys for a class. Will not return null but and empty list if
 312  
          * no keys exist.
 313  
          * 
 314  
          * @param clazz
 315  
          *            the class.
 316  
          * @return the alt keys
 317  
          */
 318  
         private List<List<String>> getAltkeys(Class<?> clazz) {
 319  0
                 final KualiModuleService kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
 320  0
                 final ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
 321  
 
 322  0
                 List<List<String>> altKeys = null;
 323  0
                 if (moduleService != null) {
 324  0
                         altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
 325  
                 }
 326  
 
 327  0
                 return altKeys != null ? altKeys : new ArrayList<List<String>>();
 328  
         }
 329  
 
 330  
         public String getDataObjectClassName() {
 331  0
                 return this.dataObjectClassName;
 332  
         }
 333  
 
 334  
         public void setDataObjectClassName(String dataObjectClassName) {
 335  0
                 this.dataObjectClassName = dataObjectClassName;
 336  0
         }
 337  
 
 338  
         public Object getBo() {
 339  0
                 return this.bo;
 340  
         }
 341  
 
 342  
         public void setBo(Object bo) {
 343  0
                 this.bo = bo;
 344  0
         }
 345  
 
 346  
         public Inquirable getInquirable() {
 347  0
                 return this.inquirable;
 348  
         }
 349  
 
 350  
         public void setInquirable(Inquirable inquirable) {
 351  0
                 this.inquirable = inquirable;
 352  0
         }
 353  
 
 354  
         public boolean isCanExport() {
 355  0
                 return this.canExport;
 356  
         }
 357  
 
 358  
         public void setCanExport(boolean canExport) {
 359  0
                 this.canExport = canExport;
 360  0
         }
 361  
 
 362  
         public Map<String, String> getInquiryPrimaryKeys() {
 363  0
                 return this.inquiryPrimaryKeys;
 364  
         }
 365  
 
 366  
         /**
 367  
          * Gets the map used to pass primary key values between invocations of the
 368  
          * inquiry screens after the start method has been called. All fields will
 369  
          * be decrypted
 370  
          * 
 371  
          * Purposely not named as a getter, to hide from binders
 372  
          * 
 373  
          * @return
 374  
          */
 375  
         public Map<String, String> retrieveInquiryDecryptedPrimaryKeys() {
 376  0
                 return this.inquiryDecryptedPrimaryKeys;
 377  
         }
 378  
 
 379  
 }