Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

  1. Create Bean Override: Used to perform overrides on the content of a Data Dictionary bean.
    Code Block
    borderStylesolid
    titleorg.kuali.rice.kns.datadictionary.BeanOverride
    borderStylesolid
    public interface BeanOverride {
       /**
         * Return the name of the bean to perform the override.
         * @return
         */
        public String getBeanName();   
        /**
         * Returns the list of fields to perform the override.
         */
        public List<FieldOverride> getFieldOverrides();
        
        /**
         * Perform the override logic on the specific bean.
         */
        public void performOverride(Object bean); 
    }
    
  2. Create Field Override: Used to override properties in a Data Dictionary bean.
    Code Block
    borderStylesolid
    titleorg.kuali.rice.kns.datadictionary.FieldOverride
    borderStylesolid
    public interface FieldOverride {
       /**
         * Return the property name to perform the override.
         * @return
         */
        public String getPropertyName();
        /**
         * perform the override.
         * 
         * @param bean
         * @param property
         * @return
         */
        public Object performFieldOverride(Object bean, Object property);
    }
    
  3. Declare beans as Data Dictionary Base Types
    Code Block
    borderStylesolid
    titleorg.kuali.rice.kns.bo.datadictionary.DataDictionaryBaseTypes.xml
    borderStylesolid
    ...
    <bean id="DataDictionaryBeanOverride" class="org.kuali.rice.kns.datadictionary.impl.BeanOverrideImpl" abstract="true">
        <property name="beanName" value="" />
        <property name="fieldOverrides">
            <list />
        </property>
    </bean>
      		
    <bean id="FieldOverrideForValueReplace" class="org.kuali.rice.kns.datadictionary.impl.FieldOverrideForValueReplaceImpl" abstract="true">
        <property name="propertyName" value="" />
        <property name="value" value="" />
    </bean>  		
    
    <bean id="FieldOverrideForListElementDelete" class="org.kuali.rice.kns.datadictionary.impl.FieldOverrideForListElementDeleteImpl" abstract="true">
        <property name="propertyNameForElementCompare" value="name" />
        <property name="propertyName" value="" />
        <property name="element" value="" />
    </bean>  		
    
    <bean id="FieldOverrideForListElementInsert" class="org.kuali.rice.kns.datadictionary.impl.FieldOverrideForListElementInsertImpl" abstract="true">
        <property name="propertyNameForElementCompare" value="name" />
        <property name="propertyName"><null /></property>
        <property name="element"><null /></property>
        <property name="insertAfter"><null /></property>
        <property name="insertBefore"><null /></property>
    </bean>  		
    
    <bean id="FieldOverrideForListElementReplace" class="org.kuali.rice.kns.datadictionary.impl.FieldOverrideForListElementReplaceImpl" abstract="true">    
        <property name="propertyNameForElementCompare" value="name" />
        <property name="propertyName"><null /></property>
        <property name="element"><null /></property>
        <property name="replaceWith"><null /></property>
    </bean>
    
  4. Add a performOverrides() method to DataDictionary.
    Code Block
    borderStylesolid
    titleorg.kuali.rice.kns.datadictionary.DataDictionary.java
    borderStylesolid
    ...
    public void performBeanOverrides()
        {
        	Collection<BeanOverride> beanOverrides = ddBeans.getBeansOfType(BeanOverride.class).values();
        	
        	if (beanOverrides.isEmpty()){
        		LOG.info("DataDictionary.performOverrides(): No beans to override");
        	}
    		for (BeanOverride beanOverride : beanOverrides) {
    			
    			Object bean = ddBeans.getBean(beanOverride.getBeanName());
    			beanOverride.performOverride(bean);
    			LOG.info("DataDictionary.performOverrides(): Performing override on bean: " + bean.toString());
    		}
        }
    ...
    
  5. Modify KNS Configurer to call performOverrides() after the Data Dictionary has been loaded and validated.
    Code Block
    borderStylesolid
    1 org.kuali.rice.kns.config.KNSConfigurer
    borderStylesolid
    ...
    public void onEvent(RiceConfigEvent event) throws Exception {
        if (event instanceof AfterStartEvent) {
            if (isLoadDataDictionary()) {
                LOG.info("KNS Configurer - Loading DD");
                DataDictionaryService dds = KNSServiceLocator.getDataDictionaryService();
                if ( dds == null ) {
                    dds = (DataDictionaryService)RiceResourceLoaderFactory.getSpringResourceLoader().getContext().getBean( KNSServiceLocator.DATA_DICTIONARY_SERVICE );
                }
                dds.getDataDictionary().parseDataDictionaryConfigurationFiles(false);
    
                if ( isValidateDataDictionary() ) {
                    LOG.info("KNS Configurer - Validating DD");
                    dds.getDataDictionary().validateDD( validateDataDictionaryEboReferences );
                }
                // KULRICE-4513 After the Data Dictionary is loaded and validated, perform Data Dictionary bean overrides.
                dds.getDataDictionary().performBeanOverrides();
            }
            KNSServiceLocator.getDateTimeService().initializeDateTimeService();
        }
    }
    

...

  1. Modify the class descriptor of TRV_ACCT_FO.
    Code Block
    borderStylesolid
    titleOJB-respository-sampleapp.xml
    borderStylesolid
    <descriptor-repository>
    ...
        <class-descriptor class="edu.sampleu.travel.bo.FiscalOfficer" table="TRV_ACCT_FO">
    	<field-descriptor name="id" column="acct_fo_id" jdbc-type="BIGINT" primarykey="true" autoincrement="true" sequence-name="TRV_FO_ID_S" />
    	<field-descriptor name="userName" column="acct_fo_user_name" jdbc-type="VARCHAR" />
    	<field-descriptor name="firstName" column="acct_fo_user_name" jdbc-type="VARCHAR" />
            ...
    </class-descriptor>
    ...
    </descriptor-repository>
    
  2. Add support in FiscalOfficer object.
    Code Block
    borderStylesolid
    titleedu.sampleu.travel.bo.FiscalOfficer
    borderStylesolid
    public class FiscalOfficer extends PersistableBusinessObjectBase {
    ...
        @Column(name="acct_fo_user_name")
        private String firstName;
    ...
        public String getFirstName() {
    	return this.firstName;
        }
        public void setFirstName(String firstName) {
    	this.firstName = firstName;
        }
    ...
    
    Info

    In this implementation, we created a member called firstName but mapped it to the same column as username.
    Optionally, we can:

    1. Add column ACCT_FO_FIRST_NAME to table TRV_ACCT_FO and populate.
    2. Modify the class descriptor of TRV_ACCT_FO
      Code Block
      borderStylesolid
      titleOJB-respository-sampleapp.xml
      borderStylesolid
      ...
      	<field-descriptor name="firstName" column="acct_fo_first_name" jdbc-type="VARCHAR" />
      ...
      
    3. Add support in FiscalOfficer object.
      Code Block
      borderStylesolid
      titleedu.sampleu.travel.bo.FiscalOfficer
      borderStylesolid
      public class FiscalOfficer extends PersistableBusinessObjectBase {
      ...
          @Column(name="acct_fo_first_name")
          private String firstName;
      ...
      
  3. Create a Data Dictionary entry for First Name (in general, any additional entries to existing ones). This is where we use FieldOverride to place First Name where we want.
    Code Block
    borderStylesolid
    titleedu.sampleu.travel.datadictionary.FiscalOfficer-Extension.xml
    borderStylesolid
    <beans>
      
      <bean id="FiscalOfficer" parent="FiscalOfficer-parentBean">
        <property name="attributes">
          <list merge="true">
            <ref bean="FiscalOfficer-firstName"/>
          </list>
        </property>
      </bean>
      
      <bean id="FiscalOfficer-firstName" parent="FiscalOfficer-firstName-parentBean"/>
    
      <bean id="FiscalOfficer-firstName-parentBean" abstract="true" parent="AttributeDefinition">
        <property name="forceUppercase" value="false"/>
        <property name="shortLabel" value="First Name"/>
        <property name="maxLength" value="30"/>
        <property name="validationPattern">
          <bean parent="AnyCharacterValidationPattern"/>
        </property>
        <property name="control">
          <bean parent="TextControlDefinition" p:size="30"/>
        </property>
        <property name="summary" value="First Name"/>
        <property name="name" value="firstName"/>
        <property name="label" value="First Name"/>
        <property name="description" value="First Name"/>
      </bean>
    
      <bean id="FiscalOfficer-inquiryDefinition-override" parent="DataDictionaryBeanOverride">
          <property name="beanName" value="FiscalOfficer-inquiryDefinition" />
              <property name="fieldOverrides">
      	      <list>
                      <bean parent="FieldOverrideForListElementInsert" >
      		  <!-- Place First Name in the "Primary Info" section (inquirySections[0]) -->
      		      <property name="propertyName" value="inquirySections[0].inquiryFields" />
    		      <property name="propertyNameForElementCompare" value="attributeName" />
      		      <property name="element">
    			  <bean parent="FieldDefinition" p:attributeName="id" />
      		      </property>
      		      <property name="insertAfter">
      		          <list>			
    			      <bean parent="FieldDefinition" p:attributeName="firstName" />
    			  </list>	        			
      		      </property>
      		   </bean>
                  </list>
          </property>
      </bean>
      
      <bean id="FiscalOfficer-lookupDefinition-override" parent="DataDictionaryBeanOverride">
          <property name="beanName" value="FiscalOfficer-lookupDefinition" />
          <property name="fieldOverrides">
               <list>
      	       <!-- Place First Name lookup field under ID -->
      	       <bean parent="FieldOverrideForListElementInsert" >
      	           <property name="propertyName" value="lookupFields" />
    		   <property name="propertyNameForElementCompare" value="attributeName" />
      		   <property name="element">
    		       <bean parent="FieldDefinition" p:attributeName="id" />
      		   </property>
      		   <property name="insertAfter">
      		       <list>
      		           <bean parent="FieldDefinition" p:attributeName="firstName" />
    		       </list>	        			
      		   </property>
      	       </bean>
      	       <!-- Place First Name column after ID -->
      	       <bean parent="FieldOverrideForListElementInsert" >
      	           <property name="propertyName" value="resultFields" />
    		   <property name="propertyNameForElementCompare" value="attributeName" />
      		   <property name="element">
    		       <bean parent="FieldDefinition" p:attributeName="id" />
      		   </property>
      	           <property name="insertAfter">
      		       <list>
    		           <bean parent="FieldDefinition" p:attributeName="firstName" />
    		       </list>	        			
      		   </property>
      		</bean>
      	   </list>
           </property>
      </bean>
    
    </beans>
    
    Info

    Notice that the bean FiscalOfficer uses <list merge="true"> to "append" firstName to the Data Dictionary entry of the same name in the "out-of-the-box" FiscalOfficer.xml file.

  4. Declare the new Data Dictionary entries in the Module Configuration. This will be injected into the Travel application's Module Configurer.
    Code Block
    borderStylesolid
    titlewe/src/main/resources/SampleAppModuleBeans.xml
    borderStylesolid
    <beans>
    	 	  
        <bean id="sampleAppModuleConfiguration" class="org.kuali.rice.kns.bo.ModuleConfiguration">
            <property name="namespaceCode" value="tv"/>
            <property name="initializeDataDictionary" value="true"/>
            <property name="dataDictionaryPackages">
                <list>
                    <value>classpath:edu/sampleu/travel/datadictionary/FiscalOfficer.xml</value>
                    <value>classpath:edu/sampleu/travel/datadictionary/FiscalOfficer-Extension.xml</value>
                    ...
                </list>
            </property>
            ...
        </bean>
        ...
    </beans>
    

...