View Javadoc
1   /**
2    * Copyright 2005-2016 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.kns.web.struts.action;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.struts.action.ActionForm;
20  import org.apache.struts.action.ActionForward;
21  import org.apache.struts.action.ActionMapping;
22  import org.kuali.rice.core.api.CoreApiServiceLocator;
23  import org.kuali.rice.core.api.config.property.ConfigContext;
24  import org.kuali.rice.core.api.config.property.ConfigurationService;
25  import org.kuali.rice.core.api.util.RiceConstants;
26  import org.kuali.rice.core.api.util.RiceKeyConstants;
27  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
28  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
29  import org.kuali.rice.kew.api.KewApiServiceLocator;
30  import org.kuali.rice.kew.api.doctype.DocumentType;
31  import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
32  import org.kuali.rice.kns.datadictionary.HeaderNavigation;
33  import org.kuali.rice.kns.datadictionary.KNSDocumentEntry;
34  import org.kuali.rice.kns.datadictionary.LookupDefinition;
35  import org.kuali.rice.kns.datadictionary.MaintainableFieldDefinition;
36  import org.kuali.rice.kns.service.KNSServiceLocator;
37  import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
38  import org.kuali.rice.kns.util.WebUtils;
39  import org.kuali.rice.kns.web.struts.form.KualiHelpForm;
40  import org.kuali.rice.krad.datadictionary.AttributeDefinition;
41  import org.kuali.rice.krad.datadictionary.DataDictionary;
42  import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
43  import org.kuali.rice.krad.datadictionary.HelpDefinition;
44  import org.kuali.rice.krad.service.DataDictionaryService;
45  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
46  import org.kuali.rice.krad.util.KRADConstants;
47  
48  import javax.servlet.http.HttpServletRequest;
49  import javax.servlet.http.HttpServletResponse;
50  
51  /**
52   * This class handles requests for help text.
53   * 
54   * @deprecated KNS Struts deprecated, use KRAD and the Spring MVC framework.
55   */
56  @Deprecated
57  public class KualiHelpAction extends KualiAction {
58      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiHelpAction.class);
59  
60      private static final String VALIDATION_PATTERN_STRING = "ValidationPattern";
61      private static final String NO = "No";
62      private static final String YES = "Yes";
63      static final String DEFAULT_LOOKUP_HELP_TEXT_RESOURCE_KEY = "lookupHelpText";
64      
65      private static DataDictionaryService dataDictionaryService;
66      private static ConfigurationService kualiConfigurationService;
67      private static ParameterService parameterService;
68      private static MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
69  
70      private DataDictionaryService getDataDictionaryService() {
71          if ( dataDictionaryService == null ) {
72              dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
73          }
74          return dataDictionaryService;
75      }
76      private ConfigurationService getConfigurationService() {
77          if ( kualiConfigurationService == null ) {
78              kualiConfigurationService = CoreApiServiceLocator.getKualiConfigurationService();
79          }
80          return kualiConfigurationService;
81      }
82      private ParameterService getParameterService() {
83          if ( parameterService == null ) {
84              parameterService = CoreFrameworkServiceLocator.getParameterService();
85          }
86          return parameterService;
87      }
88  
89      private MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
90          if ( maintenanceDocumentDictionaryService == null ) {
91              maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
92          }
93          return maintenanceDocumentDictionaryService;
94      }
95      
96      /**
97       * Convenience method for accessing <code>{@link DataDictionaryEntry}</code> for the given business object
98       * 
99       * @param businessObjectClassName
100      * @return DataDictionaryEntry
101      */
102     private DataDictionaryEntry getDataDictionaryEntry(String businessObjectClassName) {
103         return getDataDictionaryService().getDataDictionary().getDictionaryObjectEntry(businessObjectClassName);
104     }
105 
106     /**
107      * Convenience method for accessing the <code>{@link AttributeDefinition}</code> for a specific business object attribute
108      * defined in the DataDictionary.
109      * 
110      * @param businessObjectClassName
111      * @param attributeName
112      * @return AttributeDefinition
113      */
114     private AttributeDefinition getAttributeDefinition(String businessObjectClassName, String attributeName) throws ClassNotFoundException {
115         AttributeDefinition retval = null;
116 
117         if (getDataDictionaryEntry(businessObjectClassName) != null) {
118             retval = getDataDictionaryEntry(businessObjectClassName).getAttributeDefinition(attributeName);
119         }
120         return retval;
121     }
122 
123     /**
124      * @param attribute <code>{@link AttributeDefinition}</code>
125      * @return String
126      */
127     private String getAttributeMaxLength(AttributeDefinition attribute) throws Exception {
128         return attribute.getMaxLength().toString();
129     }
130 
131     /**
132      * @param attribute <code>{@link AttributeDefinition}</code>
133      * @return String
134      */
135     private String getAttributeValidationPatternName(AttributeDefinition attribute) throws Exception {
136         String retval = new String();
137         if (attribute.getValidationPattern() != null) {
138             retval = attribute.getValidationPattern().getClass().getName();
139         }
140 
141         if (retval.indexOf(".") > 0) {
142             retval = retval.substring(retval.lastIndexOf(".") + 1);
143         }
144         if (retval.endsWith(VALIDATION_PATTERN_STRING)) {
145             retval = retval.substring(0, retval.lastIndexOf(VALIDATION_PATTERN_STRING));
146         }
147 
148         return retval;
149     }
150 
151     /**
152      * Retrieves help information from the data dictionary for the business object attribute.
153      * 
154      * @return ActionForward
155      */
156     public ActionForward getAttributeHelpText(ActionMapping mapping, KualiHelpForm helpForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
157 
158         AttributeDefinition attribute;
159 
160         if (StringUtils.isBlank(helpForm.getBusinessObjectClassName()) || StringUtils.isBlank(helpForm.getAttributeName())) {
161             throw new RuntimeException("Business object and attribute name not specified.");
162         }
163         attribute = getAttributeDefinition(helpForm.getBusinessObjectClassName(), helpForm.getAttributeName());
164 
165         if ( LOG.isDebugEnabled() ) {
166             LOG.debug( "Request for help on: " + helpForm.getBusinessObjectClassName() + " -- " + helpForm.getAttributeName() );
167             LOG.debug( "  attribute: " + attribute );
168         }
169                 
170         if (attribute == null || StringUtils.isBlank(attribute.getSummary())) {
171             helpForm.setResourceKey(RiceKeyConstants.MESSAGE_NO_HELP_TEXT);
172             return getResourceHelpText(mapping, helpForm, request, response);
173         }
174 
175         boolean required = attribute.isRequired().booleanValue();
176         // KULRNE-4392 - pull the required attribute on BO maintenance documents from the document def rather than the BO
177         try {
178             Class boClass = Class.forName( helpForm.getBusinessObjectClassName() );
179             String docTypeName = getMaintenanceDocumentDictionaryService().getDocumentTypeName( boClass );
180             if (StringUtils.isNotBlank(docTypeName)) {
181                 // maybe it's not a maint doc
182                 MaintainableFieldDefinition field = getMaintenanceDocumentDictionaryService().getMaintainableField( docTypeName, helpForm.getAttributeName() );
183                 if ( field != null ) {
184                     required = field.isRequired();
185                 }
186             }
187             else {
188                 if (log.isInfoEnabled()) {
189                     log.info("BO class " + boClass.getName() + " does not have a maint doc definition.  Defaulting to using DD for definition");
190                 }
191             }
192         } catch ( ClassNotFoundException ex ) {
193             // do nothing
194             LOG.warn( "Unable to obtain maintainable field for BO property.", ex );
195         }
196         
197         helpForm.setHelpLabel(attribute.getLabel());
198         helpForm.setHelpSummary(attribute.getSummary());
199         helpForm.setHelpDescription(attribute.getDescription());
200         helpForm.setHelpRequired(required?YES:NO);
201         helpForm.setHelpMaxLength(getAttributeMaxLength(attribute));
202         helpForm.setValidationPatternName(getAttributeValidationPatternName(attribute));
203 
204         return mapping.findForward(RiceConstants.MAPPING_BASIC);
205     }
206 
207     /**
208      * Retrieves help information from the data dictionary for the business object attribute.
209      * 
210      * @return ActionForward
211      */
212     public ActionForward getAttributeHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
213         return getAttributeHelpText(mapping, (KualiHelpForm) form, request, response);
214     }
215 
216     /**
217      * Retrieves help information from the data dictionary for the document type.
218      */
219     public ActionForward getDocumentHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
220         KualiHelpForm helpForm = (KualiHelpForm) form;
221 
222         String documentTypeName = helpForm.getDocumentTypeName();
223 
224         if (StringUtils.isBlank(documentTypeName)) {
225             throw new RuntimeException("Document type name not specified.");
226         }
227 
228         DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
229         org.kuali.rice.krad.datadictionary.DocumentEntry entry = (org.kuali.rice.krad.datadictionary.DocumentEntry ) dataDictionary.getDocumentEntry(documentTypeName);
230 
231         String label = "";
232         String summary = "";
233         String description = "";
234         HelpDefinition helpDefinition = null;
235         String apcHelpUrl = null;
236         if (entry != null) {
237             DocumentType docType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(entry.getDocumentTypeName());
238             label = docType.getLabel();
239             description = docType.getDescription();
240             if (StringUtils.isNotBlank(docType.getHelpDefinitionUrl())) {
241             	apcHelpUrl = WebUtils.toAbsoluteURL(ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.EXTERNALIZABLE_HELP_URL_KEY), docType.getHelpDefinitionUrl());
242             }
243         }
244 
245         if ( StringUtils.isNotBlank(apcHelpUrl) ) {
246             response.sendRedirect(apcHelpUrl);
247             return null;
248         }
249 
250         helpForm.setHelpLabel(label);
251         helpForm.setHelpSummary(summary);
252         helpForm.setHelpDescription(description);
253         helpForm.setHelpDefinition(helpDefinition);
254 
255         return mapping.findForward(RiceConstants.MAPPING_BASIC);
256     }
257 
258     /**
259      * Retrieves help information from the data dictionary for the document type.
260      */
261     public ActionForward getBusinessObjectHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
262         KualiHelpForm helpForm = (KualiHelpForm) form;
263 
264         String objectClassName = helpForm.getBusinessObjectClassName();
265 
266         if (StringUtils.isBlank(objectClassName)) {
267             throw new RuntimeException("Document type name not specified.");
268         }
269 
270         DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
271         BusinessObjectEntry entry = (BusinessObjectEntry) dataDictionary.getBusinessObjectEntry(objectClassName);
272 
273         HelpDefinition helpDefinition = null;
274         String apcHelpUrl = null;
275         String label = "";
276         String objectDescription = "";
277         if (entry != null) {
278             helpDefinition = entry.getHelpDefinition();
279             label = entry.getObjectLabel();
280             objectDescription = entry.getObjectDescription();
281             if (null != helpDefinition && null != helpDefinition.getParameterNamespace() && null != helpDefinition.getParameterDetailType() && null != helpDefinition.getParameterName()) {
282                 apcHelpUrl = getHelpUrl(helpDefinition.getParameterNamespace(), helpDefinition.getParameterDetailType(), helpDefinition.getParameterName());
283                 }
284                 }
285 
286         if ( !StringUtils.isBlank(apcHelpUrl) ) {
287             response.sendRedirect(apcHelpUrl);
288             return null;
289         }
290         helpForm.setHelpLabel(label);
291         helpForm.setHelpDescription(objectDescription);
292 
293         return mapping.findForward(RiceConstants.MAPPING_BASIC);
294     }
295     
296     /**
297      * Retrieves help information from the data dictionary for the document type.
298      */
299     public ActionForward getPageHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
300         KualiHelpForm helpForm = (KualiHelpForm) form;
301 
302         String documentTypeName = helpForm.getDocumentTypeName();
303         String pageName = helpForm.getPageName();
304 
305         if (StringUtils.isBlank(documentTypeName)) {
306             throw new RuntimeException("Document type name not specified.");
307         }
308         
309         if (StringUtils.isBlank(pageName)) {
310             throw new RuntimeException("Page name not specified.");
311         }
312 
313         DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
314         KNSDocumentEntry entry = (KNSDocumentEntry) dataDictionary.getDocumentEntry(documentTypeName);
315 
316         String apcHelpUrl = null;
317         String label = "";
318         String objectDescription = "";
319         if (entry != null) {
320             for ( HeaderNavigation headerNavigation : entry.getHeaderNavigationList() ) {
321                 if (headerNavigation.getHeaderTabDisplayName().equals(pageName)) {
322                     HelpDefinition helpDefinition = headerNavigation.getHelpDefinition();
323                     if (null != helpDefinition && null != helpDefinition.getParameterNamespace() && null != helpDefinition.getParameterDetailType() && null != helpDefinition.getParameterName()) {
324                         apcHelpUrl = getHelpUrl(helpDefinition.getParameterNamespace(), helpDefinition.getParameterDetailType(), helpDefinition.getParameterName());
325                     }
326                 }
327             }
328         }
329 
330         if ( !StringUtils.isBlank(apcHelpUrl) ) {
331             response.sendRedirect(apcHelpUrl);
332             return null;
333         }
334         helpForm.setHelpLabel(pageName);
335         helpForm.setHelpDescription("No help content available.");
336 
337         return mapping.findForward(RiceConstants.MAPPING_BASIC);
338     }
339     
340     /**
341      * Retrieves help content to link to based on security group/parameter
342      */
343     public ActionForward getStoredHelpUrl(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
344         KualiHelpForm helpForm = (KualiHelpForm) form;
345         
346         String helpParameterNamespace = helpForm.getHelpParameterNamespace();
347         String helpParameterDetailType = helpForm.getHelpParameterDetailType();
348         String helpParameterName = helpForm.getHelpParameterName();
349         
350         if (StringUtils.isBlank(helpParameterNamespace)) {
351             throw new RuntimeException("Parameter Namespace not specified.");
352         }
353         
354         if (StringUtils.isBlank(helpParameterDetailType)) {
355             throw new RuntimeException("Detail Type not specified.");
356         }
357 
358         if (StringUtils.isBlank(helpParameterName)) {
359             throw new RuntimeException("Parameter Name not specified.");
360         }
361         
362         String apcHelpUrl = getHelpUrl(helpParameterNamespace, helpParameterDetailType, helpParameterName);
363         
364         if ( !StringUtils.isBlank(apcHelpUrl) ) {
365             response.sendRedirect(apcHelpUrl);
366             return null;
367         }
368         
369         helpForm.setHelpDescription("No help content available.");
370         return mapping.findForward(RiceConstants.MAPPING_BASIC);
371     }
372 
373     /**
374      * Retrieves help information from resources by key.
375      */
376     public ActionForward getResourceHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
377         KualiHelpForm helpForm = (KualiHelpForm) form;
378 
379         String resourceKey = helpForm.getResourceKey();
380         populateHelpFormForResourceText(helpForm, resourceKey);
381 
382         return mapping.findForward(RiceConstants.MAPPING_BASIC);
383     }
384     
385     /**
386      * Utility method that populates a KualiHelpForm with the description from a given resource key
387      * @param helpForm the KualiHelpForm to populate with help text
388      * @param resourceKey the resource key to use as help text
389      */
390     protected void populateHelpFormForResourceText(KualiHelpForm helpForm, String resourceKey) {
391     	if (StringUtils.isBlank(resourceKey)) {
392             throw new RuntimeException("Help resource key not specified.");
393         }
394 
395         helpForm.setHelpLabel("");
396         helpForm.setHelpSummary("");
397         helpForm.setHelpDescription(getConfigurationService().getPropertyValueAsString(resourceKey));
398     }
399     
400     /**
401      * Retrieves help for a lookup
402      */
403     public ActionForward getLookupHelpText(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
404     	KualiHelpForm helpForm = (KualiHelpForm) form;
405 
406         // handle doc search custom help urls
407     	if (!StringUtils.isEmpty(helpForm.getSearchDocumentTypeName())) {
408     	    DocumentType docType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(helpForm.getSearchDocumentTypeName());
409     	    if (docType != null && !StringUtils.isEmpty(docType.getDocSearchHelpUrl())) {
410     	        String docSearchHelpUrl = WebUtils.toAbsoluteURL(ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.EXTERNALIZABLE_HELP_URL_KEY), docType.getDocSearchHelpUrl());
411 
412     	        if ( StringUtils.isNotBlank(docSearchHelpUrl) ) {
413     	            response.sendRedirect(docSearchHelpUrl);
414     	            return null;
415     	        }
416     	    }
417     	}
418 
419     	final String lookupBusinessObjectClassName = helpForm.getLookupBusinessObjectClassName();
420     	if (!StringUtils.isBlank(lookupBusinessObjectClassName)) {
421     		final DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
422     		final BusinessObjectEntry entry = (BusinessObjectEntry) dataDictionary.getBusinessObjectEntry(lookupBusinessObjectClassName);
423     		final LookupDefinition lookupDefinition = entry.getLookupDefinition();
424     		
425     		if (lookupDefinition != null) {
426     			if (lookupDefinition.getHelpDefinition() != null && !StringUtils.isBlank(lookupDefinition.getHelpDefinition().getParameterNamespace()) && !StringUtils.isBlank(lookupDefinition.getHelpDefinition().getParameterDetailType()) && !StringUtils.isBlank(lookupDefinition.getHelpDefinition().getParameterName())) {
427     				final String apcHelpUrl = getHelpUrl(lookupDefinition.getHelpDefinition().getParameterNamespace(), lookupDefinition.getHelpDefinition().getParameterDetailType(), lookupDefinition.getHelpDefinition().getParameterName());
428     		        
429     		        if ( !StringUtils.isBlank(apcHelpUrl) ) {
430     		            response.sendRedirect(apcHelpUrl);
431     		            return null;
432     		        }
433     			} else if (!StringUtils.isBlank(lookupDefinition.getHelpUrl())) {
434     				final String apcHelpUrl = WebUtils.toAbsoluteURL(ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.EXTERNALIZABLE_HELP_URL_KEY), lookupDefinition.getHelpUrl());
435     				response.sendRedirect(apcHelpUrl);
436     				return null;
437     			}
438     		}
439     	}
440     	
441     	// still here?  guess we're defaulting...
442     	populateHelpFormForResourceText(helpForm, getDefaultLookupHelpResourceKey());
443         return mapping.findForward(RiceConstants.MAPPING_BASIC);
444     }
445     
446     /**
447      * @return the key of the default lookup help resource text
448      */
449     protected String getDefaultLookupHelpResourceKey() {
450     	return KualiHelpAction.DEFAULT_LOOKUP_HELP_TEXT_RESOURCE_KEY;
451     }
452 
453     private String getHelpUrl(String parameterNamespace, String parameterDetailTypeCode, String parameterName) {
454         return WebUtils.toAbsoluteURL(getConfigurationService().getPropertyValueAsString(KRADConstants.EXTERNALIZABLE_HELP_URL_KEY), getParameterService().getParameterValueAsString(parameterNamespace, parameterDetailTypeCode, parameterName));
455     }    
456     
457     /**
458      * Retrieves help content to link to based on parameterNamespace and parameterName
459      */
460     public ActionForward getHelpUrlByNamespace(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
461         KualiHelpForm helpForm = (KualiHelpForm) form;
462        return getStoredHelpUrl(mapping, form, request, response); 
463     }
464 }